Skip to content

Commit 2bb5e33

Browse files
Add logic to throw exception on workload group deletion with associated rules (#19502)
Signed-off-by: Kaushal Kumar <[email protected]>
1 parent d3ad5b8 commit 2bb5e33

File tree

7 files changed

+392
-29
lines changed

7 files changed

+392
-29
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
1111
- Refactor to move prepareIndex and prepareDelete methods to Engine class ([#19551](https://github.com/opensearch-project/OpenSearch/pull/19551))
1212

1313
### Fixed
14+
- [WLM] add a check to stop workload group deletion having rules ([#19502](https://github.com/opensearch-project/OpenSearch/pull/19502))
1415

1516
### Dependencies
1617
- Bump `org.apache.zookeeper:zookeeper` from 3.9.3 to 3.9.4 ([#19535](https://github.com/opensearch-project/OpenSearch/pull/19535))

plugins/workload-management/src/internalClusterTest/java/org/opensearch/plugin/wlm/WlmAutoTaggingIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,7 @@ public Collection<Object> createComponents(
784784
wlmClusterSettingValuesProvider,
785785
featureType
786786
);
787-
return List.of(refreshMechanism);
787+
return List.of(refreshMechanism, rulePersistenceService, featureType);
788788
}
789789

790790
@Override

plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPlugin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ public Collection<Object> createComponents(
171171
wlmClusterSettingValuesProvider,
172172
featureType
173173
);
174-
return List.of(refreshMechanism);
174+
return List.of(refreshMechanism, featureType, rulePersistenceService);
175175
}
176176

177177
@Override

plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/TransportDeleteWorkloadGroupAction.java

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,34 @@
88

99
package org.opensearch.plugin.wlm.action;
1010

11+
import org.opensearch.ResourceNotFoundException;
1112
import org.opensearch.action.support.ActionFilters;
1213
import org.opensearch.action.support.clustermanager.AcknowledgedResponse;
1314
import org.opensearch.action.support.clustermanager.TransportClusterManagerNodeAction;
1415
import org.opensearch.cluster.ClusterState;
1516
import org.opensearch.cluster.block.ClusterBlockException;
1617
import org.opensearch.cluster.block.ClusterBlockLevel;
1718
import org.opensearch.cluster.metadata.IndexNameExpressionResolver;
19+
import org.opensearch.cluster.metadata.WorkloadGroup;
1820
import org.opensearch.cluster.service.ClusterService;
1921
import org.opensearch.common.inject.Inject;
2022
import org.opensearch.core.action.ActionListener;
2123
import org.opensearch.core.common.io.stream.StreamInput;
24+
import org.opensearch.plugin.wlm.rule.WorkloadGroupFeatureType;
2225
import org.opensearch.plugin.wlm.service.WorkloadGroupPersistenceService;
26+
import org.opensearch.rule.RulePersistenceService;
27+
import org.opensearch.rule.action.GetRuleRequest;
28+
import org.opensearch.rule.action.GetRuleResponse;
29+
import org.opensearch.rule.autotagging.FeatureType;
30+
import org.opensearch.rule.autotagging.Rule;
31+
import org.opensearch.rule.service.IndexStoredRulePersistenceService;
2332
import org.opensearch.threadpool.ThreadPool;
2433
import org.opensearch.transport.TransportService;
2534

2635
import java.io.IOException;
36+
import java.util.Collection;
37+
import java.util.Collections;
38+
import java.util.List;
2739

2840
/**
2941
* Transport action for delete WorkloadGroup
@@ -35,6 +47,8 @@ public class TransportDeleteWorkloadGroupAction extends TransportClusterManagerN
3547
AcknowledgedResponse> {
3648

3749
private final WorkloadGroupPersistenceService workloadGroupPersistenceService;
50+
private final RulePersistenceService rulePersistenceService;
51+
private final FeatureType featureType;
3852

3953
/**
4054
* Constructor for TransportDeleteWorkloadGroupAction
@@ -45,6 +59,8 @@ public class TransportDeleteWorkloadGroupAction extends TransportClusterManagerN
4559
* @param threadPool - a {@link ThreadPool} object
4660
* @param indexNameExpressionResolver - a {@link IndexNameExpressionResolver} object
4761
* @param workloadGroupPersistenceService - a {@link WorkloadGroupPersistenceService} object
62+
* @param persistenceService - a {@link IndexStoredRulePersistenceService} instance
63+
* @param featureType - workloadManagement feature type
4864
*/
4965
@Inject
5066
public TransportDeleteWorkloadGroupAction(
@@ -53,7 +69,9 @@ public TransportDeleteWorkloadGroupAction(
5369
ActionFilters actionFilters,
5470
ThreadPool threadPool,
5571
IndexNameExpressionResolver indexNameExpressionResolver,
56-
WorkloadGroupPersistenceService workloadGroupPersistenceService
72+
WorkloadGroupPersistenceService workloadGroupPersistenceService,
73+
IndexStoredRulePersistenceService persistenceService,
74+
WorkloadGroupFeatureType featureType
5775
) {
5876
super(
5977
DeleteWorkloadGroupAction.NAME,
@@ -65,6 +83,8 @@ public TransportDeleteWorkloadGroupAction(
6583
indexNameExpressionResolver
6684
);
6785
this.workloadGroupPersistenceService = workloadGroupPersistenceService;
86+
this.rulePersistenceService = persistenceService;
87+
this.featureType = featureType;
6888
}
6989

7090
@Override
@@ -73,12 +93,18 @@ protected void clusterManagerOperation(
7393
ClusterState state,
7494
ActionListener<AcknowledgedResponse> listener
7595
) throws Exception {
76-
workloadGroupPersistenceService.deleteInClusterStateMetadata(request, listener);
96+
threadPool.executor(executor()).submit(() -> {
97+
try {
98+
checkNoAssociatedRulesExist(request, listener, state);
99+
} catch (Exception e) {
100+
listener.onFailure(e);
101+
}
102+
});
77103
}
78104

79105
@Override
80106
protected String executor() {
81-
return ThreadPool.Names.SAME;
107+
return ThreadPool.Names.GET;
82108
}
83109

84110
@Override
@@ -90,4 +116,48 @@ protected AcknowledgedResponse read(StreamInput in) throws IOException {
90116
protected ClusterBlockException checkBlock(DeleteWorkloadGroupRequest request, ClusterState state) {
91117
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
92118
}
119+
120+
private void checkNoAssociatedRulesExist(
121+
DeleteWorkloadGroupRequest request,
122+
ActionListener<AcknowledgedResponse> listener,
123+
ClusterState state
124+
) {
125+
Collection<WorkloadGroup> workloadGroups = WorkloadGroupPersistenceService.getFromClusterStateMetadata(request.getName(), state);
126+
if (workloadGroups.isEmpty()) {
127+
throw new ResourceNotFoundException("No WorkloadGroup exists with the provided name: " + request.getName());
128+
}
129+
130+
WorkloadGroup workloadGroup = workloadGroups.iterator().next();
131+
rulePersistenceService.getRule(
132+
new GetRuleRequest(null, Collections.emptyMap(), null, featureType),
133+
new ActionListener<GetRuleResponse>() {
134+
@Override
135+
public void onResponse(GetRuleResponse getRuleResponse) {
136+
List<Rule> associatedRules = getRuleResponse.getRules()
137+
.stream()
138+
.filter(rule -> rule.getFeatureValue().equals(workloadGroup.get_id()))
139+
.toList();
140+
141+
if (!associatedRules.isEmpty()) {
142+
listener.onFailure(
143+
new IllegalStateException(
144+
workloadGroup.getName()
145+
+ " workload group has rules with ids: "
146+
+ associatedRules
147+
+ " ."
148+
+ "Please delete them first otherwise system will be an inconsistent state."
149+
)
150+
);
151+
return;
152+
}
153+
workloadGroupPersistenceService.deleteInClusterStateMetadata(request, listener);
154+
}
155+
156+
@Override
157+
public void onFailure(Exception e) {
158+
listener.onFailure(e);
159+
}
160+
}
161+
);
162+
}
93163
}

plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/WorkloadGroupPersistenceService.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,14 +236,18 @@ protected AcknowledgedResponse newResponse(boolean acknowledged) {
236236
*/
237237
ClusterState deleteWorkloadGroupInClusterState(final String name, final ClusterState currentClusterState) {
238238
final Metadata metadata = currentClusterState.metadata();
239-
final WorkloadGroup workloadGroupToRemove = metadata.workloadGroups()
239+
final WorkloadGroup workloadGroupToRemove = getWorkloadGroup(name, metadata);
240+
241+
return ClusterState.builder(currentClusterState).metadata(Metadata.builder(metadata).remove(workloadGroupToRemove).build()).build();
242+
}
243+
244+
private static WorkloadGroup getWorkloadGroup(String name, Metadata metadata) {
245+
return metadata.workloadGroups()
240246
.values()
241247
.stream()
242248
.filter(workloadGroup -> workloadGroup.getName().equals(name))
243249
.findAny()
244250
.orElseThrow(() -> new ResourceNotFoundException("No WorkloadGroup exists with the provided name: " + name));
245-
246-
return ClusterState.builder(currentClusterState).metadata(Metadata.builder(metadata).remove(workloadGroupToRemove).build()).build();
247251
}
248252

249253
/**

plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/WorkloadManagementPluginTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import java.util.function.Supplier;
5151

5252
import static org.opensearch.plugin.wlm.WorkloadManagementPlugin.PRINCIPAL_ATTRIBUTE_NAME;
53+
import static org.hamcrest.Matchers.equalTo;
5354
import static org.mockito.Mockito.mock;
5455
import static org.mockito.Mockito.spy;
5556
import static org.mockito.Mockito.times;
@@ -187,8 +188,7 @@ public void testCreateComponentsReturnsRefreshMechanism() {
187188
mockRepositoriesServiceSupplier
188189
);
189190

190-
assertEquals(1, components.size());
191-
assertTrue(components.iterator().next() instanceof RefreshBasedSyncMechanism);
191+
assertThat(components.stream().filter(c -> c instanceof RefreshBasedSyncMechanism).count(), equalTo(1L));
192192
}
193193

194194
public void testSetAttributesWithMock() {

0 commit comments

Comments
 (0)