diff --git a/CHANGELOG.md b/CHANGELOG.md index 07db5a30b9eaa..07f1879d1d167 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Add NodeResourceUsageStats to ClusterInfo ([#18480](https://github.com/opensearch-project/OpenSearch/issues/18472)) - Introduce SecureHttpTransportParameters experimental API (to complement SecureTransportParameters counterpart) ([#18572](https://github.com/opensearch-project/OpenSearch/issues/18572)) - Create equivalents of JSM's AccessController in the java agent ([#18346](https://github.com/opensearch-project/OpenSearch/issues/18346)) +- [WLM] Add WLM mode validation for workload group CRUD requests ([#18652](https://github.com/opensearch-project/OpenSearch/issues/18652)) - Introduced a new cluster-level API to fetch remote store metadata (segments and translogs) for each shard of an index. ([#18257](https://github.com/opensearch-project/OpenSearch/pull/18257)) - Add last index request timestamp columns to the `_cat/indices` API. ([10766](https://github.com/opensearch-project/OpenSearch/issues/10766)) - Introduce a new pull-based ingestion plugin for file-based indexing (for local testing) ([#18591](https://github.com/opensearch-project/OpenSearch/pull/18591)) diff --git a/plugins/workload-management/src/javaRestTest/java/org/opensearch/rest/WorkloadManagementRestIT.java b/plugins/workload-management/src/javaRestTest/java/org/opensearch/rest/WorkloadManagementRestIT.java index 00d3e901588b1..a1ade144a7701 100644 --- a/plugins/workload-management/src/javaRestTest/java/org/opensearch/rest/WorkloadManagementRestIT.java +++ b/plugins/workload-management/src/javaRestTest/java/org/opensearch/rest/WorkloadManagementRestIT.java @@ -13,11 +13,18 @@ import org.opensearch.client.Response; import org.opensearch.client.ResponseException; import org.opensearch.test.rest.OpenSearchRestTestCase; +import org.junit.Before; import java.io.IOException; +import java.util.Locale; public class WorkloadManagementRestIT extends OpenSearchRestTestCase { + @Before + public void enableWlmMode() throws Exception { + setWlmMode("enabled"); + } + public void testCreate() throws Exception { Response response = performOperation("PUT", "_wlm/workload_group", getCreateJson("analytics", "enforced", 0.4, 0.2)); assertEquals(response.getStatusLine().getStatusCode(), 200); @@ -129,6 +136,16 @@ public void testCRUD() throws Exception { performOperation("DELETE", "_wlm/workload_group/users3", null); } + public void testOperationWhenWlmDisabled() throws Exception { + setWlmMode("disabled"); + assertThrows( + ResponseException.class, + () -> performOperation("PUT", "_wlm/workload_group", getCreateJson("analytics", "enforced", 0.4, 0.2)) + ); + assertThrows(ResponseException.class, () -> performOperation("DELETE", "_wlm/workload_group/analytics4", null)); + assertOK(performOperation("GET", "_wlm/workload_group/", null)); + } + static String getCreateJson(String name, String resiliencyMode, double cpu, double memory) { return "{\n" + " \"name\": \"" @@ -171,4 +188,19 @@ Response performOperation(String method, String uriPath, String json) throws IOE } return client().performRequest(request); } + + private void setWlmMode(String mode) throws Exception { + String settingJson = String.format(Locale.ROOT, """ + { + "persistent": { + "wlm.workload_group.mode": "%s" + } + } + """, mode); + + Request request = new Request("PUT", "/_cluster/settings"); + request.setJsonEntity(settingJson); + Response response = client().performRequest(request); + assertEquals(200, response.getStatusLine().getStatusCode()); + } } diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WlmClusterSettingValuesProvider.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WlmClusterSettingValuesProvider.java new file mode 100644 index 0000000000000..56b78714c0db5 --- /dev/null +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WlmClusterSettingValuesProvider.java @@ -0,0 +1,64 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.plugin.wlm; + +import org.opensearch.common.settings.ClusterSettings; +import org.opensearch.common.settings.Settings; +import org.opensearch.wlm.WlmMode; +import org.opensearch.wlm.WorkloadManagementSettings; + +/** + * Central provider for maintaining and supplying the current values of wlm cluster settings. + * This class listens for updates to relevant settings and provides the latest setting values. + */ +public class WlmClusterSettingValuesProvider { + + private volatile WlmMode wlmMode; + + /** + * Constructor for WlmClusterSettingValuesProvider + * @param settings OpenSearch settings + * @param clusterSettings Cluster settings to register update listener + */ + public WlmClusterSettingValuesProvider(Settings settings, ClusterSettings clusterSettings) { + this.wlmMode = WorkloadManagementSettings.WLM_MODE_SETTING.get(settings); + clusterSettings.addSettingsUpdateConsumer(WorkloadManagementSettings.WLM_MODE_SETTING, this::setWlmMode); + } + + /** + * Check if WLM mode is ENABLED + * Throws an IllegalStateException if WLM mode is DISABLED or MONITOR ONLY. + * @param operationDescription A short text describing the operation, e.g. "create workload group". + */ + public void ensureWlmEnabled(String operationDescription) { + if (wlmMode != WlmMode.ENABLED) { + throw new IllegalStateException( + "Cannot " + + operationDescription + + " because workload management mode is disabled or monitor_only." + + "To enable this feature, set [wlm.workload_group.mode] to 'enabled' in cluster settings." + ); + } + } + + /** + * Set the latest WLM mode. + * @param mode The wlm mode to set + */ + private void setWlmMode(WlmMode mode) { + this.wlmMode = mode; + } + + /** + * Get the latest WLM mode. + */ + public WlmMode getWlmMode() { + return wlmMode; + } +} diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPlugin.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPlugin.java index 9135b12c9cfaf..dfe4147e4bcbd 100644 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPlugin.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPlugin.java @@ -91,6 +91,7 @@ public class WorkloadManagementPlugin extends Plugin implements ActionPlugin, Sy private static FeatureType featureType; private static RulePersistenceService rulePersistenceService; private static RuleRoutingService ruleRoutingService; + private WlmClusterSettingValuesProvider wlmClusterSettingValuesProvider; private AutoTaggingActionFilter autoTaggingActionFilter; /** @@ -112,6 +113,10 @@ public Collection createComponents( IndexNameExpressionResolver indexNameExpressionResolver, Supplier repositoriesServiceSupplier ) { + wlmClusterSettingValuesProvider = new WlmClusterSettingValuesProvider( + clusterService.getSettings(), + clusterService.getClusterSettings() + ); featureType = new WorkloadGroupFeatureType(new WorkloadGroupFeatureValueValidator(clusterService)); RuleEntityParser parser = new XContentRuleParser(featureType); AttributeValueStoreFactory attributeValueStoreFactory = new AttributeValueStoreFactory( @@ -132,12 +137,10 @@ public Collection createComponents( RefreshBasedSyncMechanism refreshMechanism = new RefreshBasedSyncMechanism( threadPool, clusterService.getSettings(), - clusterService.getClusterSettings(), - parser, - ruleProcessingService, featureType, rulePersistenceService, - new RuleEventClassifier(Collections.emptySet(), ruleProcessingService) + new RuleEventClassifier(Collections.emptySet(), ruleProcessingService), + wlmClusterSettingValuesProvider ); autoTaggingActionFilter = new AutoTaggingActionFilter(ruleProcessingService, threadPool); @@ -181,10 +184,10 @@ public List getRestHandlers( Supplier nodesInCluster ) { return List.of( - new RestCreateWorkloadGroupAction(), + new RestCreateWorkloadGroupAction(wlmClusterSettingValuesProvider), new RestGetWorkloadGroupAction(), - new RestDeleteWorkloadGroupAction(), - new RestUpdateWorkloadGroupAction() + new RestDeleteWorkloadGroupAction(wlmClusterSettingValuesProvider), + new RestUpdateWorkloadGroupAction(wlmClusterSettingValuesProvider) ); } diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestCreateWorkloadGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestCreateWorkloadGroupAction.java index 5ef59602f7893..5cb6a8a582df7 100644 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestCreateWorkloadGroupAction.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestCreateWorkloadGroupAction.java @@ -11,6 +11,7 @@ import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.plugin.wlm.WlmClusterSettingValuesProvider; import org.opensearch.plugin.wlm.action.CreateWorkloadGroupAction; import org.opensearch.plugin.wlm.action.CreateWorkloadGroupRequest; import org.opensearch.plugin.wlm.action.CreateWorkloadGroupResponse; @@ -35,10 +36,15 @@ */ public class RestCreateWorkloadGroupAction extends BaseRestHandler { + private final WlmClusterSettingValuesProvider nonPluginSettingValuesProvider; + /** * Constructor for RestCreateWorkloadGroupAction + * @param nonPluginSettingValuesProvider the settings provider to access the current WLM mode */ - public RestCreateWorkloadGroupAction() {} + public RestCreateWorkloadGroupAction(WlmClusterSettingValuesProvider nonPluginSettingValuesProvider) { + this.nonPluginSettingValuesProvider = nonPluginSettingValuesProvider; + } @Override public String getName() { @@ -55,6 +61,7 @@ public List routes() { @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + nonPluginSettingValuesProvider.ensureWlmEnabled(getName()); try (XContentParser parser = request.contentParser()) { CreateWorkloadGroupRequest createWorkloadGroupRequest = CreateWorkloadGroupRequest.fromXContent(parser); return channel -> client.execute( diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestDeleteWorkloadGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestDeleteWorkloadGroupAction.java index d0d82f43679fa..e1ad166ed6bda 100644 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestDeleteWorkloadGroupAction.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestDeleteWorkloadGroupAction.java @@ -8,6 +8,7 @@ package org.opensearch.plugin.wlm.rest; +import org.opensearch.plugin.wlm.WlmClusterSettingValuesProvider; import org.opensearch.plugin.wlm.action.DeleteWorkloadGroupAction; import org.opensearch.plugin.wlm.action.DeleteWorkloadGroupRequest; import org.opensearch.rest.BaseRestHandler; @@ -27,10 +28,15 @@ */ public class RestDeleteWorkloadGroupAction extends BaseRestHandler { + private final WlmClusterSettingValuesProvider nonPluginSettingValuesProvider; + /** * Constructor for RestDeleteWorkloadGroupAction + * @param nonPluginSettingValuesProvider the settings provider to access the current WLM mode */ - public RestDeleteWorkloadGroupAction() {} + public RestDeleteWorkloadGroupAction(WlmClusterSettingValuesProvider nonPluginSettingValuesProvider) { + this.nonPluginSettingValuesProvider = nonPluginSettingValuesProvider; + } @Override public String getName() { @@ -47,6 +53,7 @@ public List routes() { @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + nonPluginSettingValuesProvider.ensureWlmEnabled(getName()); DeleteWorkloadGroupRequest deleteWorkloadGroupRequest = new DeleteWorkloadGroupRequest(request.param("name")); deleteWorkloadGroupRequest.clusterManagerNodeTimeout( request.paramAsTime("cluster_manager_timeout", deleteWorkloadGroupRequest.clusterManagerNodeTimeout()) diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestUpdateWorkloadGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestUpdateWorkloadGroupAction.java index db77dc5963037..2e237cf191c75 100644 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestUpdateWorkloadGroupAction.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestUpdateWorkloadGroupAction.java @@ -11,6 +11,7 @@ import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.plugin.wlm.WlmClusterSettingValuesProvider; import org.opensearch.plugin.wlm.action.UpdateWorkloadGroupAction; import org.opensearch.plugin.wlm.action.UpdateWorkloadGroupRequest; import org.opensearch.plugin.wlm.action.UpdateWorkloadGroupResponse; @@ -35,10 +36,15 @@ */ public class RestUpdateWorkloadGroupAction extends BaseRestHandler { + private final WlmClusterSettingValuesProvider nonPluginSettingValuesProvider; + /** * Constructor for RestUpdateWorkloadGroupAction + * @param nonPluginSettingValuesProvider the settings provider to access the current WLM mode */ - public RestUpdateWorkloadGroupAction() {} + public RestUpdateWorkloadGroupAction(WlmClusterSettingValuesProvider nonPluginSettingValuesProvider) { + this.nonPluginSettingValuesProvider = nonPluginSettingValuesProvider; + } @Override public String getName() { @@ -55,6 +61,7 @@ public List routes() { @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + nonPluginSettingValuesProvider.ensureWlmEnabled(getName()); try (XContentParser parser = request.contentParser()) { UpdateWorkloadGroupRequest updateWorkloadGroupRequest = UpdateWorkloadGroupRequest.fromXContent(parser, request.param("name")); return channel -> client.execute( diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/sync/RefreshBasedSyncMechanism.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/sync/RefreshBasedSyncMechanism.java index f367e63aa3f51..9bded4c845204 100644 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/sync/RefreshBasedSyncMechanism.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/sync/RefreshBasedSyncMechanism.java @@ -11,15 +11,13 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.opensearch.common.lifecycle.AbstractLifecycleComponent; -import org.opensearch.common.settings.ClusterSettings; import org.opensearch.common.settings.Setting; import org.opensearch.common.settings.Settings; import org.opensearch.common.unit.TimeValue; import org.opensearch.core.action.ActionListener; +import org.opensearch.plugin.wlm.WlmClusterSettingValuesProvider; import org.opensearch.plugin.wlm.rule.sync.detect.RuleEvent; import org.opensearch.plugin.wlm.rule.sync.detect.RuleEventClassifier; -import org.opensearch.rule.InMemoryRuleProcessingService; -import org.opensearch.rule.RuleEntityParser; import org.opensearch.rule.RulePersistenceService; import org.opensearch.rule.action.GetRuleRequest; import org.opensearch.rule.action.GetRuleResponse; @@ -28,7 +26,6 @@ import org.opensearch.threadpool.Scheduler; import org.opensearch.threadpool.ThreadPool; import org.opensearch.wlm.WlmMode; -import org.opensearch.wlm.WorkloadManagementSettings; import java.io.IOException; import java.util.Collections; @@ -65,12 +62,10 @@ public class RefreshBasedSyncMechanism extends AbstractLifecycleComponent { private final ThreadPool threadPool; private long refreshInterval; private volatile Scheduler.Cancellable scheduledFuture; - private final RuleEntityParser parser; - private final InMemoryRuleProcessingService ruleProcessingService; private final RulePersistenceService rulePersistenceService; private final RuleEventClassifier ruleEventClassifier; private final FeatureType featureType; - private WlmMode wlmMode; + private final WlmClusterSettingValuesProvider nonPluginSettingValuesProvider; // This var keeps the Rules which were present during last run of this service private Set lastRunIndexedRules; private static final Logger logger = LogManager.getLogger(RefreshBasedSyncMechanism.class); @@ -80,33 +75,26 @@ public class RefreshBasedSyncMechanism extends AbstractLifecycleComponent { * * @param threadPool * @param settings - * @param clusterSettings - * @param parser - * @param ruleProcessingService * @param featureType * @param rulePersistenceService * @param ruleEventClassifier + * @param nonPluginSettingValuesProvider */ public RefreshBasedSyncMechanism( ThreadPool threadPool, Settings settings, - ClusterSettings clusterSettings, - RuleEntityParser parser, - InMemoryRuleProcessingService ruleProcessingService, FeatureType featureType, RulePersistenceService rulePersistenceService, - RuleEventClassifier ruleEventClassifier + RuleEventClassifier ruleEventClassifier, + WlmClusterSettingValuesProvider nonPluginSettingValuesProvider ) { this.threadPool = threadPool; refreshInterval = RULE_SYNC_REFRESH_INTERVAL_SETTING.get(settings); - this.parser = parser; - this.ruleProcessingService = ruleProcessingService; this.featureType = featureType; this.rulePersistenceService = rulePersistenceService; this.lastRunIndexedRules = new HashSet<>(); this.ruleEventClassifier = ruleEventClassifier; - wlmMode = WorkloadManagementSettings.WLM_MODE_SETTING.get(settings); - clusterSettings.addSettingsUpdateConsumer(WorkloadManagementSettings.WLM_MODE_SETTING, this::setWlmMode); + this.nonPluginSettingValuesProvider = nonPluginSettingValuesProvider; } /** @@ -114,7 +102,7 @@ public RefreshBasedSyncMechanism( * but theoretically possible */ synchronized void doRun() { - if (wlmMode != WlmMode.ENABLED) { + if (nonPluginSettingValuesProvider.getWlmMode() != WlmMode.ENABLED) { return; } @@ -161,8 +149,4 @@ protected void doClose() throws IOException { scheduledFuture.cancel(); } } - - void setWlmMode(WlmMode mode) { - this.wlmMode = mode; - } } diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/WlmClusterSettingValuesProviderTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/WlmClusterSettingValuesProviderTests.java new file mode 100644 index 0000000000000..4dd4b423abc28 --- /dev/null +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/WlmClusterSettingValuesProviderTests.java @@ -0,0 +1,54 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.plugin.wlm; + +import org.opensearch.common.settings.ClusterSettings; +import org.opensearch.common.settings.Settings; +import org.opensearch.test.OpenSearchTestCase; +import org.opensearch.wlm.WorkloadManagementSettings; +import org.junit.Before; + +import java.util.HashSet; + +import static org.mockito.Mockito.spy; + +public class WlmClusterSettingValuesProviderTests extends OpenSearchTestCase { + + private ClusterSettings clusterSettings; + + @Before + public void setUp() throws Exception { + super.setUp(); + try (WorkloadManagementPlugin plugin = new WorkloadManagementPlugin()) { + clusterSettings = new ClusterSettings(Settings.EMPTY, new HashSet<>(plugin.getSettings())); + clusterSettings.registerSetting(WorkloadManagementSettings.WLM_MODE_SETTING); + } + } + + public void testEnsureWlmEnabledThrowsWhenDisabled() { + WlmClusterSettingValuesProvider spyProvider = createSpyProviderWithMode("disabled"); + assertThrows(IllegalStateException.class, () -> spyProvider.ensureWlmEnabled("")); + } + + public void testEnsureWlmEnabledThrowsWhenMonitorOnly() { + WlmClusterSettingValuesProvider spyProvider = createSpyProviderWithMode("monitor_only"); + assertThrows(IllegalStateException.class, () -> spyProvider.ensureWlmEnabled("")); + } + + public void testEnsureWlmEnabledSucceedsWhenEnabled() { + WlmClusterSettingValuesProvider spyProvider = createSpyProviderWithMode("enabled"); + spyProvider.ensureWlmEnabled(""); + } + + private WlmClusterSettingValuesProvider createSpyProviderWithMode(String mode) { + Settings settings = Settings.builder().put(WorkloadManagementSettings.WLM_MODE_SETTING.getKey(), mode).build(); + WlmClusterSettingValuesProvider realProvider = new WlmClusterSettingValuesProvider(settings, clusterSettings); + return spy(realProvider); + } +} diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/WorkloadManagementTestUtils.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/WorkloadManagementTestUtils.java index bfc9ca356c112..60eee025e1c02 100644 --- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/WorkloadManagementTestUtils.java +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/WorkloadManagementTestUtils.java @@ -19,10 +19,12 @@ import org.opensearch.common.settings.ClusterSettings; import org.opensearch.common.settings.Setting; import org.opensearch.common.settings.Settings; +import org.opensearch.plugin.wlm.rule.sync.RefreshBasedSyncMechanism; import org.opensearch.plugin.wlm.service.WorkloadGroupPersistenceService; import org.opensearch.threadpool.ThreadPool; import org.opensearch.wlm.MutableWorkloadGroupFragment; import org.opensearch.wlm.ResourceType; +import org.opensearch.wlm.WorkloadManagementSettings; import java.util.ArrayList; import java.util.Collection; @@ -165,4 +167,16 @@ public static void assertEqualWorkloadGroups( } } } + + public static WlmClusterSettingValuesProvider setUpNonPluginSettingValuesProvider(String wlmMode) throws Exception { + try (WorkloadManagementPlugin plugin = new WorkloadManagementPlugin()) { + Settings settings = Settings.builder() + .put(RefreshBasedSyncMechanism.RULE_SYNC_REFRESH_INTERVAL_SETTING_NAME, 1000) + .put(WorkloadManagementSettings.WLM_MODE_SETTING_NAME, wlmMode) + .build(); + ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, new HashSet<>(plugin.getSettings())); + clusterSettings.registerSetting(WorkloadManagementSettings.WLM_MODE_SETTING); + return new WlmClusterSettingValuesProvider(settings, clusterSettings); + } + } } diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rest/RestCreateWorkloadGroupActionTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rest/RestCreateWorkloadGroupActionTests.java new file mode 100644 index 0000000000000..abd5135f5f529 --- /dev/null +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rest/RestCreateWorkloadGroupActionTests.java @@ -0,0 +1,44 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.plugin.wlm.rest; + +import org.opensearch.plugin.wlm.WlmClusterSettingValuesProvider; +import org.opensearch.plugin.wlm.WorkloadManagementTestUtils; +import org.opensearch.rest.RestRequest; +import org.opensearch.test.OpenSearchTestCase; +import org.opensearch.transport.client.node.NodeClient; + +import static org.mockito.Mockito.mock; + +public class RestCreateWorkloadGroupActionTests extends OpenSearchTestCase { + + public void testPrepareRequestThrowsWhenWlmModeDisabled() { + try { + WlmClusterSettingValuesProvider nonPluginSettingValuesProvider = WorkloadManagementTestUtils + .setUpNonPluginSettingValuesProvider("disabled"); + RestCreateWorkloadGroupAction restCreateWorkloadGroupAction = new RestCreateWorkloadGroupAction(nonPluginSettingValuesProvider); + restCreateWorkloadGroupAction.prepareRequest(mock(RestRequest.class), mock(NodeClient.class)); + fail("Expected exception when WLM mode is DISABLED"); + } catch (Exception e) { + assertTrue(e.getMessage().contains("create")); + } + } + + public void testPrepareRequestThrowsWhenWlmModeMonitorOnly() { + try { + WlmClusterSettingValuesProvider nonPluginSettingValuesProvider = WorkloadManagementTestUtils + .setUpNonPluginSettingValuesProvider("monitor_only"); + RestCreateWorkloadGroupAction restCreateWorkloadGroupAction = new RestCreateWorkloadGroupAction(nonPluginSettingValuesProvider); + restCreateWorkloadGroupAction.prepareRequest(mock(RestRequest.class), mock(NodeClient.class)); + fail("Expected exception when WLM mode is MONITOR_ONLY"); + } catch (Exception e) { + assertTrue(e.getMessage().contains("create")); + } + } +} diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rest/RestDeleteWorkloadGroupActionTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rest/RestDeleteWorkloadGroupActionTests.java index 199b55754d132..c54313af62bae 100644 --- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rest/RestDeleteWorkloadGroupActionTests.java +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rest/RestDeleteWorkloadGroupActionTests.java @@ -11,6 +11,8 @@ import org.opensearch.action.support.clustermanager.AcknowledgedResponse; import org.opensearch.common.CheckedConsumer; import org.opensearch.common.unit.TimeValue; +import org.opensearch.plugin.wlm.WlmClusterSettingValuesProvider; +import org.opensearch.plugin.wlm.WorkloadManagementTestUtils; import org.opensearch.plugin.wlm.action.DeleteWorkloadGroupAction; import org.opensearch.plugin.wlm.action.DeleteWorkloadGroupRequest; import org.opensearch.rest.RestChannel; @@ -40,7 +42,7 @@ public class RestDeleteWorkloadGroupActionTests extends OpenSearchTestCase { * Test case to validate the construction for RestDeleteWorkloadGroupAction */ public void testConstruction() { - RestDeleteWorkloadGroupAction action = new RestDeleteWorkloadGroupAction(); + RestDeleteWorkloadGroupAction action = new RestDeleteWorkloadGroupAction(mock(WlmClusterSettingValuesProvider.class)); assertNotNull(action); assertEquals("delete_workload_group", action.getName()); List routes = action.routes(); @@ -55,7 +57,9 @@ public void testConstruction() { */ @SuppressWarnings("unchecked") public void testPrepareRequest() throws Exception { - RestDeleteWorkloadGroupAction restDeleteWorkloadGroupAction = new RestDeleteWorkloadGroupAction(); + RestDeleteWorkloadGroupAction restDeleteWorkloadGroupAction = new RestDeleteWorkloadGroupAction( + mock(WlmClusterSettingValuesProvider.class) + ); NodeClient nodeClient = mock(NodeClient.class); RestRequest realRequest = new FakeRestRequest(); realRequest.params().put("name", NAME_ONE); @@ -82,4 +86,16 @@ public void testPrepareRequest() throws Exception { any(RestToXContentListener.class) ); } + + public void testPrepareRequestThrowsWhenWlmModeDisabled() throws Exception { + try { + WlmClusterSettingValuesProvider nonPluginSettingValuesProvider = WorkloadManagementTestUtils + .setUpNonPluginSettingValuesProvider("disabled"); + RestDeleteWorkloadGroupAction restDeleteWorkloadGroupAction = new RestDeleteWorkloadGroupAction(nonPluginSettingValuesProvider); + restDeleteWorkloadGroupAction.prepareRequest(mock(RestRequest.class), mock(NodeClient.class)); + fail("Expected exception when WLM mode is DISABLED"); + } catch (Exception e) { + assertTrue(e.getMessage().contains("delete")); + } + } } diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rest/RestUpdateWorkloadGroupActionTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rest/RestUpdateWorkloadGroupActionTests.java new file mode 100644 index 0000000000000..ba6ddb1a947a8 --- /dev/null +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rest/RestUpdateWorkloadGroupActionTests.java @@ -0,0 +1,44 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.plugin.wlm.rest; + +import org.opensearch.plugin.wlm.WlmClusterSettingValuesProvider; +import org.opensearch.plugin.wlm.WorkloadManagementTestUtils; +import org.opensearch.rest.RestRequest; +import org.opensearch.test.OpenSearchTestCase; +import org.opensearch.transport.client.node.NodeClient; + +import static org.mockito.Mockito.mock; + +public class RestUpdateWorkloadGroupActionTests extends OpenSearchTestCase { + + public void testPrepareRequestThrowsWhenWlmModeDisabled() { + try { + WlmClusterSettingValuesProvider nonPluginSettingValuesProvider = WorkloadManagementTestUtils + .setUpNonPluginSettingValuesProvider("disabled"); + RestUpdateWorkloadGroupAction restUpdateWorkloadGroupAction = new RestUpdateWorkloadGroupAction(nonPluginSettingValuesProvider); + restUpdateWorkloadGroupAction.prepareRequest(mock(RestRequest.class), mock(NodeClient.class)); + fail("Expected exception when WLM mode is DISABLED"); + } catch (Exception e) { + assertTrue(e.getMessage().contains("update")); + } + } + + public void testPrepareRequestThrowsWhenWlmModeMonitorOnly() { + try { + WlmClusterSettingValuesProvider nonPluginSettingValuesProvider = WorkloadManagementTestUtils + .setUpNonPluginSettingValuesProvider("monitor_only"); + RestUpdateWorkloadGroupAction restUpdateWorkloadGroupAction = new RestUpdateWorkloadGroupAction(nonPluginSettingValuesProvider); + restUpdateWorkloadGroupAction.prepareRequest(mock(RestRequest.class), mock(NodeClient.class)); + fail("Expected exception when WLM mode is MONITOR_ONLY"); + } catch (Exception e) { + assertTrue(e.getMessage().contains("update")); + } + } +} diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/sync/RefreshBasedSyncMechanismTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/sync/RefreshBasedSyncMechanismTests.java index cca14c8778a87..739122e022bcb 100644 --- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/sync/RefreshBasedSyncMechanismTests.java +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/sync/RefreshBasedSyncMechanismTests.java @@ -12,10 +12,10 @@ import org.opensearch.common.settings.Settings; import org.opensearch.core.action.ActionListener; import org.opensearch.plugin.wlm.AutoTaggingActionFilterTests; +import org.opensearch.plugin.wlm.WlmClusterSettingValuesProvider; import org.opensearch.plugin.wlm.WorkloadManagementPlugin; import org.opensearch.plugin.wlm.rule.sync.detect.RuleEventClassifier; import org.opensearch.rule.InMemoryRuleProcessingService; -import org.opensearch.rule.RuleEntityParser; import org.opensearch.rule.RulePersistenceService; import org.opensearch.rule.action.GetRuleRequest; import org.opensearch.rule.action.GetRuleResponse; @@ -24,12 +24,10 @@ import org.opensearch.rule.autotagging.Rule; import org.opensearch.rule.storage.AttributeValueStoreFactory; import org.opensearch.rule.storage.DefaultAttributeValueStore; -import org.opensearch.rule.storage.XContentRuleParser; import org.opensearch.test.OpenSearchTestCase; import org.opensearch.threadpool.Scheduler; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.Client; -import org.opensearch.wlm.WlmMode; import org.opensearch.wlm.WorkloadManagementSettings; import java.io.IOException; @@ -59,6 +57,8 @@ public class RefreshBasedSyncMechanismTests extends OpenSearchTestCase { Scheduler.Cancellable scheduledFuture; RuleEventClassifier ruleEventClassifier; FeatureType featureType; + WlmClusterSettingValuesProvider nonPluginSettingValuesProvider; + ClusterSettings clusterSettings; @Override public void setUp() throws Exception { @@ -68,7 +68,7 @@ public void setUp() throws Exception { .put(RefreshBasedSyncMechanism.RULE_SYNC_REFRESH_INTERVAL_SETTING_NAME, 1000) .put(WorkloadManagementSettings.WLM_MODE_SETTING_NAME, "enabled") .build(); - ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, new HashSet<>(plugin.getSettings())); + clusterSettings = new ClusterSettings(Settings.EMPTY, new HashSet<>(plugin.getSettings())); clusterSettings.registerSetting(WorkloadManagementSettings.WLM_MODE_SETTING); featureType = mock(FeatureType.class); mockThreadPool = mock(ThreadPool.class); @@ -76,7 +76,7 @@ public void setUp() throws Exception { rulePersistenceService = mock(RulePersistenceService.class); ruleEventClassifier = new RuleEventClassifier(Collections.emptySet(), ruleProcessingService); attributeValueStoreFactory = new AttributeValueStoreFactory(featureType, DefaultAttributeValueStore::new); - RuleEntityParser parser = new XContentRuleParser(featureType); + nonPluginSettingValuesProvider = new WlmClusterSettingValuesProvider(settings, clusterSettings); mockClient = mock(Client.class); scheduledFuture = mock(Scheduler.Cancellable.class); when(mockThreadPool.scheduleWithFixedDelay(any(), any(), any())).thenReturn(scheduledFuture); @@ -84,12 +84,10 @@ public void setUp() throws Exception { sut = new RefreshBasedSyncMechanism( mockThreadPool, settings, - clusterSettings, - parser, - ruleProcessingService, featureType, rulePersistenceService, - ruleEventClassifier + ruleEventClassifier, + nonPluginSettingValuesProvider ); } } @@ -123,7 +121,19 @@ public void testDoClose() throws IOException { */ @SuppressWarnings("unchecked") public void testDoRunWhenWLM_isDisabled() { - sut.setWlmMode(WlmMode.DISABLED); + Settings disabledSettings = Settings.builder() + .put(RefreshBasedSyncMechanism.RULE_SYNC_REFRESH_INTERVAL_SETTING_NAME, 1000) + .put(WorkloadManagementSettings.WLM_MODE_SETTING_NAME, "disabled") + .build(); + WlmClusterSettingValuesProvider disabledWlmModeProvider = new WlmClusterSettingValuesProvider(disabledSettings, clusterSettings); + sut = new RefreshBasedSyncMechanism( + mockThreadPool, + disabledSettings, + featureType, + rulePersistenceService, + ruleEventClassifier, + disabledWlmModeProvider + ); sut.doRun(); verify(rulePersistenceService, times(0)).getRule(any(GetRuleRequest.class), any(ActionListener.class)); } diff --git a/plugins/workload-management/src/yamlRestTest/resources/rest-api-spec/test/wlm/10_workload_group.yml b/plugins/workload-management/src/yamlRestTest/resources/rest-api-spec/test/wlm/10_workload_group.yml index 178639638890d..a9ba5d300c9fa 100644 --- a/plugins/workload-management/src/yamlRestTest/resources/rest-api-spec/test/wlm/10_workload_group.yml +++ b/plugins/workload-management/src/yamlRestTest/resources/rest-api-spec/test/wlm/10_workload_group.yml @@ -3,6 +3,13 @@ version: " - 2.16.99" reason: "QueryGroup WorkloadManagement feature was added in 2.17" + - do: + cluster.put_settings: + flat_settings: true + body: + transient: + wlm.workload_group.mode: "enabled" + - do: create_workload_group_context: body: