From 8217a77a9b4207613d8d953cd15a37683938e512 Mon Sep 17 00:00:00 2001 From: Kaushal Kumar Date: Thu, 11 Apr 2024 21:15:54 -0700 Subject: [PATCH 01/15] created a skeleton plugin with functional Rest API Signed-off-by: Kaushal Kumar --- .../TransportIndexCorrelationRuleAction.java | 2 +- .../query-resource-limit-group/build.gradle | 18 +++++ .../ResourceLimitGroupPlugin.java | 46 ++++++++++++ .../resource_limit_group/SampleAction.java | 20 ++++++ .../resource_limit_group/SampleRequest.java | 43 +++++++++++ .../resource_limit_group/SampleResponse.java | 52 ++++++++++++++ .../SampleTransportAction.java | 35 +++++++++ .../rest/SampleRestAction.java | 71 +++++++++++++++++++ .../rest/package-info.java | 9 +++ 9 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 plugins/query-resource-limit-group/build.gradle create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleAction.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleRequest.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleResponse.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleTransportAction.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/SampleRestAction.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/package-info.java diff --git a/plugins/events-correlation-engine/src/main/java/org/opensearch/plugin/correlation/rules/transport/TransportIndexCorrelationRuleAction.java b/plugins/events-correlation-engine/src/main/java/org/opensearch/plugin/correlation/rules/transport/TransportIndexCorrelationRuleAction.java index 7b4fb670c4aee..53e3fdec52700 100644 --- a/plugins/events-correlation-engine/src/main/java/org/opensearch/plugin/correlation/rules/transport/TransportIndexCorrelationRuleAction.java +++ b/plugins/events-correlation-engine/src/main/java/org/opensearch/plugin/correlation/rules/transport/TransportIndexCorrelationRuleAction.java @@ -70,7 +70,7 @@ public TransportIndexCorrelationRuleAction( ClusterService clusterService, CorrelationRuleIndices correlationRuleIndices ) { - super(IndexCorrelationRuleAction.NAME, transportService, actionFilters, IndexCorrelationRuleRequest::new); + super(IndexCorrelationRuleAction.NAME, transportService, IndexCorrelationRuleRequest::new); this.client = client; this.clusterService = clusterService; this.correlationRuleIndices = correlationRuleIndices; diff --git a/plugins/query-resource-limit-group/build.gradle b/plugins/query-resource-limit-group/build.gradle new file mode 100644 index 0000000000000..cca4402f60e42 --- /dev/null +++ b/plugins/query-resource-limit-group/build.gradle @@ -0,0 +1,18 @@ +/* + * 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. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +opensearchplugin { + description 'OpenSearch ResourceLimitGroup Plugin.' + classname 'org.opensearch.plugin.resource_limit_group.ResourceLimitGroupPlugin' +} + +dependencies { +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java new file mode 100644 index 0000000000000..1559c6c3e6316 --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java @@ -0,0 +1,46 @@ +package org.opensearch.plugin.resource_limit_group; + +import org.opensearch.action.ActionRequest; +import org.opensearch.action.ActionType; +import org.opensearch.action.support.ActionFilter; +import org.opensearch.cluster.metadata.IndexNameExpressionResolver; +import org.opensearch.cluster.node.DiscoveryNodes; +import org.opensearch.common.settings.ClusterSettings; +import org.opensearch.common.settings.IndexScopedSettings; +import org.opensearch.common.settings.Settings; +import org.opensearch.common.settings.SettingsFilter; +import org.opensearch.core.action.ActionResponse; +import org.opensearch.plugin.resource_limit_group.rest.SampleRestAction; +import org.opensearch.plugins.ActionPlugin; +import org.opensearch.plugins.Plugin; +import org.opensearch.rest.RestController; +import org.opensearch.rest.RestHandler; + +import java.util.List; +import java.util.function.Supplier; + +public class ResourceLimitGroupPlugin extends Plugin implements ActionPlugin { + /** + * Actions added by this plugin. + */ + @Override + public List> getActions() { + return List.of(new ActionPlugin.ActionHandler<>(SampleAction.INSTANCE, SampleTransportAction.class)); + } + + /** + * Rest handlers added by this plugin. + * + * @param settings + * @param restController + * @param clusterSettings + * @param indexScopedSettings + * @param settingsFilter + * @param indexNameExpressionResolver + * @param nodesInCluster + */ + @Override + public List getRestHandlers(Settings settings, RestController restController, ClusterSettings clusterSettings, IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter, IndexNameExpressionResolver indexNameExpressionResolver, Supplier nodesInCluster) { + return List.of(new SampleRestAction()); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleAction.java new file mode 100644 index 0000000000000..ccd870178ae63 --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleAction.java @@ -0,0 +1,20 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.action.ActionType; + +public class SampleAction extends ActionType { + + public static final SampleAction INSTANCE = new SampleAction(); + private static final String NAME = "cluster:admin/opensearch/sample_rest"; + private SampleAction() { + super(NAME, SampleResponse::new); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleRequest.java new file mode 100644 index 0000000000000..a3d673c7de1da --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleRequest.java @@ -0,0 +1,43 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.action.ActionRequest; +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; + +import java.io.IOException; + +public class SampleRequest extends ActionRequest { + + public SampleRequest() { + } + + public SampleRequest(StreamInput in) throws IOException { + super(in); + } + + /** + * @return + */ + @Override + public ActionRequestValidationException validate() { + return null; + } + + /** + * @param out + * @throws IOException + */ + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleResponse.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleResponse.java new file mode 100644 index 0000000000000..56c64ba726c9c --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleResponse.java @@ -0,0 +1,52 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.core.action.ActionResponse; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.ToXContentObject; +import org.opensearch.core.xcontent.XContentBuilder; + +import java.io.IOException; + +public class SampleResponse extends ActionResponse implements ToXContentObject { + + public SampleResponse() { + + } + + public SampleResponse(StreamInput in) throws IOException { + super(in); + } + + /** + * Write this into the {@linkplain StreamOutput}. + * + * @param out + */ + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString("Hello from sample plugin!"); + } + + /** + * @param builder + * @param params + * @return + * @throws IOException + */ + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field("response", "Hello plugin"); + builder.endObject(); + return builder; + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleTransportAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleTransportAction.java new file mode 100644 index 0000000000000..5d877cfcdea87 --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleTransportAction.java @@ -0,0 +1,35 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.common.inject.Inject; +import org.opensearch.core.action.ActionListener; +import org.opensearch.tasks.Task; +import org.opensearch.transport.TransportService; + +public class SampleTransportAction extends HandledTransportAction { + @Inject + public SampleTransportAction(String actionName, ActionFilters actionFilters, TransportService transportService) { + super(actionName, transportService, actionFilters, SampleRequest::new); + } + + /** + * @param task + * @param request + * @param listener + */ + @Override + protected void doExecute(Task task, SampleRequest request, ActionListener listener) { + listener.onResponse(new SampleResponse()); + } + + +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/SampleRestAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/SampleRestAction.java new file mode 100644 index 0000000000000..4b5ee25e22dc7 --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/SampleRestAction.java @@ -0,0 +1,71 @@ +/* + * 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.resource_limit_group.rest; + +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.plugin.resource_limit_group.SampleAction; +import org.opensearch.plugin.resource_limit_group.SampleRequest; +import org.opensearch.plugin.resource_limit_group.SampleResponse; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.BytesRestResponse; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.RestResponse; +import org.opensearch.rest.action.RestResponseListener; + +import java.io.IOException; +import java.util.List; + +public class SampleRestAction extends BaseRestHandler { + /** + * @return the name of this handler. The name should be human readable and + * should describe the action that will performed when this API is + * called. This name is used in the response to the + */ + @Override + public String getName() { + return this.getClass().getName(); + } + + /** + * The list of {@link Route}s that this RestHandler is responsible for handling. + */ + @Override + public List routes() { + return List.of( + new Route(RestRequest.Method.GET, "/_sample_rest") + ); + } + + /** + * Prepare the request for execution. Implementations should consume all request params before + * returning the runnable for actual execution. Unconsumed params will immediately terminate + * execution of the request. However, some params are only used in processing the response; + * implementations can override {@link BaseRestHandler#responseParams()} to indicate such + * params. + * + * @param request the request to execute + * @param client client for executing actions on the local node + * @return the action to execute + * @throws IOException if an I/O exception occurred parsing the request and preparing for + * execution + */ + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + return (channel) -> { + client.execute(SampleAction.INSTANCE, new SampleRequest(), new RestResponseListener(channel) { + @Override + public RestResponse buildResponse(SampleResponse sampleResponse) throws Exception { + return new BytesRestResponse(RestStatus.OK, sampleResponse.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS)); + } + }); + }; + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/package-info.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/package-info.java new file mode 100644 index 0000000000000..68aad78e4a9f3 --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/package-info.java @@ -0,0 +1,9 @@ +/* + * 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.resource_limit_group.rest; From 019c5aa192fbf4c8dfb00430393e85a4915eddda Mon Sep 17 00:00:00 2001 From: Kaushal Kumar Date: Wed, 10 Apr 2024 10:18:54 -0700 Subject: [PATCH 02/15] add sandbox service Signed-off-by: Kaushal Kumar --- .../common/settings/ClusterSettings.java | 8 +- .../search/sandbox/QuerySandboxService.java | 94 ++++++++ .../sandbox/QuerySandboxServiceSettings.java | 202 ++++++++++++++++++ .../search/sandbox/SandboxPruner.java | 20 ++ .../cancellation/SandboxRequestCanceller.java | 19 ++ .../sandbox/cancellation/package-info.java | 12 ++ .../search/sandbox/module/SandboxModule.java | 33 +++ .../search/sandbox/module/package-info.java | 13 ++ .../search/sandbox/package-info.java | 12 ++ .../tracker/SandboxResourceTracker.java | 19 ++ .../SandboxResourceTrackerService.java | 178 +++++++++++++++ .../search/sandbox/tracker/package-info.java | 12 ++ .../QuerySandboxServiceSettingsTests.java | 129 +++++++++++ 13 files changed, 750 insertions(+), 1 deletion(-) create mode 100644 server/src/main/java/org/opensearch/search/sandbox/QuerySandboxService.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/QuerySandboxServiceSettings.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/SandboxPruner.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/cancellation/SandboxRequestCanceller.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/cancellation/package-info.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/module/SandboxModule.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/module/package-info.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/package-info.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/tracker/SandboxResourceTracker.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/tracker/SandboxResourceTrackerService.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/tracker/package-info.java create mode 100644 server/src/test/java/org/opensearch/search/sandbox/QuerySandboxServiceSettingsTests.java diff --git a/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java b/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java index 004973e50d43a..221f404cbb168 100644 --- a/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java +++ b/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java @@ -154,6 +154,7 @@ import org.opensearch.search.backpressure.settings.SearchShardTaskSettings; import org.opensearch.search.backpressure.settings.SearchTaskSettings; import org.opensearch.search.fetch.subphase.highlight.FastVectorHighlighter; +import org.opensearch.search.sandbox.QuerySandboxServiceSettings; import org.opensearch.snapshots.InternalSnapshotsInfoService; import org.opensearch.snapshots.SnapshotsService; import org.opensearch.tasks.TaskCancellationMonitoringSettings; @@ -729,7 +730,12 @@ public void apply(Settings value, Settings current, Settings previous) { RemoteStoreSettings.CLUSTER_REMOTE_INDEX_SEGMENT_METADATA_RETENTION_MAX_COUNT_SETTING, RemoteStoreSettings.CLUSTER_REMOTE_TRANSLOG_BUFFER_INTERVAL_SETTING, - RemoteStoreSettings.CLUSTER_REMOTE_TRANSLOG_TRANSFER_TIMEOUT_SETTING + RemoteStoreSettings.CLUSTER_REMOTE_TRANSLOG_TRANSFER_TIMEOUT_SETTING, + + // Sandbox settings + QuerySandboxServiceSettings.MAX_SANDBOX_COUNT, + QuerySandboxServiceSettings.NODE_LEVEL_REJECTION_THRESHOLD, + QuerySandboxServiceSettings.NODE_LEVEL_CANCELLATION_THRESHOLD ) ) ); diff --git a/server/src/main/java/org/opensearch/search/sandbox/QuerySandboxService.java b/server/src/main/java/org/opensearch/search/sandbox/QuerySandboxService.java new file mode 100644 index 0000000000000..001e2e7315aac --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/QuerySandboxService.java @@ -0,0 +1,94 @@ +/* + * 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.search.sandbox; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.common.inject.Inject; +import org.opensearch.common.lifecycle.AbstractLifecycleComponent; +import org.opensearch.search.sandbox.tracker.SandboxResourceTracker; +import org.opensearch.search.sandbox.cancellation.SandboxRequestCanceller; +import org.opensearch.threadpool.Scheduler; +import org.opensearch.threadpool.ThreadPool; + +import java.io.IOException; + +/** + * Main service which will run periodically to track and cancel resource constraint violating tasks in sandboxes + */ +public class QuerySandboxService extends AbstractLifecycleComponent { + private static final Logger logger = LogManager.getLogger(QuerySandboxService.class); + + private final SandboxResourceTracker requestTracker; + private final SandboxRequestCanceller requestCanceller; + private final SandboxPruner sandboxPruner; + private volatile Scheduler.Cancellable scheduledFuture; + private final QuerySandboxServiceSettings sandboxServiceSettings; + private final ThreadPool threadPool; + + /** + * Guice managed constructor + * @param requestTrackerService + * @param requestCanceller + * @param sandboxPruner + * @param sandboxServiceSettings + * @param threadPool + */ + @Inject + public QuerySandboxService( + SandboxResourceTracker requestTrackerService, + SandboxRequestCanceller requestCanceller, + SandboxPruner sandboxPruner, + QuerySandboxServiceSettings sandboxServiceSettings, + ThreadPool threadPool + ) { + this.requestTracker = requestTrackerService; + this.requestCanceller = requestCanceller; + this.sandboxPruner = sandboxPruner; + this.sandboxServiceSettings = sandboxServiceSettings; + this.threadPool = threadPool; + } + + /** + * run at regular interval + */ + private void doRun() { + requestTracker.updateSandboxResourceUsages(); + requestCanceller.cancelViolatingTasks(); + sandboxPruner.pruneSandboxes(); + } + + /** + * {@link AbstractLifecycleComponent} lifecycle method + */ + @Override + protected void doStart() { + scheduledFuture = threadPool.scheduleWithFixedDelay(() -> { + try { + doRun(); + } catch (Exception e) { + logger.debug("Exception occurred in Query Sandbox service", e); + } + }, sandboxServiceSettings.getRunIntervalMillis(), ThreadPool.Names.GENERIC); + } + + @Override + protected void doStop() { + if (scheduledFuture != null) { + scheduledFuture.cancel(); + } + } + + @Override + protected void doClose() throws IOException {} + + // public SandboxStatsHolder stats() { + // return requestTrackerService.getSandboxLevelStats(); + // } +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/QuerySandboxServiceSettings.java b/server/src/main/java/org/opensearch/search/sandbox/QuerySandboxServiceSettings.java new file mode 100644 index 0000000000000..70d6a7076d4d2 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/QuerySandboxServiceSettings.java @@ -0,0 +1,202 @@ +/* + * 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.search.sandbox; + +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 java.util.List; + +/** + * Main class to declare the query sandboxing feature related settings + */ +public class QuerySandboxServiceSettings { + private static final Long DEFAULT_RUN_INTERVAL_MILLIS = 1000l; + private static final Double DEFAULT_NODE_LEVEL_REJECTION_QUERY_SANDBOX_THRESHOLD = 0.8; + private static final Double DEFAULT_NODE_LEVEL_CANCELLATION_QUERY_SANDBOX_THRESHOLD = 0.9; + /** + * default max sandbox count on any node at any given point in time + */ + public static final int DEFAULT_MAX_SANDBOX_COUNT_VALUE = 100; + + public static final String SANDBOX_COUNT_SETTING_NAME = "node.sandbox.max_count"; + public static final double NODE_LEVEL_CANCELLATION_THRESHOLD_MAX_VALUE = 0.95; + public static final double NODE_LEVEL_REJECTION_THRESHOLD_MAX_VALUE = 0.90; + + private TimeValue runIntervalMillis; + private Double nodeLevelJvmCancellationThreshold; + private Double nodeLevelJvmRejectionThreshold; + private volatile int maxSandboxCount; + /** + * max sandbox count setting + */ + public static final Setting MAX_SANDBOX_COUNT = Setting.intSetting( + SANDBOX_COUNT_SETTING_NAME, + DEFAULT_MAX_SANDBOX_COUNT_VALUE, + 0, + (newVal) -> { + if (newVal > 100 || newVal < 1) + throw new IllegalArgumentException(SANDBOX_COUNT_SETTING_NAME + " should be in range [1-100]"); + }, + Setting.Property.Dynamic, + Setting.Property.NodeScope + ); + /** + * Setting name for default sandbox count + */ + public static final String QUERY_SANDBOX_SERVICE_RUN_INTERVAL_MILLIS_SETTING_NAME = "query_sandbox.service.run_interval_millis"; + /** + * Setting to control the run interval of QSB service + */ + private static final Setting QSB_RUN_INTERVAL_SETTING = Setting.longSetting( + QUERY_SANDBOX_SERVICE_RUN_INTERVAL_MILLIS_SETTING_NAME, + DEFAULT_RUN_INTERVAL_MILLIS, + 1, + Setting.Property.Dynamic, + Setting.Property.NodeScope + ); + + /** + * Setting name for node level rejection threshold for QSB + */ + public static final String QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME = "query_sandbox.node.rejection_threshold"; + /** + * Setting to control the rejection threshold + */ + public static final Setting NODE_LEVEL_REJECTION_THRESHOLD = Setting.doubleSetting( + QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME, + DEFAULT_NODE_LEVEL_REJECTION_QUERY_SANDBOX_THRESHOLD, + Setting.Property.Dynamic, + Setting.Property.NodeScope + ); + /** + * Setting name for node level cancellation threshold + */ + public static final String QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME = "query_sandbox.node.cancellation_threshold"; + /** + * Setting name for node level cancellation threshold + */ + public static final Setting NODE_LEVEL_CANCELLATION_THRESHOLD = Setting.doubleSetting( + QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME, + DEFAULT_NODE_LEVEL_CANCELLATION_QUERY_SANDBOX_THRESHOLD, + Setting.Property.Dynamic, + Setting.Property.NodeScope + ); + + /** + * Sandbox service settings constructor + * @param settings + * @param clusterSettings + */ + public QuerySandboxServiceSettings(Settings settings, ClusterSettings clusterSettings) { + runIntervalMillis = new TimeValue(QSB_RUN_INTERVAL_SETTING.get(settings)); + nodeLevelJvmCancellationThreshold = NODE_LEVEL_CANCELLATION_THRESHOLD.get(settings); + nodeLevelJvmRejectionThreshold = NODE_LEVEL_REJECTION_THRESHOLD.get(settings); + maxSandboxCount = MAX_SANDBOX_COUNT.get(settings); + + ensureRejectionThresholdIsLessThanCancellation(nodeLevelJvmRejectionThreshold, nodeLevelJvmCancellationThreshold); + + clusterSettings.addSettingsUpdateConsumer(MAX_SANDBOX_COUNT, this::setMaxSandboxCount); + clusterSettings.addSettingsUpdateConsumer(NODE_LEVEL_CANCELLATION_THRESHOLD, this::setNodeLevelJvmCancellationThreshold); + clusterSettings.addSettingsUpdateConsumer(NODE_LEVEL_REJECTION_THRESHOLD, this::setNodeLevelJvmRejectionThreshold); + } + + /** + * Method to get runInterval for QSB + * @return runInterval in milliseconds for QSB Service + */ + public TimeValue getRunIntervalMillis() { + return runIntervalMillis; + } + + /** + * Method to set the new sandbox count + * @param newMaxSandboxCount is the new maxSandboxCount per node + */ + public void setMaxSandboxCount(int newMaxSandboxCount) { + if (newMaxSandboxCount < 0) { + throw new IllegalArgumentException("node.sandbox.max_count can't be negative"); + } + this.maxSandboxCount = newMaxSandboxCount; + } + + /** + * Method to get the node level cancellation threshold + * @return current node level cancellation threshold + */ + public Double getNodeLevelJvmCancellationThreshold() { + return nodeLevelJvmCancellationThreshold; + } + + /** + * Method to set the node level cancellation threshold + * @param nodeLevelJvmCancellationThreshold sets the new node level cancellation threshold + * @throws IllegalArgumentException if the value is > 0.95 and cancellation < rejection threshold + */ + public void setNodeLevelJvmCancellationThreshold(Double nodeLevelJvmCancellationThreshold) { + if (Double.compare(nodeLevelJvmCancellationThreshold, NODE_LEVEL_CANCELLATION_THRESHOLD_MAX_VALUE) > 0) { + throw new IllegalArgumentException( + QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME + + " value should not be greater than 0.95 as it pose a threat of node drop" + ); + } + + ensureRejectionThresholdIsLessThanCancellation(nodeLevelJvmRejectionThreshold, nodeLevelJvmCancellationThreshold); + + this.nodeLevelJvmCancellationThreshold = nodeLevelJvmCancellationThreshold; + } + + /** + * Method to get the node level rejection threshold + * @return the current node level rejection threshold + */ + public Double getNodeLevelJvmRejectionThreshold() { + return nodeLevelJvmRejectionThreshold; + } + + /** + * Method to set the node level rejection threshold + * @param nodeLevelJvmRejectionThreshold sets the new rejection threshold + * @throws IllegalArgumentException if rejection > 0.90 and rejection < cancellation threshold + */ + public void setNodeLevelJvmRejectionThreshold(Double nodeLevelJvmRejectionThreshold) { + if (Double.compare(nodeLevelJvmRejectionThreshold, NODE_LEVEL_REJECTION_THRESHOLD_MAX_VALUE) > 0) { + throw new IllegalArgumentException( + QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME + " value not be greater than 0.90 as it pose a threat of node drop" + ); + } + + ensureRejectionThresholdIsLessThanCancellation(nodeLevelJvmRejectionThreshold, nodeLevelJvmCancellationThreshold); + + this.nodeLevelJvmRejectionThreshold = nodeLevelJvmRejectionThreshold; + } + + private void ensureRejectionThresholdIsLessThanCancellation( + Double nodeLevelJvmRejectionThreshold, + Double nodeLevelJvmCancellationThreshold + ) { + if (Double.compare(nodeLevelJvmCancellationThreshold , nodeLevelJvmRejectionThreshold) < 0) { + throw new IllegalArgumentException( + QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME + + " value should not be less than " + + QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME + ); + } + } + + /** + * Method to get the current sandbox count + * @return the current max sandbox count + */ + public int getMaxSandboxCount() { + return maxSandboxCount; + } +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/SandboxPruner.java b/server/src/main/java/org/opensearch/search/sandbox/SandboxPruner.java new file mode 100644 index 0000000000000..c47e5c22d4c3a --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/SandboxPruner.java @@ -0,0 +1,20 @@ +/* + * 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.search.sandbox; + +/** + * This interface is used to identify and completely remove deleted sandboxes which has been marked as deleted + * previously but had the tasks running at the time of deletion request + */ +public interface SandboxPruner { + /** + * remove the deleted sandboxes from the system once all the tasks in that sandbox are completed/cancelled + */ + void pruneSandboxes(); +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/cancellation/SandboxRequestCanceller.java b/server/src/main/java/org/opensearch/search/sandbox/cancellation/SandboxRequestCanceller.java new file mode 100644 index 0000000000000..713d6314f4bf2 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/cancellation/SandboxRequestCanceller.java @@ -0,0 +1,19 @@ +/* + * 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.search.sandbox.cancellation; + +/** + * This interface is used to identify and cancel the violating tasks in a sandbox + */ +public interface SandboxRequestCanceller { + /** + * Cancels the tasks from conteded sandboxes + */ + void cancelViolatingTasks(); +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/cancellation/package-info.java b/server/src/main/java/org/opensearch/search/sandbox/cancellation/package-info.java new file mode 100644 index 0000000000000..52c31596380f0 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/cancellation/package-info.java @@ -0,0 +1,12 @@ +/* + * 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 for cancellation related abstracts + */ +package org.opensearch.search.sandbox.cancellation; diff --git a/server/src/main/java/org/opensearch/search/sandbox/module/SandboxModule.java b/server/src/main/java/org/opensearch/search/sandbox/module/SandboxModule.java new file mode 100644 index 0000000000000..b6da7a1d9539b --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/module/SandboxModule.java @@ -0,0 +1,33 @@ +/* + * 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.search.sandbox.module; + +import org.opensearch.common.inject.AbstractModule; +import org.opensearch.search.sandbox.SandboxPruner; +import org.opensearch.search.sandbox.tracker.SandboxResourceTracker; +import org.opensearch.search.sandbox.cancellation.SandboxRequestCanceller; +import org.opensearch.search.sandbox.tracker.SandboxResourceTrackerService; + +/** + * Module class for sandboxing related artifacts + */ +public class SandboxModule extends AbstractModule { + + /** + * Default constructor + */ + public SandboxModule() {} + + @Override + protected void configure() { + bind(SandboxResourceTracker.class).to(SandboxResourceTrackerService.class).asEagerSingleton(); + bind(SandboxRequestCanceller.class).to(SandboxResourceTrackerService.class).asEagerSingleton(); + bind(SandboxPruner.class).to(SandboxResourceTrackerService.class).asEagerSingleton(); + } +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/module/package-info.java b/server/src/main/java/org/opensearch/search/sandbox/module/package-info.java new file mode 100644 index 0000000000000..d1bcb8d6e01d3 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/module/package-info.java @@ -0,0 +1,13 @@ +/* + * 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. + */ + +/** + * Guice Module + */ + +package org.opensearch.search.sandbox.module; diff --git a/server/src/main/java/org/opensearch/search/sandbox/package-info.java b/server/src/main/java/org/opensearch/search/sandbox/package-info.java new file mode 100644 index 0000000000000..36bfefab5a9aa --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/package-info.java @@ -0,0 +1,12 @@ +/* + * 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. + */ + +/** + * Query Sandboxing related artifacts + */ +package org.opensearch.search.sandbox; diff --git a/server/src/main/java/org/opensearch/search/sandbox/tracker/SandboxResourceTracker.java b/server/src/main/java/org/opensearch/search/sandbox/tracker/SandboxResourceTracker.java new file mode 100644 index 0000000000000..0ab1702d4c3a1 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/tracker/SandboxResourceTracker.java @@ -0,0 +1,19 @@ +/* + * 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.search.sandbox.tracker; + +/** + * This interface is mainly for tracking the sandbox level resource usages + */ +public interface SandboxResourceTracker { + /** + * updates the current resource usage of sandboxes + */ + public void updateSandboxResourceUsages(); +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/tracker/SandboxResourceTrackerService.java b/server/src/main/java/org/opensearch/search/sandbox/tracker/SandboxResourceTrackerService.java new file mode 100644 index 0000000000000..aa0722ebcc7a5 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/tracker/SandboxResourceTrackerService.java @@ -0,0 +1,178 @@ +/* + * 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.search.sandbox.tracker; + +import org.opensearch.common.inject.Inject; +import org.opensearch.core.tasks.resourcetracker.TaskResourceUsage; +import org.opensearch.search.sandbox.SandboxPruner; +import org.opensearch.search.sandbox.cancellation.SandboxRequestCanceller; +import org.opensearch.tasks.Task; +import org.opensearch.tasks.TaskCancellation; +import org.opensearch.tasks.TaskManager; +import org.opensearch.tasks.TaskResourceTrackingService; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.function.LongSupplier; +import java.util.stream.Collectors; + +/** + * This class tracks requests per sandboxes + */ +public class SandboxResourceTrackerService + implements + TaskManager.TaskEventListeners, + SandboxResourceTracker, + SandboxRequestCanceller, + SandboxPruner { + + private static final String CPU = "CPU"; + private static final String JVM_ALLOCATIONS = "JVM_Allocations"; + private static final int numberOfAvailableProcessors = Runtime.getRuntime().availableProcessors(); + private static final long totalAvailableJvmMemory = Runtime.getRuntime().totalMemory(); + private final LongSupplier timeNanosSupplier; + /** + * Sandbox ids which are marked for deletion in between the @link SandboxService runs + */ + private List toDeleteSandboxes; + private List activeSandboxes; + private final TaskManager taskManager; + private final TaskResourceTrackingService taskResourceTrackingService; + + /** + * SandboxResourceTrackerService constructor + * @param taskManager + * @param taskResourceTrackingService + */ + @Inject + public SandboxResourceTrackerService( + TaskManager taskManager, + TaskResourceTrackingService taskResourceTrackingService + ) { + this.taskManager = taskManager; + this.taskResourceTrackingService = taskResourceTrackingService; + toDeleteSandboxes = Collections.synchronizedList(new ArrayList<>()); + this.timeNanosSupplier = System::nanoTime; + } + + @Override + public void updateSandboxResourceUsages() { + + } + + // @Override + // public SandboxStatsHolder getStats() { + // return null; + // } + + private AbsoluteResourceUsage calculateAbsoluteResourceUsageFor(Task task) { + TaskResourceUsage taskResourceUsage = task.getTotalResourceStats(); + long cpuTimeInNanos = taskResourceUsage.getCpuTimeInNanos(); + long jvmAllocations = taskResourceUsage.getMemoryInBytes(); + long taskElapsedTime = timeNanosSupplier.getAsLong() - task.getStartTimeNanos(); + return new AbsoluteResourceUsage( + (cpuTimeInNanos * 1.0f) / (taskElapsedTime * numberOfAvailableProcessors), + ((jvmAllocations * 1.0f) / totalAvailableJvmMemory) + ); + } + + /** + * Value holder class for resource usage in absolute terms with respect to system/process mem + */ + private static class AbsoluteResourceUsage { + private final double absoluteCpuUsage; + private final double absoluteJvmAllocationsUsage; + + public AbsoluteResourceUsage(double absoluteCpuUsage, double absoluteJvmAllocationsUsage) { + this.absoluteCpuUsage = absoluteCpuUsage; + this.absoluteJvmAllocationsUsage = absoluteJvmAllocationsUsage; + } + + public static AbsoluteResourceUsage merge(AbsoluteResourceUsage a, AbsoluteResourceUsage b) { + return new AbsoluteResourceUsage( + a.absoluteCpuUsage + b.absoluteCpuUsage, + a.absoluteJvmAllocationsUsage + b.absoluteJvmAllocationsUsage + ); + } + + public double getAbsoluteCpuUsageInPercentage() { + return absoluteCpuUsage * 100; + } + + public double getAbsoluteJvmAllocationsUsageInPercent() { + return absoluteJvmAllocationsUsage * 100; + } + } + + /** + * filter out the deleted sandboxes which still has unfi + */ + public void pruneSandboxes() { + toDeleteSandboxes = toDeleteSandboxes.stream().filter(this::hasUnfinishedTasks).collect(Collectors.toList()); + } + + private boolean hasUnfinishedTasks(String sandboxId) { + return false; + } + + /** + * method to handle the completed tasks + * @param task represents completed task on the node + */ + @Override + public void onTaskCompleted(Task task) {} + + /** + * This method will select the sandboxes violating the enforced constraints + * and cancel the tasks from the violating sandboxes + * Cancellation happens in two scenarios + *
    + *
  1. If the sandbox is of enforced type and it is breaching its cancellation limit for the threshold
  2. + *
  3. Node is in duress and sandboxes which are breaching the cancellation thresholds will have cancellations
  4. + *
+ */ + @Override + public void cancelViolatingTasks() { + List cancellableTasks = getCancellableTasks(); + for (TaskCancellation taskCancellation : cancellableTasks) { + taskCancellation.cancel(); + } + } + + private List getCancellableTasks() { + // perform cancellations from enforced type sandboxes + List inViolationSandboxes = getBreachingSandboxIds(); + List cancellableTasks = new ArrayList<>(); + for (String sandboxId : inViolationSandboxes) { + cancellableTasks.addAll(getCancellableTasksFrom(sandboxId)); + } + + // perform cancellations from soft type sandboxes if the node is in duress (hitting node level cancellation + // threshold) + + + return cancellableTasks; + } + + public void deleteSandbox(String sandboxId) { + if (hasUnfinishedTasks(sandboxId)) { + toDeleteSandboxes.add(sandboxId); + } + // remove this sandbox from the active sandboxes + } + + private List getBreachingSandboxIds() { + return Collections.emptyList(); + } + + private List getCancellableTasksFrom(String sandboxId) { + return Collections.emptyList(); + } +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/tracker/package-info.java b/server/src/main/java/org/opensearch/search/sandbox/tracker/package-info.java new file mode 100644 index 0000000000000..e7be9a36f3ce5 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/tracker/package-info.java @@ -0,0 +1,12 @@ +/* + * 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. + */ + +/** + * Sandbox resource tracking artifacts + */ +package org.opensearch.search.sandbox.tracker; diff --git a/server/src/test/java/org/opensearch/search/sandbox/QuerySandboxServiceSettingsTests.java b/server/src/test/java/org/opensearch/search/sandbox/QuerySandboxServiceSettingsTests.java new file mode 100644 index 0000000000000..9d6158c8244ab --- /dev/null +++ b/server/src/test/java/org/opensearch/search/sandbox/QuerySandboxServiceSettingsTests.java @@ -0,0 +1,129 @@ +/* + * 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.search.sandbox; + +import org.opensearch.common.settings.ClusterSettings; +import org.opensearch.common.settings.Settings; +import org.opensearch.test.OpenSearchTestCase; + +import static org.opensearch.search.sandbox.QuerySandboxServiceSettings.*; + +public class QuerySandboxServiceSettingsTests extends OpenSearchTestCase { + + /** + * Tests the valid value of {@code node.sandbox.max_count} + */ + public void testValidMaxSandboxCountSetting() { + Settings settings = Settings.builder().put(SANDBOX_COUNT_SETTING_NAME, 100).build(); + ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + QuerySandboxServiceSettings querySandboxServiceSettings = new QuerySandboxServiceSettings(settings, cs); + assertEquals(100, querySandboxServiceSettings.getMaxSandboxCount()); + } + + + /** + * test the invalid value of {@code node.sandbox.max_count} + */ + public void testInValidMaxSandboxCountSetting() { + Settings settings = Settings.builder().put(SANDBOX_COUNT_SETTING_NAME, -100).build(); + ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + assertThrows(IllegalArgumentException.class, + () -> new QuerySandboxServiceSettings(settings, cs)); + } + + /** + * Tests the valid value for {@code query_sandbox.node.rejection_threshold} + */ + public void testValidNodeLevelRejectionThreshold() { + Settings settings = Settings.builder().put(QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.80).build(); + ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + QuerySandboxServiceSettings querySandboxServiceSettings = new QuerySandboxServiceSettings(settings, cs); + assertEquals(0.80, querySandboxServiceSettings.getNodeLevelJvmRejectionThreshold(), 1e-9); + } + + /** + * Tests the invalid value for {@code query_sandbox.node.rejection_threshold} + * When the value is set more than {@literal 0.90} + */ + public void testInValidNodeLevelRejectionThresholdCase1() { + Settings settings = Settings.builder().put(QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.80).build(); + ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + QuerySandboxServiceSettings querySandboxServiceSettings = new QuerySandboxServiceSettings(settings, cs); + assertThrows(IllegalArgumentException.class, + () -> querySandboxServiceSettings.setNodeLevelJvmRejectionThreshold(0.95)); + } + + /** + * Tests the invalid value for {@code query_sandbox.node.rejection_threshold} + * When the value is set more than {@code query_sandbox.node.cancellation_threshold} + */ + public void testInValidNodeLevelRejectionThresholdCase2() { + Settings settings = Settings.builder().put(QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.70) + .put(QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80) + .build(); + ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + QuerySandboxServiceSettings querySandboxServiceSettings = new QuerySandboxServiceSettings(settings, cs); + assertThrows(IllegalArgumentException.class, + () -> querySandboxServiceSettings.setNodeLevelJvmRejectionThreshold(0.85)); + } + + + /** + * Tests the invalid value for {@code query_sandbox.node.rejection_threshold} + * When the value is set more than {@code query_sandbox.node.cancellation_threshold} accidentally during + * new feature development. This test is to ensure that {@link QuerySandboxServiceSettings} holds the + * invariant {@code nodeLevelRejectionThreshold < nodeLevelCancellationThreshold} + */ + public void testInValidInstantiationOfQuerySandboxServiceSettings() { + Settings settings = Settings.builder().put(QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.80) + .put(QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.70) + .build(); + ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + + assertThrows(IllegalArgumentException.class, + () -> new QuerySandboxServiceSettings(settings, cs)); + } + + /** + * Tests the valid value for {@code query_sandbox.node.cancellation_threshold} + */ + public void testValidNodeLevelCancellationThreshold() { + Settings settings = Settings.builder().put(QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80).build(); + ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + QuerySandboxServiceSettings querySandboxServiceSettings = new QuerySandboxServiceSettings(settings, cs); + assertEquals(0.80, querySandboxServiceSettings.getNodeLevelJvmRejectionThreshold(), 1e-9); + } + + /** + * Tests the invalid value for {@code query_sandbox.node.cancellation_threshold} + * When the value is set more than {@literal 0.95} + */ + public void testInValidNodeLevelCancellationThresholdCase1() { + Settings settings = Settings.builder().put(QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80).build(); + ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + QuerySandboxServiceSettings querySandboxServiceSettings = new QuerySandboxServiceSettings(settings, cs); + assertThrows(IllegalArgumentException.class, + () -> querySandboxServiceSettings.setNodeLevelJvmRejectionThreshold(0.96)); + } + + /** + * Tests the invalid value for {@code query_sandbox.node.cancellation_threshold} + * When the value is set less than {@code query_sandbox.node.rejection_threshold} + */ + public void testInValidNodeLevelCancellationThresholdCase2() { + Settings settings = Settings.builder().put(QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.70) + .put(QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80) + .build(); + ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + QuerySandboxServiceSettings querySandboxServiceSettings = new QuerySandboxServiceSettings(settings, cs); + assertThrows(IllegalArgumentException.class, + () -> querySandboxServiceSettings.setNodeLevelJvmRejectionThreshold(0.85)); + } + +} From 028b0ce74e6d6adebbca0515030f8e1286e337bd Mon Sep 17 00:00:00 2001 From: Kaushal Kumar Date: Thu, 11 Apr 2024 18:47:58 -0700 Subject: [PATCH 03/15] add resourceLimitGroupId propagation logic from coordinator to data nodes Signed-off-by: Kaushal Kumar --- .../search/AbstractSearchAsyncAction.java | 3 + .../action/search/SearchRequest.java | 27 +++++- .../action/search/SearchShardTask.java | 9 ++ .../opensearch/action/search/SearchTask.java | 9 ++ .../action/search/TransportSearchAction.java | 3 + .../common/settings/ClusterSettings.java | 8 +- .../rest/action/search/RestSearchAction.java | 5 ++ .../org/opensearch/search/SearchService.java | 3 + .../search/internal/ShardSearchRequest.java | 16 ++++ .../ResourceLimitGroupPruner.java} | 10 +-- .../ResourceLimitGroupService.java} | 38 ++++---- .../ResourceLimitGroupServiceSettings.java} | 88 +++++++++---------- .../ResourceLimitGroupRequestCanceller.java} | 8 +- .../cancellation/package-info.java | 2 +- .../module/ResourceLimitGroupModule.java | 33 +++++++ .../module/package-info.java | 2 +- .../package-info.java | 2 +- ...esourceLimitGroupResourceUsageTracker.java | 19 ++++ ...mitsGroupResourceUsageTrackerService.java} | 43 +++++---- .../tracker/package-info.java | 4 +- .../search/sandbox/module/SandboxModule.java | 33 ------- .../tracker/SandboxResourceTracker.java | 19 ---- ...sourceLimitGroupServiceSettingsTests.java} | 64 +++++++------- 23 files changed, 261 insertions(+), 187 deletions(-) rename server/src/main/java/org/opensearch/search/{sandbox/SandboxPruner.java => resource_limit_group/ResourceLimitGroupPruner.java} (53%) rename server/src/main/java/org/opensearch/search/{sandbox/QuerySandboxService.java => resource_limit_group/ResourceLimitGroupService.java} (61%) rename server/src/main/java/org/opensearch/search/{sandbox/QuerySandboxServiceSettings.java => resource_limit_group/ResourceLimitGroupServiceSettings.java} (62%) rename server/src/main/java/org/opensearch/search/{sandbox/cancellation/SandboxRequestCanceller.java => resource_limit_group/cancellation/ResourceLimitGroupRequestCanceller.java} (61%) rename server/src/main/java/org/opensearch/search/{sandbox => resource_limit_group}/cancellation/package-info.java (79%) create mode 100644 server/src/main/java/org/opensearch/search/resource_limit_group/module/ResourceLimitGroupModule.java rename server/src/main/java/org/opensearch/search/{sandbox => resource_limit_group}/module/package-info.java (79%) rename server/src/main/java/org/opensearch/search/{sandbox => resource_limit_group}/package-info.java (82%) create mode 100644 server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitGroupResourceUsageTracker.java rename server/src/main/java/org/opensearch/search/{sandbox/tracker/SandboxResourceTrackerService.java => resource_limit_group/tracker/ResourceLimitsGroupResourceUsageTrackerService.java} (78%) rename server/src/main/java/org/opensearch/search/{sandbox => resource_limit_group}/tracker/package-info.java (65%) delete mode 100644 server/src/main/java/org/opensearch/search/sandbox/module/SandboxModule.java delete mode 100644 server/src/main/java/org/opensearch/search/sandbox/tracker/SandboxResourceTracker.java rename server/src/test/java/org/opensearch/search/sandbox/{QuerySandboxServiceSettingsTests.java => ResourceLimitGroupServiceSettingsTests.java} (53%) diff --git a/server/src/main/java/org/opensearch/action/search/AbstractSearchAsyncAction.java b/server/src/main/java/org/opensearch/action/search/AbstractSearchAsyncAction.java index 0520a4a7aecec..c706189f993a2 100644 --- a/server/src/main/java/org/opensearch/action/search/AbstractSearchAsyncAction.java +++ b/server/src/main/java/org/opensearch/action/search/AbstractSearchAsyncAction.java @@ -839,6 +839,9 @@ public final ShardSearchRequest buildShardSearchRequest(SearchShardIterator shar // than creating an empty response in the search thread pool. // Note that, we have to disable this shortcut for queries that create a context (scroll and search context). shardRequest.canReturnNullResponseIfMatchNoDocs(hasShardResponse.get() && shardRequest.scroll() == null); + + // Propagate the resource limit group from co-ordinator to data nodes + shardRequest.setResourceLimitGroupId(getTask().getResourceLimitGroupId()); return shardRequest; } diff --git a/server/src/main/java/org/opensearch/action/search/SearchRequest.java b/server/src/main/java/org/opensearch/action/search/SearchRequest.java index 3b8a6937815aa..2b6c64883a9fb 100644 --- a/server/src/main/java/org/opensearch/action/search/SearchRequest.java +++ b/server/src/main/java/org/opensearch/action/search/SearchRequest.java @@ -122,6 +122,8 @@ public class SearchRequest extends ActionRequest implements IndicesRequest.Repla private Boolean phaseTook = null; + private String resourceLimitGroupId; + public SearchRequest() { this.localClusterAlias = null; this.absoluteStartMillis = DEFAULT_ABSOLUTE_START_MILLIS; @@ -262,6 +264,10 @@ public SearchRequest(StreamInput in) throws IOException { if (in.getVersion().onOrAfter(Version.V_2_12_0)) { phaseTook = in.readOptionalBoolean(); } + + if (in.getVersion().onOrAfter(Version.V_3_0_0)) { + resourceLimitGroupId = in.readOptionalString(); + } } @Override @@ -296,6 +302,9 @@ public void writeTo(StreamOutput out) throws IOException { if (out.getVersion().onOrAfter(Version.V_2_12_0)) { out.writeOptionalBoolean(phaseTook); } + if (out.getVersion().onOrAfter(Version.V_3_0_0)) { + out.writeOptionalString(resourceLimitGroupId); + } } @Override @@ -698,6 +707,15 @@ public String pipeline() { return pipeline; } + public SearchRequest resourceLimitGroupId(String resourceLimitGroupId) { + this.resourceLimitGroupId = resourceLimitGroupId; + return this; + } + + public String resourceLimitGroupId() { + return resourceLimitGroupId; + } + @Override public SearchTask createTask(long id, String type, String action, TaskId parentTaskId, Map headers) { return new SearchTask(id, type, action, this::buildDescription, parentTaskId, headers, cancelAfterTimeInterval); @@ -752,7 +770,8 @@ public boolean equals(Object o) { && ccsMinimizeRoundtrips == that.ccsMinimizeRoundtrips && Objects.equals(cancelAfterTimeInterval, that.cancelAfterTimeInterval) && Objects.equals(pipeline, that.pipeline) - && Objects.equals(phaseTook, that.phaseTook); + && Objects.equals(phaseTook, that.phaseTook) + && Objects.equals(resourceLimitGroupId, that.resourceLimitGroupId); } @Override @@ -774,7 +793,8 @@ public int hashCode() { absoluteStartMillis, ccsMinimizeRoundtrips, cancelAfterTimeInterval, - phaseTook + phaseTook, + resourceLimitGroupId ); } @@ -819,6 +839,7 @@ public String toString() { + pipeline + ", phaseTook=" + phaseTook - + "}"; + + ", resourceLimitGroupId=" + + resourceLimitGroupId + "}"; } } diff --git a/server/src/main/java/org/opensearch/action/search/SearchShardTask.java b/server/src/main/java/org/opensearch/action/search/SearchShardTask.java index dfecf4f462c4d..9e78a06aa7da5 100644 --- a/server/src/main/java/org/opensearch/action/search/SearchShardTask.java +++ b/server/src/main/java/org/opensearch/action/search/SearchShardTask.java @@ -53,6 +53,7 @@ public class SearchShardTask extends CancellableTask implements SearchBackpressureTask { // generating metadata in a lazy way since source can be quite big private final MemoizedSupplier metadataSupplier; + private String resourceLimitGroupId; public SearchShardTask(long id, String type, String action, String description, TaskId parentTaskId, Map headers) { this(id, type, action, description, parentTaskId, headers, () -> ""); @@ -84,4 +85,12 @@ public boolean supportsResourceTracking() { public boolean shouldCancelChildrenOnCancellation() { return false; } + + public String getResourceLimitGroupId() { + return resourceLimitGroupId; + } + + public void setResourceLimitGroupId(String resourceLimitGroupId) { + this.resourceLimitGroupId = resourceLimitGroupId; + } } diff --git a/server/src/main/java/org/opensearch/action/search/SearchTask.java b/server/src/main/java/org/opensearch/action/search/SearchTask.java index d3c1043c50cce..363f3fde65338 100644 --- a/server/src/main/java/org/opensearch/action/search/SearchTask.java +++ b/server/src/main/java/org/opensearch/action/search/SearchTask.java @@ -53,6 +53,7 @@ public class SearchTask extends CancellableTask implements SearchBackpressureTas // generating description in a lazy way since source can be quite big private final Supplier descriptionSupplier; private SearchProgressListener progressListener = SearchProgressListener.NOOP; + private String resourceLimitGroupId; public SearchTask( long id, @@ -106,4 +107,12 @@ public final SearchProgressListener getProgressListener() { public boolean shouldCancelChildrenOnCancellation() { return true; } + + public String getResourceLimitGroupId() { + return resourceLimitGroupId; + } + + public void setResourceLimitGroupId(String resourceLimitGroupId) { + this.resourceLimitGroupId = resourceLimitGroupId; + } } diff --git a/server/src/main/java/org/opensearch/action/search/TransportSearchAction.java b/server/src/main/java/org/opensearch/action/search/TransportSearchAction.java index 65cfd35489033..7ee7292176473 100644 --- a/server/src/main/java/org/opensearch/action/search/TransportSearchAction.java +++ b/server/src/main/java/org/opensearch/action/search/TransportSearchAction.java @@ -1104,6 +1104,9 @@ private void executeSearch( concreteLocalIndices, localShardIterators.size() + remoteShardIterators.size() ); + + task.setResourceLimitGroupId(searchRequest.resourceLimitGroupId()); + searchAsyncActionProvider.asyncSearchAction( task, searchRequest, diff --git a/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java b/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java index 221f404cbb168..d70b793b71741 100644 --- a/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java +++ b/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java @@ -154,7 +154,7 @@ import org.opensearch.search.backpressure.settings.SearchShardTaskSettings; import org.opensearch.search.backpressure.settings.SearchTaskSettings; import org.opensearch.search.fetch.subphase.highlight.FastVectorHighlighter; -import org.opensearch.search.sandbox.QuerySandboxServiceSettings; +import org.opensearch.search.sandbox.ResourceLimitGroupServiceSettings; import org.opensearch.snapshots.InternalSnapshotsInfoService; import org.opensearch.snapshots.SnapshotsService; import org.opensearch.tasks.TaskCancellationMonitoringSettings; @@ -733,9 +733,9 @@ public void apply(Settings value, Settings current, Settings previous) { RemoteStoreSettings.CLUSTER_REMOTE_TRANSLOG_TRANSFER_TIMEOUT_SETTING, // Sandbox settings - QuerySandboxServiceSettings.MAX_SANDBOX_COUNT, - QuerySandboxServiceSettings.NODE_LEVEL_REJECTION_THRESHOLD, - QuerySandboxServiceSettings.NODE_LEVEL_CANCELLATION_THRESHOLD + ResourceLimitGroupServiceSettings.MAX_RESOURCE_LIMIT_GROUP_COUNT, + ResourceLimitGroupServiceSettings.NODE_LEVEL_REJECTION_THRESHOLD, + ResourceLimitGroupServiceSettings.NODE_LEVEL_CANCELLATION_THRESHOLD ) ) ); diff --git a/server/src/main/java/org/opensearch/rest/action/search/RestSearchAction.java b/server/src/main/java/org/opensearch/rest/action/search/RestSearchAction.java index 80dc34c4d5d68..7fa1b38ba95bf 100644 --- a/server/src/main/java/org/opensearch/rest/action/search/RestSearchAction.java +++ b/server/src/main/java/org/opensearch/rest/action/search/RestSearchAction.java @@ -222,6 +222,11 @@ public static void parseSearchRequest( ); } + // As part of first phase in enforcing the resource limits on the groups of queries + if (request.hasParam("resource_limit_group_id")) { + searchRequest.resourceLimitGroupId(request.param("resource_limit_group_id")); + } + searchRequest.setCancelAfterTimeInterval(request.paramAsTime("cancel_after_time_interval", null)); } diff --git a/server/src/main/java/org/opensearch/search/SearchService.java b/server/src/main/java/org/opensearch/search/SearchService.java index f2328bea65eb1..ae937f57a9355 100644 --- a/server/src/main/java/org/opensearch/search/SearchService.java +++ b/server/src/main/java/org/opensearch/search/SearchService.java @@ -559,6 +559,7 @@ public void executeQueryPhase( assert request.canReturnNullResponseIfMatchNoDocs() == false || request.numberOfShards() > 1 : "empty responses require more than one shard"; final IndexShard shard = getShard(request); + task.setResourceLimitGroupId(request.resourceLimitGroupId()); rewriteAndFetchShardRequest(shard, request, new ActionListener() { @Override public void onResponse(ShardSearchRequest orig) { @@ -667,6 +668,7 @@ public void executeQueryPhase( } runAsync(getExecutor(readerContext.indexShard()), () -> { final ShardSearchRequest shardSearchRequest = readerContext.getShardSearchRequest(null); + task.setResourceLimitGroupId(shardSearchRequest.resourceLimitGroupId()); try ( SearchContext searchContext = createContext(readerContext, shardSearchRequest, task, false); SearchOperationListenerExecutor executor = new SearchOperationListenerExecutor(searchContext) @@ -769,6 +771,7 @@ public void executeFetchPhase( public void executeFetchPhase(ShardFetchRequest request, SearchShardTask task, ActionListener listener) { final ReaderContext readerContext = findReaderContext(request.contextId(), request); final ShardSearchRequest shardSearchRequest = readerContext.getShardSearchRequest(request.getShardSearchRequest()); + task.setResourceLimitGroupId(shardSearchRequest.resourceLimitGroupId()); final Releasable markAsUsed = readerContext.markAsUsed(getKeepAlive(shardSearchRequest)); runAsync(getExecutor(readerContext.indexShard()), () -> { try (SearchContext searchContext = createContext(readerContext, shardSearchRequest, task, false)) { diff --git a/server/src/main/java/org/opensearch/search/internal/ShardSearchRequest.java b/server/src/main/java/org/opensearch/search/internal/ShardSearchRequest.java index de1d5fb8b4098..cf661c7243bb8 100644 --- a/server/src/main/java/org/opensearch/search/internal/ShardSearchRequest.java +++ b/server/src/main/java/org/opensearch/search/internal/ShardSearchRequest.java @@ -112,6 +112,7 @@ public class ShardSearchRequest extends TransportRequest implements IndicesReque private SearchSourceBuilder source; private final ShardSearchContextId readerId; private final TimeValue keepAlive; + private String resourceLimitGroupId; public ShardSearchRequest( OriginalIndices originalIndices, @@ -266,6 +267,9 @@ public ShardSearchRequest(StreamInput in) throws IOException { readerId = in.readOptionalWriteable(ShardSearchContextId::new); keepAlive = in.readOptionalTimeValue(); originalIndices = OriginalIndices.readOriginalIndices(in); + if (in.getVersion().onOrAfter(Version.V_3_0_0)) { + resourceLimitGroupId = in.readOptionalString(); + } assert keepAlive == null || readerId != null : "readerId: " + readerId + " keepAlive: " + keepAlive; } @@ -290,6 +294,7 @@ public ShardSearchRequest(ShardSearchRequest clone) { this.originalIndices = clone.originalIndices; this.readerId = clone.readerId; this.keepAlive = clone.keepAlive; + this.resourceLimitGroupId = clone.resourceLimitGroupId; } @Override @@ -297,6 +302,9 @@ public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); innerWriteTo(out, false); OriginalIndices.writeOriginalIndices(originalIndices, out); + if (out.getVersion().onOrAfter(Version.V_3_0_0)) { + out.writeOptionalString(resourceLimitGroupId); + } } protected final void innerWriteTo(StreamOutput out, boolean asKey) throws IOException { @@ -425,6 +433,14 @@ public String preference() { return preference; } + public String resourceLimitGroupId() { + return resourceLimitGroupId; + } + + public void setResourceLimitGroupId(String resourceLimitGroupId) { + this.resourceLimitGroupId = resourceLimitGroupId; + } + /** * Sets the bottom sort values that can be used by the searcher to filter documents * that are after it. This value is computed by coordinating nodes that throttles the diff --git a/server/src/main/java/org/opensearch/search/sandbox/SandboxPruner.java b/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupPruner.java similarity index 53% rename from server/src/main/java/org/opensearch/search/sandbox/SandboxPruner.java rename to server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupPruner.java index c47e5c22d4c3a..50b532eeadeb8 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/SandboxPruner.java +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupPruner.java @@ -6,15 +6,15 @@ * compatible open source license. */ -package org.opensearch.search.sandbox; +package org.opensearch.search.resource_limit_group; /** - * This interface is used to identify and completely remove deleted sandboxes which has been marked as deleted + * This interface is used to identify and completely remove deleted resourceLimitGroups which has been marked as deleted * previously but had the tasks running at the time of deletion request */ -public interface SandboxPruner { +public interface ResourceLimitGroupPruner { /** - * remove the deleted sandboxes from the system once all the tasks in that sandbox are completed/cancelled + * remove the deleted resourceLimitGroups from the system once all the tasks in those resourceLimitGroups are completed/cancelled */ - void pruneSandboxes(); + void pruneResourceLimitGroup(); } diff --git a/server/src/main/java/org/opensearch/search/sandbox/QuerySandboxService.java b/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupService.java similarity index 61% rename from server/src/main/java/org/opensearch/search/sandbox/QuerySandboxService.java rename to server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupService.java index 001e2e7315aac..02954aa140f06 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/QuerySandboxService.java +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupService.java @@ -6,51 +6,51 @@ * compatible open source license. */ -package org.opensearch.search.sandbox; +package org.opensearch.search.resource_limit_group; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.opensearch.common.inject.Inject; import org.opensearch.common.lifecycle.AbstractLifecycleComponent; -import org.opensearch.search.sandbox.tracker.SandboxResourceTracker; -import org.opensearch.search.sandbox.cancellation.SandboxRequestCanceller; +import org.opensearch.search.resource_limit_group.tracker.ResourceLimitGroupResourceUsageTracker; +import org.opensearch.search.resource_limit_group.cancellation.ResourceLimitGroupRequestCanceller; import org.opensearch.threadpool.Scheduler; import org.opensearch.threadpool.ThreadPool; import java.io.IOException; /** - * Main service which will run periodically to track and cancel resource constraint violating tasks in sandboxes + * Main service which will run periodically to track and cancel resource constraint violating tasks in resourceLimitGroups */ -public class QuerySandboxService extends AbstractLifecycleComponent { - private static final Logger logger = LogManager.getLogger(QuerySandboxService.class); +public class ResourceLimitGroupService extends AbstractLifecycleComponent { + private static final Logger logger = LogManager.getLogger(ResourceLimitGroupService.class); - private final SandboxResourceTracker requestTracker; - private final SandboxRequestCanceller requestCanceller; - private final SandboxPruner sandboxPruner; + private final ResourceLimitGroupResourceUsageTracker requestTracker; + private final ResourceLimitGroupRequestCanceller requestCanceller; + private final ResourceLimitGroupPruner resourceLimitGroupPruner; private volatile Scheduler.Cancellable scheduledFuture; - private final QuerySandboxServiceSettings sandboxServiceSettings; + private final ResourceLimitGroupServiceSettings sandboxServiceSettings; private final ThreadPool threadPool; /** * Guice managed constructor * @param requestTrackerService * @param requestCanceller - * @param sandboxPruner + * @param resourceLimitGroupPruner * @param sandboxServiceSettings * @param threadPool */ @Inject - public QuerySandboxService( - SandboxResourceTracker requestTrackerService, - SandboxRequestCanceller requestCanceller, - SandboxPruner sandboxPruner, - QuerySandboxServiceSettings sandboxServiceSettings, + public ResourceLimitGroupService( + ResourceLimitGroupResourceUsageTracker requestTrackerService, + ResourceLimitGroupRequestCanceller requestCanceller, + ResourceLimitGroupPruner resourceLimitGroupPruner, + ResourceLimitGroupServiceSettings sandboxServiceSettings, ThreadPool threadPool ) { this.requestTracker = requestTrackerService; this.requestCanceller = requestCanceller; - this.sandboxPruner = sandboxPruner; + this.resourceLimitGroupPruner = resourceLimitGroupPruner; this.sandboxServiceSettings = sandboxServiceSettings; this.threadPool = threadPool; } @@ -59,9 +59,9 @@ public QuerySandboxService( * run at regular interval */ private void doRun() { - requestTracker.updateSandboxResourceUsages(); + requestTracker.updateResourceLimitGroupsResourceUsage(); requestCanceller.cancelViolatingTasks(); - sandboxPruner.pruneSandboxes(); + resourceLimitGroupPruner.pruneResourceLimitGroup(); } /** diff --git a/server/src/main/java/org/opensearch/search/sandbox/QuerySandboxServiceSettings.java b/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettings.java similarity index 62% rename from server/src/main/java/org/opensearch/search/sandbox/QuerySandboxServiceSettings.java rename to server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettings.java index 70d6a7076d4d2..56bdfbae87168 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/QuerySandboxServiceSettings.java +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettings.java @@ -6,58 +6,56 @@ * compatible open source license. */ -package org.opensearch.search.sandbox; +package org.opensearch.search.resource_limit_group; 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 java.util.List; - /** - * Main class to declare the query sandboxing feature related settings + * Main class to declare the query ResourceLimitGrouping feature related settings */ -public class QuerySandboxServiceSettings { +public class ResourceLimitGroupServiceSettings { private static final Long DEFAULT_RUN_INTERVAL_MILLIS = 1000l; - private static final Double DEFAULT_NODE_LEVEL_REJECTION_QUERY_SANDBOX_THRESHOLD = 0.8; - private static final Double DEFAULT_NODE_LEVEL_CANCELLATION_QUERY_SANDBOX_THRESHOLD = 0.9; + private static final Double DEFAULT_NODE_LEVEL_REJECTION_THRESHOLD = 0.8; + private static final Double DEFAULT_NODE_LEVEL_CANCELLATION_THRESHOLD = 0.9; /** - * default max sandbox count on any node at any given point in time + * default max ResourceLimitGroup count on any node at any given point in time */ - public static final int DEFAULT_MAX_SANDBOX_COUNT_VALUE = 100; + public static final int DEFAULT_MAX_RESOURCE_LIMIT_GROUP_COUNT_VALUE = 100; - public static final String SANDBOX_COUNT_SETTING_NAME = "node.sandbox.max_count"; + public static final String RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME = "node.resource_limit_group.max_count"; public static final double NODE_LEVEL_CANCELLATION_THRESHOLD_MAX_VALUE = 0.95; public static final double NODE_LEVEL_REJECTION_THRESHOLD_MAX_VALUE = 0.90; private TimeValue runIntervalMillis; private Double nodeLevelJvmCancellationThreshold; private Double nodeLevelJvmRejectionThreshold; - private volatile int maxSandboxCount; + private volatile int maxResourceLimitGroupCount; /** - * max sandbox count setting + * max ResourceLimitGroup count setting */ - public static final Setting MAX_SANDBOX_COUNT = Setting.intSetting( - SANDBOX_COUNT_SETTING_NAME, - DEFAULT_MAX_SANDBOX_COUNT_VALUE, + public static final Setting MAX_RESOURCE_LIMIT_GROUP_COUNT = Setting.intSetting( + RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME, + DEFAULT_MAX_RESOURCE_LIMIT_GROUP_COUNT_VALUE, 0, (newVal) -> { if (newVal > 100 || newVal < 1) - throw new IllegalArgumentException(SANDBOX_COUNT_SETTING_NAME + " should be in range [1-100]"); + throw new IllegalArgumentException(RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME + " should be in range [1-100]"); }, Setting.Property.Dynamic, Setting.Property.NodeScope ); /** - * Setting name for default sandbox count + * Setting name for default ResourceLimitGroup count */ - public static final String QUERY_SANDBOX_SERVICE_RUN_INTERVAL_MILLIS_SETTING_NAME = "query_sandbox.service.run_interval_millis"; + public static final String SERVICE_RUN_INTERVAL_MILLIS_SETTING_NAME = "resource_limit_group.service.run_interval_millis"; /** * Setting to control the run interval of QSB service */ - private static final Setting QSB_RUN_INTERVAL_SETTING = Setting.longSetting( - QUERY_SANDBOX_SERVICE_RUN_INTERVAL_MILLIS_SETTING_NAME, + private static final Setting RESOURCE_LIMIT_GROUP_RUN_INTERVAL_SETTING = Setting.longSetting( + SERVICE_RUN_INTERVAL_MILLIS_SETTING_NAME, DEFAULT_RUN_INTERVAL_MILLIS, 1, Setting.Property.Dynamic, @@ -67,44 +65,44 @@ public class QuerySandboxServiceSettings { /** * Setting name for node level rejection threshold for QSB */ - public static final String QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME = "query_sandbox.node.rejection_threshold"; + public static final String NODE_REJECTION_THRESHOLD_SETTING_NAME = "resource_limit_group.node.rejection_threshold"; /** * Setting to control the rejection threshold */ public static final Setting NODE_LEVEL_REJECTION_THRESHOLD = Setting.doubleSetting( - QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME, - DEFAULT_NODE_LEVEL_REJECTION_QUERY_SANDBOX_THRESHOLD, + NODE_REJECTION_THRESHOLD_SETTING_NAME, + DEFAULT_NODE_LEVEL_REJECTION_THRESHOLD, Setting.Property.Dynamic, Setting.Property.NodeScope ); /** * Setting name for node level cancellation threshold */ - public static final String QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME = "query_sandbox.node.cancellation_threshold"; + public static final String NODE_CANCELLATION_THRESHOLD_SETTING_NAME = "resource_limit_group.node.cancellation_threshold"; /** * Setting name for node level cancellation threshold */ public static final Setting NODE_LEVEL_CANCELLATION_THRESHOLD = Setting.doubleSetting( - QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME, - DEFAULT_NODE_LEVEL_CANCELLATION_QUERY_SANDBOX_THRESHOLD, + NODE_CANCELLATION_THRESHOLD_SETTING_NAME, + DEFAULT_NODE_LEVEL_CANCELLATION_THRESHOLD, Setting.Property.Dynamic, Setting.Property.NodeScope ); /** - * Sandbox service settings constructor + * ResourceLimitGroup service settings constructor * @param settings * @param clusterSettings */ - public QuerySandboxServiceSettings(Settings settings, ClusterSettings clusterSettings) { - runIntervalMillis = new TimeValue(QSB_RUN_INTERVAL_SETTING.get(settings)); + public ResourceLimitGroupServiceSettings(Settings settings, ClusterSettings clusterSettings) { + runIntervalMillis = new TimeValue(RESOURCE_LIMIT_GROUP_RUN_INTERVAL_SETTING.get(settings)); nodeLevelJvmCancellationThreshold = NODE_LEVEL_CANCELLATION_THRESHOLD.get(settings); nodeLevelJvmRejectionThreshold = NODE_LEVEL_REJECTION_THRESHOLD.get(settings); - maxSandboxCount = MAX_SANDBOX_COUNT.get(settings); + maxResourceLimitGroupCount = MAX_RESOURCE_LIMIT_GROUP_COUNT.get(settings); ensureRejectionThresholdIsLessThanCancellation(nodeLevelJvmRejectionThreshold, nodeLevelJvmCancellationThreshold); - clusterSettings.addSettingsUpdateConsumer(MAX_SANDBOX_COUNT, this::setMaxSandboxCount); + clusterSettings.addSettingsUpdateConsumer(MAX_RESOURCE_LIMIT_GROUP_COUNT, this::setMaxResourceLimitGroupCount); clusterSettings.addSettingsUpdateConsumer(NODE_LEVEL_CANCELLATION_THRESHOLD, this::setNodeLevelJvmCancellationThreshold); clusterSettings.addSettingsUpdateConsumer(NODE_LEVEL_REJECTION_THRESHOLD, this::setNodeLevelJvmRejectionThreshold); } @@ -118,14 +116,14 @@ public TimeValue getRunIntervalMillis() { } /** - * Method to set the new sandbox count - * @param newMaxSandboxCount is the new maxSandboxCount per node + * Method to set the new ResourceLimitGroup count + * @param newMaxResourceLimitGroupCount is the new maxResourceLimitGroupCount per node */ - public void setMaxSandboxCount(int newMaxSandboxCount) { - if (newMaxSandboxCount < 0) { - throw new IllegalArgumentException("node.sandbox.max_count can't be negative"); + public void setMaxResourceLimitGroupCount(int newMaxResourceLimitGroupCount) { + if (newMaxResourceLimitGroupCount < 0) { + throw new IllegalArgumentException("node.ResourceLimitGroup.max_count can't be negative"); } - this.maxSandboxCount = newMaxSandboxCount; + this.maxResourceLimitGroupCount = newMaxResourceLimitGroupCount; } /** @@ -144,7 +142,7 @@ public Double getNodeLevelJvmCancellationThreshold() { public void setNodeLevelJvmCancellationThreshold(Double nodeLevelJvmCancellationThreshold) { if (Double.compare(nodeLevelJvmCancellationThreshold, NODE_LEVEL_CANCELLATION_THRESHOLD_MAX_VALUE) > 0) { throw new IllegalArgumentException( - QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME + NODE_CANCELLATION_THRESHOLD_SETTING_NAME + " value should not be greater than 0.95 as it pose a threat of node drop" ); } @@ -170,7 +168,7 @@ public Double getNodeLevelJvmRejectionThreshold() { public void setNodeLevelJvmRejectionThreshold(Double nodeLevelJvmRejectionThreshold) { if (Double.compare(nodeLevelJvmRejectionThreshold, NODE_LEVEL_REJECTION_THRESHOLD_MAX_VALUE) > 0) { throw new IllegalArgumentException( - QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME + " value not be greater than 0.90 as it pose a threat of node drop" + NODE_REJECTION_THRESHOLD_SETTING_NAME + " value not be greater than 0.90 as it pose a threat of node drop" ); } @@ -185,18 +183,18 @@ private void ensureRejectionThresholdIsLessThanCancellation( ) { if (Double.compare(nodeLevelJvmCancellationThreshold , nodeLevelJvmRejectionThreshold) < 0) { throw new IllegalArgumentException( - QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME + NODE_CANCELLATION_THRESHOLD_SETTING_NAME + " value should not be less than " - + QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME + + NODE_REJECTION_THRESHOLD_SETTING_NAME ); } } /** - * Method to get the current sandbox count - * @return the current max sandbox count + * Method to get the current ResourceLimitGroup count + * @return the current max ResourceLimitGroup count */ - public int getMaxSandboxCount() { - return maxSandboxCount; + public int getMaxResourceLimitGroupCount() { + return maxResourceLimitGroupCount; } } diff --git a/server/src/main/java/org/opensearch/search/sandbox/cancellation/SandboxRequestCanceller.java b/server/src/main/java/org/opensearch/search/resource_limit_group/cancellation/ResourceLimitGroupRequestCanceller.java similarity index 61% rename from server/src/main/java/org/opensearch/search/sandbox/cancellation/SandboxRequestCanceller.java rename to server/src/main/java/org/opensearch/search/resource_limit_group/cancellation/ResourceLimitGroupRequestCanceller.java index 713d6314f4bf2..77be6104c9600 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/cancellation/SandboxRequestCanceller.java +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/cancellation/ResourceLimitGroupRequestCanceller.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.search.sandbox.cancellation; +package org.opensearch.search.resource_limit_group.cancellation; /** - * This interface is used to identify and cancel the violating tasks in a sandbox + * This interface is used to identify and cancel the violating tasks in a resourceLimitGroup */ -public interface SandboxRequestCanceller { +public interface ResourceLimitGroupRequestCanceller { /** - * Cancels the tasks from conteded sandboxes + * Cancels the tasks from conteded resourceLimitGroups */ void cancelViolatingTasks(); } diff --git a/server/src/main/java/org/opensearch/search/sandbox/cancellation/package-info.java b/server/src/main/java/org/opensearch/search/resource_limit_group/cancellation/package-info.java similarity index 79% rename from server/src/main/java/org/opensearch/search/sandbox/cancellation/package-info.java rename to server/src/main/java/org/opensearch/search/resource_limit_group/cancellation/package-info.java index 52c31596380f0..01502e42e9dfc 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/cancellation/package-info.java +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/cancellation/package-info.java @@ -9,4 +9,4 @@ /** * Package for cancellation related abstracts */ -package org.opensearch.search.sandbox.cancellation; +package org.opensearch.search.resource_limit_group.cancellation; diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/module/ResourceLimitGroupModule.java b/server/src/main/java/org/opensearch/search/resource_limit_group/module/ResourceLimitGroupModule.java new file mode 100644 index 0000000000000..9700612a71edc --- /dev/null +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/module/ResourceLimitGroupModule.java @@ -0,0 +1,33 @@ +/* + * 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.search.resource_limit_group.module; + +import org.opensearch.common.inject.AbstractModule; +import org.opensearch.search.resource_limit_group.ResourceLimitGroupPruner; +import org.opensearch.search.resource_limit_group.tracker.ResourceLimitGroupResourceUsageTracker; +import org.opensearch.search.resource_limit_group.cancellation.ResourceLimitGroupRequestCanceller; +import org.opensearch.search.resource_limit_group.tracker.ResourceLimitsGroupResourceUsageTrackerService; + +/** + * Module class for resource usage limiting related artifacts + */ +public class ResourceLimitGroupModule extends AbstractModule { + + /** + * Default constructor + */ + public ResourceLimitGroupModule() {} + + @Override + protected void configure() { + bind(ResourceLimitGroupResourceUsageTracker.class).to(ResourceLimitsGroupResourceUsageTrackerService.class).asEagerSingleton(); + bind(ResourceLimitGroupRequestCanceller.class).to(ResourceLimitsGroupResourceUsageTrackerService.class).asEagerSingleton(); + bind(ResourceLimitGroupPruner.class).to(ResourceLimitsGroupResourceUsageTrackerService.class).asEagerSingleton(); + } +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/module/package-info.java b/server/src/main/java/org/opensearch/search/resource_limit_group/module/package-info.java similarity index 79% rename from server/src/main/java/org/opensearch/search/sandbox/module/package-info.java rename to server/src/main/java/org/opensearch/search/resource_limit_group/module/package-info.java index d1bcb8d6e01d3..b547a83cd5a42 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/module/package-info.java +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/module/package-info.java @@ -10,4 +10,4 @@ * Guice Module */ -package org.opensearch.search.sandbox.module; +package org.opensearch.search.resource_limit_group.module; diff --git a/server/src/main/java/org/opensearch/search/sandbox/package-info.java b/server/src/main/java/org/opensearch/search/resource_limit_group/package-info.java similarity index 82% rename from server/src/main/java/org/opensearch/search/sandbox/package-info.java rename to server/src/main/java/org/opensearch/search/resource_limit_group/package-info.java index 36bfefab5a9aa..04e807374c1ff 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/package-info.java +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/package-info.java @@ -9,4 +9,4 @@ /** * Query Sandboxing related artifacts */ -package org.opensearch.search.sandbox; +package org.opensearch.search.resource_limit_group; diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitGroupResourceUsageTracker.java b/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitGroupResourceUsageTracker.java new file mode 100644 index 0000000000000..dccf5d4552bca --- /dev/null +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitGroupResourceUsageTracker.java @@ -0,0 +1,19 @@ +/* + * 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.search.resource_limit_group.tracker; + +/** + * This interface is mainly for tracking the resourceLimitGroup level resource usages + */ +public interface ResourceLimitGroupResourceUsageTracker { + /** + * updates the current resource usage of resourceLimitGroups + */ + public void updateResourceLimitGroupsResourceUsage(); +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/tracker/SandboxResourceTrackerService.java b/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitsGroupResourceUsageTrackerService.java similarity index 78% rename from server/src/main/java/org/opensearch/search/sandbox/tracker/SandboxResourceTrackerService.java rename to server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitsGroupResourceUsageTrackerService.java index aa0722ebcc7a5..cb2994b85b829 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/tracker/SandboxResourceTrackerService.java +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitsGroupResourceUsageTrackerService.java @@ -6,12 +6,12 @@ * compatible open source license. */ -package org.opensearch.search.sandbox.tracker; +package org.opensearch.search.resource_limit_group.tracker; import org.opensearch.common.inject.Inject; import org.opensearch.core.tasks.resourcetracker.TaskResourceUsage; -import org.opensearch.search.sandbox.SandboxPruner; -import org.opensearch.search.sandbox.cancellation.SandboxRequestCanceller; +import org.opensearch.search.resource_limit_group.ResourceLimitGroupPruner; +import org.opensearch.search.resource_limit_group.cancellation.ResourceLimitGroupRequestCanceller; import org.opensearch.tasks.Task; import org.opensearch.tasks.TaskCancellation; import org.opensearch.tasks.TaskManager; @@ -24,14 +24,14 @@ import java.util.stream.Collectors; /** - * This class tracks requests per sandboxes + * This class tracks requests per resourceLimitGroups */ -public class SandboxResourceTrackerService +public class ResourceLimitsGroupResourceUsageTrackerService implements TaskManager.TaskEventListeners, - SandboxResourceTracker, - SandboxRequestCanceller, - SandboxPruner { + ResourceLimitGroupResourceUsageTracker, + ResourceLimitGroupRequestCanceller, + ResourceLimitGroupPruner { private static final String CPU = "CPU"; private static final String JVM_ALLOCATIONS = "JVM_Allocations"; @@ -39,10 +39,11 @@ public class SandboxResourceTrackerService private static final long totalAvailableJvmMemory = Runtime.getRuntime().totalMemory(); private final LongSupplier timeNanosSupplier; /** - * Sandbox ids which are marked for deletion in between the @link SandboxService runs + * ResourceLimitGroup ids which are marked for deletion in between the + * {@link org.opensearch.search.resource_limit_group.ResourceLimitGroupService} runs */ - private List toDeleteSandboxes; - private List activeSandboxes; + private List toDeleteResourceLimitGroups; + private List activeResourceLimitGroups; private final TaskManager taskManager; private final TaskResourceTrackingService taskResourceTrackingService; @@ -52,18 +53,18 @@ public class SandboxResourceTrackerService * @param taskResourceTrackingService */ @Inject - public SandboxResourceTrackerService( + public ResourceLimitsGroupResourceUsageTrackerService( TaskManager taskManager, TaskResourceTrackingService taskResourceTrackingService ) { this.taskManager = taskManager; this.taskResourceTrackingService = taskResourceTrackingService; - toDeleteSandboxes = Collections.synchronizedList(new ArrayList<>()); + toDeleteResourceLimitGroups = Collections.synchronizedList(new ArrayList<>()); this.timeNanosSupplier = System::nanoTime; } @Override - public void updateSandboxResourceUsages() { + public void updateResourceLimitGroupsResourceUsage() { } @@ -114,8 +115,8 @@ public double getAbsoluteJvmAllocationsUsageInPercent() { /** * filter out the deleted sandboxes which still has unfi */ - public void pruneSandboxes() { - toDeleteSandboxes = toDeleteSandboxes.stream().filter(this::hasUnfinishedTasks).collect(Collectors.toList()); + public void pruneResourceLimitGroup() { + toDeleteResourceLimitGroups = toDeleteResourceLimitGroups.stream().filter(this::hasUnfinishedTasks).collect(Collectors.toList()); } private boolean hasUnfinishedTasks(String sandboxId) { @@ -146,15 +147,19 @@ public void cancelViolatingTasks() { } } + /** + * + * @return list of cancellable tasks + */ private List getCancellableTasks() { - // perform cancellations from enforced type sandboxes + // get cancellations from enforced type sandboxes List inViolationSandboxes = getBreachingSandboxIds(); List cancellableTasks = new ArrayList<>(); for (String sandboxId : inViolationSandboxes) { cancellableTasks.addAll(getCancellableTasksFrom(sandboxId)); } - // perform cancellations from soft type sandboxes if the node is in duress (hitting node level cancellation + // get cancellations from soft type sandboxes if the node is in duress (hitting node level cancellation // threshold) @@ -163,7 +168,7 @@ private List getCancellableTasks() { public void deleteSandbox(String sandboxId) { if (hasUnfinishedTasks(sandboxId)) { - toDeleteSandboxes.add(sandboxId); + toDeleteResourceLimitGroups.add(sandboxId); } // remove this sandbox from the active sandboxes } diff --git a/server/src/main/java/org/opensearch/search/sandbox/tracker/package-info.java b/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/package-info.java similarity index 65% rename from server/src/main/java/org/opensearch/search/sandbox/tracker/package-info.java rename to server/src/main/java/org/opensearch/search/resource_limit_group/tracker/package-info.java index e7be9a36f3ce5..64d8911f8a1a7 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/tracker/package-info.java +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/package-info.java @@ -7,6 +7,6 @@ */ /** - * Sandbox resource tracking artifacts + * ResourceLimitGroup resource tracking artifacts */ -package org.opensearch.search.sandbox.tracker; +package org.opensearch.search.resource_limit_group.tracker; diff --git a/server/src/main/java/org/opensearch/search/sandbox/module/SandboxModule.java b/server/src/main/java/org/opensearch/search/sandbox/module/SandboxModule.java deleted file mode 100644 index b6da7a1d9539b..0000000000000 --- a/server/src/main/java/org/opensearch/search/sandbox/module/SandboxModule.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.search.sandbox.module; - -import org.opensearch.common.inject.AbstractModule; -import org.opensearch.search.sandbox.SandboxPruner; -import org.opensearch.search.sandbox.tracker.SandboxResourceTracker; -import org.opensearch.search.sandbox.cancellation.SandboxRequestCanceller; -import org.opensearch.search.sandbox.tracker.SandboxResourceTrackerService; - -/** - * Module class for sandboxing related artifacts - */ -public class SandboxModule extends AbstractModule { - - /** - * Default constructor - */ - public SandboxModule() {} - - @Override - protected void configure() { - bind(SandboxResourceTracker.class).to(SandboxResourceTrackerService.class).asEagerSingleton(); - bind(SandboxRequestCanceller.class).to(SandboxResourceTrackerService.class).asEagerSingleton(); - bind(SandboxPruner.class).to(SandboxResourceTrackerService.class).asEagerSingleton(); - } -} diff --git a/server/src/main/java/org/opensearch/search/sandbox/tracker/SandboxResourceTracker.java b/server/src/main/java/org/opensearch/search/sandbox/tracker/SandboxResourceTracker.java deleted file mode 100644 index 0ab1702d4c3a1..0000000000000 --- a/server/src/main/java/org/opensearch/search/sandbox/tracker/SandboxResourceTracker.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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.search.sandbox.tracker; - -/** - * This interface is mainly for tracking the sandbox level resource usages - */ -public interface SandboxResourceTracker { - /** - * updates the current resource usage of sandboxes - */ - public void updateSandboxResourceUsages(); -} diff --git a/server/src/test/java/org/opensearch/search/sandbox/QuerySandboxServiceSettingsTests.java b/server/src/test/java/org/opensearch/search/sandbox/ResourceLimitGroupServiceSettingsTests.java similarity index 53% rename from server/src/test/java/org/opensearch/search/sandbox/QuerySandboxServiceSettingsTests.java rename to server/src/test/java/org/opensearch/search/sandbox/ResourceLimitGroupServiceSettingsTests.java index 9d6158c8244ab..0e500434ea488 100644 --- a/server/src/test/java/org/opensearch/search/sandbox/QuerySandboxServiceSettingsTests.java +++ b/server/src/test/java/org/opensearch/search/sandbox/ResourceLimitGroupServiceSettingsTests.java @@ -12,18 +12,20 @@ import org.opensearch.common.settings.Settings; import org.opensearch.test.OpenSearchTestCase; -import static org.opensearch.search.sandbox.QuerySandboxServiceSettings.*; +import static org.opensearch.search.sandbox.ResourceLimitGroupServiceSettings.NODE_CANCELLATION_THRESHOLD_SETTING_NAME; +import static org.opensearch.search.sandbox.ResourceLimitGroupServiceSettings.NODE_REJECTION_THRESHOLD_SETTING_NAME; +import static org.opensearch.search.sandbox.ResourceLimitGroupServiceSettings.RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME; -public class QuerySandboxServiceSettingsTests extends OpenSearchTestCase { +public class ResourceLimitGroupServiceSettingsTests extends OpenSearchTestCase { /** * Tests the valid value of {@code node.sandbox.max_count} */ public void testValidMaxSandboxCountSetting() { - Settings settings = Settings.builder().put(SANDBOX_COUNT_SETTING_NAME, 100).build(); + Settings settings = Settings.builder().put(RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME, 100).build(); ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - QuerySandboxServiceSettings querySandboxServiceSettings = new QuerySandboxServiceSettings(settings, cs); - assertEquals(100, querySandboxServiceSettings.getMaxSandboxCount()); + ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); + assertEquals(100, resourceLimitGroupServiceSettings.getMaxResourceLimitGroupCount()); } @@ -31,20 +33,20 @@ public void testValidMaxSandboxCountSetting() { * test the invalid value of {@code node.sandbox.max_count} */ public void testInValidMaxSandboxCountSetting() { - Settings settings = Settings.builder().put(SANDBOX_COUNT_SETTING_NAME, -100).build(); + Settings settings = Settings.builder().put(RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME, -100).build(); ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); assertThrows(IllegalArgumentException.class, - () -> new QuerySandboxServiceSettings(settings, cs)); + () -> new ResourceLimitGroupServiceSettings(settings, cs)); } /** * Tests the valid value for {@code query_sandbox.node.rejection_threshold} */ public void testValidNodeLevelRejectionThreshold() { - Settings settings = Settings.builder().put(QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.80).build(); + Settings settings = Settings.builder().put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.80).build(); ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - QuerySandboxServiceSettings querySandboxServiceSettings = new QuerySandboxServiceSettings(settings, cs); - assertEquals(0.80, querySandboxServiceSettings.getNodeLevelJvmRejectionThreshold(), 1e-9); + ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); + assertEquals(0.80, resourceLimitGroupServiceSettings.getNodeLevelJvmRejectionThreshold(), 1e-9); } /** @@ -52,11 +54,11 @@ public void testValidNodeLevelRejectionThreshold() { * When the value is set more than {@literal 0.90} */ public void testInValidNodeLevelRejectionThresholdCase1() { - Settings settings = Settings.builder().put(QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.80).build(); + Settings settings = Settings.builder().put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.80).build(); ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - QuerySandboxServiceSettings querySandboxServiceSettings = new QuerySandboxServiceSettings(settings, cs); + ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); assertThrows(IllegalArgumentException.class, - () -> querySandboxServiceSettings.setNodeLevelJvmRejectionThreshold(0.95)); + () -> resourceLimitGroupServiceSettings.setNodeLevelJvmRejectionThreshold(0.95)); } /** @@ -64,40 +66,40 @@ public void testInValidNodeLevelRejectionThresholdCase1() { * When the value is set more than {@code query_sandbox.node.cancellation_threshold} */ public void testInValidNodeLevelRejectionThresholdCase2() { - Settings settings = Settings.builder().put(QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.70) - .put(QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80) + Settings settings = Settings.builder().put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.70) + .put(NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80) .build(); ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - QuerySandboxServiceSettings querySandboxServiceSettings = new QuerySandboxServiceSettings(settings, cs); + ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); assertThrows(IllegalArgumentException.class, - () -> querySandboxServiceSettings.setNodeLevelJvmRejectionThreshold(0.85)); + () -> resourceLimitGroupServiceSettings.setNodeLevelJvmRejectionThreshold(0.85)); } /** * Tests the invalid value for {@code query_sandbox.node.rejection_threshold} * When the value is set more than {@code query_sandbox.node.cancellation_threshold} accidentally during - * new feature development. This test is to ensure that {@link QuerySandboxServiceSettings} holds the + * new feature development. This test is to ensure that {@link ResourceLimitGroupServiceSettings} holds the * invariant {@code nodeLevelRejectionThreshold < nodeLevelCancellationThreshold} */ public void testInValidInstantiationOfQuerySandboxServiceSettings() { - Settings settings = Settings.builder().put(QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.80) - .put(QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.70) + Settings settings = Settings.builder().put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.80) + .put(NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.70) .build(); ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); assertThrows(IllegalArgumentException.class, - () -> new QuerySandboxServiceSettings(settings, cs)); + () -> new ResourceLimitGroupServiceSettings(settings, cs)); } /** * Tests the valid value for {@code query_sandbox.node.cancellation_threshold} */ public void testValidNodeLevelCancellationThreshold() { - Settings settings = Settings.builder().put(QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80).build(); + Settings settings = Settings.builder().put(NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80).build(); ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - QuerySandboxServiceSettings querySandboxServiceSettings = new QuerySandboxServiceSettings(settings, cs); - assertEquals(0.80, querySandboxServiceSettings.getNodeLevelJvmRejectionThreshold(), 1e-9); + ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); + assertEquals(0.80, resourceLimitGroupServiceSettings.getNodeLevelJvmRejectionThreshold(), 1e-9); } /** @@ -105,11 +107,11 @@ public void testValidNodeLevelCancellationThreshold() { * When the value is set more than {@literal 0.95} */ public void testInValidNodeLevelCancellationThresholdCase1() { - Settings settings = Settings.builder().put(QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80).build(); + Settings settings = Settings.builder().put(NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80).build(); ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - QuerySandboxServiceSettings querySandboxServiceSettings = new QuerySandboxServiceSettings(settings, cs); + ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); assertThrows(IllegalArgumentException.class, - () -> querySandboxServiceSettings.setNodeLevelJvmRejectionThreshold(0.96)); + () -> resourceLimitGroupServiceSettings.setNodeLevelJvmRejectionThreshold(0.96)); } /** @@ -117,13 +119,13 @@ public void testInValidNodeLevelCancellationThresholdCase1() { * When the value is set less than {@code query_sandbox.node.rejection_threshold} */ public void testInValidNodeLevelCancellationThresholdCase2() { - Settings settings = Settings.builder().put(QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.70) - .put(QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80) + Settings settings = Settings.builder().put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.70) + .put(NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80) .build(); ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - QuerySandboxServiceSettings querySandboxServiceSettings = new QuerySandboxServiceSettings(settings, cs); + ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); assertThrows(IllegalArgumentException.class, - () -> querySandboxServiceSettings.setNodeLevelJvmRejectionThreshold(0.85)); + () -> resourceLimitGroupServiceSettings.setNodeLevelJvmRejectionThreshold(0.85)); } } From ace034c78a4bfb46ebe58e80bdee52cd8d48103a Mon Sep 17 00:00:00 2001 From: Kaushal Kumar Date: Mon, 15 Apr 2024 12:30:09 -0700 Subject: [PATCH 04/15] add sandbox schema Signed-off-by: Kaushal Kumar --- .../opensearch/cluster/metadata/Metadata.java | 39 ++++ .../cluster/metadata/ResourceLimitGroup.java | 211 ++++++++++++++++++ .../metadata/ResourceLimitGroupMetadata.java | 200 +++++++++++++++++ 3 files changed, 450 insertions(+) create mode 100644 server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java create mode 100644 server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroupMetadata.java diff --git a/server/src/main/java/org/opensearch/cluster/metadata/Metadata.java b/server/src/main/java/org/opensearch/cluster/metadata/Metadata.java index 59dc86ea28ed6..f6bb5f4c4a814 100644 --- a/server/src/main/java/org/opensearch/cluster/metadata/Metadata.java +++ b/server/src/main/java/org/opensearch/cluster/metadata/Metadata.java @@ -835,6 +835,15 @@ public Map views() { return Optional.ofNullable((ViewMetadata) this.custom(ViewMetadata.TYPE)).map(ViewMetadata::views).orElse(Collections.emptyMap()); } + public Map resourceLimitGroups() { + return + Optional.ofNullable( + (ResourceLimitGroupMetadata) this.custom(ResourceLimitGroupMetadata.TYPE)). + map(ResourceLimitGroupMetadata::resourceLimitGroups) + .orElse(Collections.emptyMap()); + + } + public DecommissionAttributeMetadata decommissionAttributeMetadata() { return custom(DecommissionAttributeMetadata.TYPE); } @@ -1329,6 +1338,36 @@ public Builder removeDataStream(String name) { return this; } + public Builder resourceLimitGroups(final Map resourceLimitGroups) { + this.customs.put(ResourceLimitGroupMetadata.TYPE, new ResourceLimitGroupMetadata(resourceLimitGroups)); + return this; + } + + public ResourceLimitGroup getResourceLimitGroup(final String resourceLimitGroupName) { + return getResourceLimitGroups().get(resourceLimitGroupName); + } + + public Builder put(final ResourceLimitGroup resourceLimitGroup) { + Objects.requireNonNull(resourceLimitGroup, "resourceLimitGroup should not be null"); + Map existing = new HashMap<>(getResourceLimitGroups()); + existing.put(resourceLimitGroup.getName(), resourceLimitGroup); + return resourceLimitGroups(existing); + } + + public Builder removeResourceLimitGroup(final String resourceLimitGroupName) { + Objects.requireNonNull(resourceLimitGroupName, "resourceLimitGroup should not be null"); + Map existing = new HashMap<>(getResourceLimitGroups()); + existing.remove(resourceLimitGroupName); + return resourceLimitGroups(existing); + } + + private Map getResourceLimitGroups() { + return Optional.ofNullable(this.customs.get(ResourceLimitGroupMetadata.TYPE)) + .map(o -> (ResourceLimitGroupMetadata) o) + .map(ResourceLimitGroupMetadata::resourceLimitGroups) + .orElse(Collections.emptyMap()); + } + private Map getViews() { return Optional.ofNullable(customs.get(ViewMetadata.TYPE)) .map(o -> (ViewMetadata) o) diff --git a/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java b/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java new file mode 100644 index 0000000000000..84bdfccd570d7 --- /dev/null +++ b/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java @@ -0,0 +1,211 @@ +/* + * 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.cluster.metadata; + +import org.opensearch.cluster.AbstractDiffable; +import org.opensearch.cluster.Diff; +import org.opensearch.common.annotation.ExperimentalApi; +import org.opensearch.core.ParseField; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.common.io.stream.Writeable; +import org.opensearch.core.xcontent.ConstructingObjectParser; +import org.opensearch.core.xcontent.ToXContentObject; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.core.xcontent.XContentParser; + +import java.io.IOException; +import java.util.List; +import java.util.Objects; + +/** + * Class to define the ResourceLimitGroup schema + * { + * "name": "analytics", + * "resourceLimits": [ + * { + * "resourceName": "jvm", + * "value": 0.4 + * } + * ] + * } + */ +@ExperimentalApi +public class ResourceLimitGroup extends AbstractDiffable implements ToXContentObject { + + private final String name; + private final List resourceLimits; + + private static final List ALLOWED_RESOURCES = List.of("jvm"); + + public static final ParseField NAME_FIELD = new ParseField("name"); + public static final ParseField RESOURCE_LIMITS_FIELD = new ParseField("resourceLimits"); + + + @SuppressWarnings("unchecked") + private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( + "ResourceLimitGroupParser", + args -> new ResourceLimitGroup((String) args[0], (List) args[1]) + ); + + static { + PARSER.declareString(ConstructingObjectParser.constructorArg(), NAME_FIELD); + PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), (p, c) -> ResourceLimit.fromXContent(p), RESOURCE_LIMITS_FIELD); + } + + public ResourceLimitGroup(String name, List resourceLimits) { + this.name = name; + this.resourceLimits = resourceLimits; + } + + public ResourceLimitGroup(StreamInput in) throws IOException { + this(in.readString(), in.readList(ResourceLimit::new)); + } + + /** + * Class to hold the system resource limits; + * sample Schema + * + */ + @ExperimentalApi + public static class ResourceLimit implements Writeable, ToXContentObject { + private final String resourceName; + private final Double value; + + static final ParseField RESOURCE_NAME_FIELD = new ParseField("resourceName"); + static final ParseField RESOURCE_VALUE_FIELD = new ParseField("value"); + + public static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( + "ResourceLimitParser", + args -> new ResourceLimit((String) args[0], (Double) args[1]) + ); + + static { + PARSER.declareString(ConstructingObjectParser.constructorArg(), RESOURCE_NAME_FIELD); + PARSER.declareDouble(ConstructingObjectParser.constructorArg(), RESOURCE_VALUE_FIELD); + } + + public ResourceLimit(String resourceName, Double value) { + Objects.requireNonNull(resourceName, "resourceName can't be null"); + Objects.requireNonNull(value, "resource value can't be null"); + + if (Double.compare(value, 1.0) > 0) { + throw new IllegalArgumentException("resource value should be less than 1.0"); + } + + if (!ALLOWED_RESOURCES.contains(resourceName.toLowerCase())) { + throw new IllegalArgumentException("resource has to be valid, valid resources " + + ALLOWED_RESOURCES.stream().reduce((x, e) -> x + ", " + e).get()); + } + this.resourceName = resourceName; + this.value = value; + } + + public ResourceLimit(StreamInput in) throws IOException { + this(in.readString(), in.readDouble()); + } + + /** + * Write this into the {@linkplain StreamOutput}. + * + * @param out + */ + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(resourceName); + out.writeDouble(value); + } + + /** + * @param builder + * @param params + * @return + * @throws IOException + */ + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field(RESOURCE_NAME_FIELD.getPreferredName(), resourceName); + builder.field(RESOURCE_VALUE_FIELD.getPreferredName(), value); + builder.endObject(); + return builder; + } + + public static ResourceLimit fromXContent(final XContentParser parser) throws IOException { + return PARSER.parse(parser, null); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ResourceLimit that = (ResourceLimit) o; + return Objects.equals(resourceName, that.resourceName) && Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(resourceName, value); + } + } + + + /** + * Write this into the {@linkplain StreamOutput}. + * + * @param out + */ + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(name); + out.writeList(resourceLimits); + } + + /** + * @param builder + * @param params + * @return + * @throws IOException + */ + @Override + public XContentBuilder toXContent(final XContentBuilder builder, final Params params) throws IOException { + builder.startObject(); + builder.field(NAME_FIELD.getPreferredName(),name); + builder.field(RESOURCE_LIMITS_FIELD.getPreferredName(), resourceLimits); + builder.endObject(); + return builder; + } + + + public static ResourceLimitGroup fromXContent(final XContentParser parser) throws IOException { + return PARSER.parse(parser, null); + } + + + public static Diff readDiff(final StreamInput in) throws IOException { + return readDiffFrom(ResourceLimitGroup::new, in); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ResourceLimitGroup that = (ResourceLimitGroup) o; + return Objects.equals(name, that.name) && Objects.equals(resourceLimits, that.resourceLimits); + } + + @Override + public int hashCode() { + return Objects.hash(name, resourceLimits); + } + + public String getName() { + return name; + } +} diff --git a/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroupMetadata.java b/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroupMetadata.java new file mode 100644 index 0000000000000..144b4c9e06227 --- /dev/null +++ b/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroupMetadata.java @@ -0,0 +1,200 @@ +/* + * 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.cluster.metadata; + +import org.opensearch.Version; +import org.opensearch.cluster.Diff; +import org.opensearch.cluster.DiffableUtils; +import org.opensearch.cluster.NamedDiff; +import org.opensearch.common.annotation.ExperimentalApi; +import org.opensearch.core.ParseField; +import org.opensearch.core.common.Strings; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.ConstructingObjectParser; +import org.opensearch.core.xcontent.MediaTypeRegistry; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.core.xcontent.XContentParser; + +import java.io.IOException; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import static org.opensearch.cluster.metadata.Metadata.ALL_CONTEXTS; + +@ExperimentalApi +public class ResourceLimitGroupMetadata implements Metadata.Custom { + public static final String TYPE = "resourceLimitGroup"; + private static final ParseField RESOURCE_LIMIT_GROUP_FIELD = new ParseField("resourceLimitGroups"); + + @SuppressWarnings("unchecked") + static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( + "resourceLimitGroupParser", + args -> new ResourceLimitGroupMetadata((Map) args [0]) + ); + + static { + PARSER.declareObject(ConstructingObjectParser.constructorArg(), (p, c) -> { + Map resourceLimitGroupMap = new HashMap<>(); + while (p.nextToken() != XContentParser.Token.END_OBJECT) { + resourceLimitGroupMap.put(p.currentName(), ResourceLimitGroup.fromXContent(p)); + } + return resourceLimitGroupMap; + }, RESOURCE_LIMIT_GROUP_FIELD); + } + + + private final Map resourceLimitGroups; + + public ResourceLimitGroupMetadata(Map resourceLimitGroups) { + this.resourceLimitGroups = resourceLimitGroups; + } + + + public Map resourceLimitGroups() { + return this.resourceLimitGroups; + } + + /** + * Returns the name of the writeable object + */ + @Override + public String getWriteableName() { + return TYPE; + } + + /** + * The minimal version of the recipient this object can be sent to + */ + @Override + public Version getMinimalSupportedVersion() { + return Version.V_3_0_0; + } + + /** + * Write this into the {@linkplain StreamOutput}. + * + * @param out + */ + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeMap(resourceLimitGroups, StreamOutput::writeString, (stream, val) -> val.writeTo(stream)); + } + + /** + * @param builder + * @param params + * @return + * @throws IOException + */ + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(RESOURCE_LIMIT_GROUP_FIELD.getPreferredName()); + for (Map.Entry entry: resourceLimitGroups.entrySet()) { + builder.field(entry.getKey(), entry.getValue()); + } + builder.endObject(); + return builder; + } + + public static ResourceLimitGroupMetadata fromXContent(XContentParser parser) throws IOException { + return PARSER.parse(parser, null); + } + + /** + * Returns serializable object representing differences between this and previousState + * + * @param previousState + */ + @Override + public Diff diff(final Metadata.Custom previousState) { + return new ResourceLimitGroupMetadataDiff((ResourceLimitGroupMetadata) previousState, this); + } + + /** + * @return + */ + @Override + public EnumSet context() { + return ALL_CONTEXTS; + } + + /** + * ResourceLimitGroupMetadataDiff + */ + static class ResourceLimitGroupMetadataDiff implements NamedDiff { + final Diff> dataStreanDiff; + + + ResourceLimitGroupMetadataDiff(final ResourceLimitGroupMetadata before, + final ResourceLimitGroupMetadata after) { + dataStreanDiff = DiffableUtils.diff(before.resourceLimitGroups, + after.resourceLimitGroups, + DiffableUtils.getStringKeySerializer()); + } + + ResourceLimitGroupMetadataDiff(final StreamInput in) throws IOException { + this.dataStreanDiff = DiffableUtils.readJdkMapDiff(in, + DiffableUtils.getStringKeySerializer(), + ResourceLimitGroup::new, + ResourceLimitGroup::readDiff); + } + + /** + * Returns the name of the writeable object + */ + @Override + public String getWriteableName() { + return TYPE; + } + + /** + * Write this into the {@linkplain StreamOutput}. + * + * @param out + */ + @Override + public void writeTo(StreamOutput out) throws IOException { + dataStreanDiff.writeTo(out); + } + + /** + * Applies difference to the specified part and returns the resulted part + * + * @param part + */ + @Override + public Metadata.Custom apply(Metadata.Custom part) { + return new ResourceLimitGroupMetadata(dataStreanDiff.apply( + ((ResourceLimitGroupMetadata) part).resourceLimitGroups) + ); + } + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ResourceLimitGroupMetadata that = (ResourceLimitGroupMetadata) o; + return Objects.equals(resourceLimitGroups, that.resourceLimitGroups); + } + + @Override + public int hashCode() { + return Objects.hash(resourceLimitGroups); + } + + @Override + public String toString() { + return Strings.toString(MediaTypeRegistry.JSON, this); + } +} From b7223139bb123da799801576fe2c1e57ae280432 Mon Sep 17 00:00:00 2001 From: Ruirui Zhang Date: Wed, 17 Apr 2024 21:35:10 -0700 Subject: [PATCH 05/15] add resource limit group crud apis Signed-off-by: Ruirui Zhang --- .../TransportIndexCorrelationRuleAction.java | 2 +- .../CreateResourceLimitGroupAction.java | 36 ++ .../CreateResourceLimitGroupRequest.java | 128 ++++++ .../CreateResourceLimitGroupResponse.java | 86 ++++ .../DeleteResourceLimitGroupAction.java | 37 ++ .../DeleteResourceLimitGroupRequest.java | 93 ++++ .../DeleteResourceLimitGroupResponse.java | 93 ++++ .../GetResourceLimitGroupAction.java | 37 ++ .../GetResourceLimitGroupRequest.java | 94 ++++ .../GetResourceLimitGroupResponse.java | 93 ++++ .../ResourceLimitGroupPlugin.java | 47 +- .../ResourceLimitGroupPluginModule.java | 31 ++ .../resource_limit_group/SampleAction.java | 20 - .../resource_limit_group/SampleRequest.java | 43 -- .../resource_limit_group/SampleResponse.java | 52 --- .../SampleTransportAction.java | 35 -- ...ansportCreateResourceLimitGroupAction.java | 59 +++ ...ansportDeleteResourceLimitGroupAction.java | 59 +++ .../TransportGetResourceLimitGroupAction.java | 59 +++ ...ansportUpdateResourceLimitGroupAction.java | 59 +++ .../UpdateResourceLimitGroupAction.java | 36 ++ .../UpdateResourceLimitGroupRequest.java | 158 +++++++ .../UpdateResourceLimitGroupResponse.java | 86 ++++ .../resource_limit_group/package-info.java | 12 + .../RestCreateResourceLimitGroupAction.java | 75 ++++ .../RestDeleteResourceLimitGroupAction.java | 66 +++ .../rest/RestGetResourceLimitGroupAction.java | 66 +++ .../RestUpdateResourceLimitGroupAction.java | 76 ++++ .../rest/SampleRestAction.java | 71 --- .../rest/package-info.java | 3 + .../service/Persistable.java | 52 +++ .../ResourceLimitGroupPersistenceService.java | 420 ++++++++++++++++++ .../service/package-info.java | 16 + .../org/opensearch/cluster/ClusterModule.java | 7 + .../opensearch/cluster/metadata/Metadata.java | 1 - .../cluster/metadata/ResourceLimitGroup.java | 115 ++++- .../metadata/ResourceLimitGroupMetadata.java | 14 + .../common/settings/ClusterSettings.java | 5 +- .../ResourceLimitGroupService.java | 16 +- .../module/ResourceLimitGroupModule.java | 2 + ...imitsGroupResourceUsageTrackerService.java | 26 +- 41 files changed, 2197 insertions(+), 289 deletions(-) create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupAction.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequest.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponse.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupAction.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupRequest.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponse.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupAction.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequest.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponse.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPluginModule.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleAction.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleRequest.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleResponse.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleTransportAction.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportCreateResourceLimitGroupAction.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportDeleteResourceLimitGroupAction.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportGetResourceLimitGroupAction.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportUpdateResourceLimitGroupAction.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupAction.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequest.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponse.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/package-info.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestCreateResourceLimitGroupAction.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestDeleteResourceLimitGroupAction.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestGetResourceLimitGroupAction.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestUpdateResourceLimitGroupAction.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/SampleRestAction.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/Persistable.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceService.java create mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/package-info.java diff --git a/plugins/events-correlation-engine/src/main/java/org/opensearch/plugin/correlation/rules/transport/TransportIndexCorrelationRuleAction.java b/plugins/events-correlation-engine/src/main/java/org/opensearch/plugin/correlation/rules/transport/TransportIndexCorrelationRuleAction.java index 53e3fdec52700..7b4fb670c4aee 100644 --- a/plugins/events-correlation-engine/src/main/java/org/opensearch/plugin/correlation/rules/transport/TransportIndexCorrelationRuleAction.java +++ b/plugins/events-correlation-engine/src/main/java/org/opensearch/plugin/correlation/rules/transport/TransportIndexCorrelationRuleAction.java @@ -70,7 +70,7 @@ public TransportIndexCorrelationRuleAction( ClusterService clusterService, CorrelationRuleIndices correlationRuleIndices ) { - super(IndexCorrelationRuleAction.NAME, transportService, IndexCorrelationRuleRequest::new); + super(IndexCorrelationRuleAction.NAME, transportService, actionFilters, IndexCorrelationRuleRequest::new); this.client = client; this.clusterService = clusterService; this.correlationRuleIndices = correlationRuleIndices; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupAction.java new file mode 100644 index 0000000000000..4b002d85f7f0e --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupAction.java @@ -0,0 +1,36 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.action.ActionType; + +/** + * Rest action to create Resource Limit Group + * + * @opensearch.api + */ +public class CreateResourceLimitGroupAction extends ActionType { + + /** + * An instance of CreateResourceLimitGroupAction + */ + public static final CreateResourceLimitGroupAction INSTANCE = new CreateResourceLimitGroupAction(); + + /** + * Name for CreateResourceLimitGroupAction + */ + public static final String NAME = "cluster:admin/opensearch/resource_limit_group/_create"; + + /** + * Default constructor + */ + private CreateResourceLimitGroupAction() { + super(NAME, CreateResourceLimitGroupResponse::new); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequest.java new file mode 100644 index 0000000000000..11c08d41191df --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequest.java @@ -0,0 +1,128 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.action.ActionRequest; +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.common.io.stream.Writeable; +import org.opensearch.core.xcontent.XContentParser; + +import java.io.IOException; +import java.util.List; + +/** + * A request for create Resource Limit Group + * + * @opensearch.internal + */ +public class CreateResourceLimitGroupRequest extends ActionRequest implements Writeable.Reader { + String name; + List resourceLimits; + String enforcement; + + /** + * Default constructor for CreateResourceLimitGroupRequest + */ + public CreateResourceLimitGroupRequest() {} + + /** + * Constructor for CreateResourceLimitGroupRequest + * @param resourceLimitGroup - A {@link ResourceLimitGroup} object + */ + public CreateResourceLimitGroupRequest(ResourceLimitGroup resourceLimitGroup) { + this.name = resourceLimitGroup.getName(); + this.resourceLimits = resourceLimitGroup.getResourceLimits(); + this.enforcement = resourceLimitGroup.getEnforcement(); + } + + /** + * Constructor for CreateResourceLimitGroupRequest + * @param in - A {@link StreamInput} object + */ + public CreateResourceLimitGroupRequest(StreamInput in) throws IOException { + super(in); + name = in.readString(); + resourceLimits = in.readList(ResourceLimit::new); + enforcement = in.readString(); + } + + @Override + public CreateResourceLimitGroupRequest read(StreamInput in) throws IOException { + return new CreateResourceLimitGroupRequest(in); + } + + /** + * Generate a CreateResourceLimitGroupRequest from XContent + * @param parser - A {@link XContentParser} object + */ + public static CreateResourceLimitGroupRequest fromXContent(XContentParser parser) throws IOException { + ResourceLimitGroup resourceLimitGroup = ResourceLimitGroup.fromXContent(parser); + return new CreateResourceLimitGroupRequest(resourceLimitGroup); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + /** + * Name getter + */ + public String getName() { + return name; + } + + /** + * Name setter + * @param name - name to be set + */ + public void setName(String name) { + this.name = name; + } + + /** + * ResourceLimits getter + */ + public List getResourceLimits() { + return resourceLimits; + } + + /** + * ResourceLimits setter + * @param resourceLimits - ResourceLimit to be set + */ + public void setResourceLimits(List resourceLimits) { + this.resourceLimits = resourceLimits; + } + + /** + * Enforcement getter + */ + public String getEnforcement() { + return enforcement; + } + + /** + * Enforcement setter + * @param enforcement - enforcement to be set + */ + public void setEnforcement(String enforcement) { + this.enforcement = enforcement; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + ResourceLimitGroup.writeToOutputStream(out, name, resourceLimits, enforcement); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponse.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponse.java new file mode 100644 index 0000000000000..290de02fc4d20 --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponse.java @@ -0,0 +1,86 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.core.action.ActionResponse; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.core.xcontent.ToXContentObject; +import org.opensearch.core.xcontent.XContentBuilder; + +import java.io.IOException; + +/** + * Response for the create API for resource limit groups + * + * @opensearch.internal + */ +public class CreateResourceLimitGroupResponse extends ActionResponse implements ToXContent, ToXContentObject { + private final ResourceLimitGroup resourceLimitGroup; + private RestStatus restStatus; + + /** + * Constructor for CreateResourceLimitGroupResponse + */ + public CreateResourceLimitGroupResponse() { + this.resourceLimitGroup = null; + } + + /** + * Constructor for CreateResourceLimitGroupResponse + * @param resourceLimitGroup - The resource limit group to be created + */ + public CreateResourceLimitGroupResponse(final ResourceLimitGroup resourceLimitGroup) { + this.resourceLimitGroup = resourceLimitGroup; + } + + /** + * Constructor for CreateResourceLimitGroupResponse + * @param in - A {@link StreamInput} object + */ + public CreateResourceLimitGroupResponse(StreamInput in) throws IOException { + resourceLimitGroup = new ResourceLimitGroup(in); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + resourceLimitGroup.writeTo(out); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + resourceLimitGroup.toXContent(builder, params); + return builder; + } + + /** + * resourceLimitGroup getter + */ + public ResourceLimitGroup getResourceLimitGroup() { + return resourceLimitGroup; + } + + /** + * restStatus getter + */ + public RestStatus getRestStatus() { + return restStatus; + } + + /** + * restStatus setter + * @param restStatus - A {@link RestStatus} object + */ + public void setRestStatus(RestStatus restStatus) { + this.restStatus = restStatus; + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupAction.java new file mode 100644 index 0000000000000..184ffdbc5ca51 --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupAction.java @@ -0,0 +1,37 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.action.ActionType; + +/** + * Rest action to delete Resource Limit Group + * + * @opensearch.api + */ +public class DeleteResourceLimitGroupAction extends ActionType { + + /** + /** + * An instance of DeleteResourceLimitGroupAction + */ + public static final DeleteResourceLimitGroupAction INSTANCE = new DeleteResourceLimitGroupAction(); + + /** + * Name for DeleteResourceLimitGroupAction + */ + public static final String NAME = "cluster:admin/opensearch/resource_limit_group/_delete"; + + /** + * Default constructor + */ + private DeleteResourceLimitGroupAction() { + super(NAME, DeleteResourceLimitGroupResponse::new); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupRequest.java new file mode 100644 index 0000000000000..10a66828ca58d --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupRequest.java @@ -0,0 +1,93 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.action.ActionRequest; +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.common.io.stream.Writeable; +import org.opensearch.core.xcontent.XContentParser; + +import java.io.IOException; + +/** + * A request for delete Resource Limit Group + * + * @opensearch.internal + */ +public class DeleteResourceLimitGroupRequest extends ActionRequest implements Writeable.Reader { + String name; + + /** + * Default constructor for DeleteResourceLimitGroupRequest + * @param name - name for the Resource Limit Group to get + */ + public DeleteResourceLimitGroupRequest(String name) { + this.name = name; + } + + /** + * Constructor for DeleteResourceLimitGroupRequest + * @param resourceLimitGroup - A {@link ResourceLimitGroup} object + */ + public DeleteResourceLimitGroupRequest(ResourceLimitGroup resourceLimitGroup) { + this.name = resourceLimitGroup.getName(); + } + + /** + * Constructor for DeleteResourceLimitGroupRequest + * @param in - A {@link StreamInput} object + */ + public DeleteResourceLimitGroupRequest(StreamInput in) throws IOException { + super(in); + name = in.readOptionalString(); + } + + @Override + public DeleteResourceLimitGroupRequest read(StreamInput in) throws IOException { + return new DeleteResourceLimitGroupRequest(in); + } + + /** + * Generate a DeleteResourceLimitGroupRequest from XContent + * @param parser - A {@link XContentParser} object + */ + public static DeleteResourceLimitGroupRequest fromXContent(XContentParser parser) throws IOException { + ResourceLimitGroup resourceLimitGroup = ResourceLimitGroup.fromXContent(parser); + return new DeleteResourceLimitGroupRequest(resourceLimitGroup); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + /** + * Name getter + */ + public String getName() { + return name; + } + + /** + * Name setter + * @param name - name to be set + */ + public void setName(String name) { + this.name = name; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeOptionalString(name); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponse.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponse.java new file mode 100644 index 0000000000000..5b579a56bfe37 --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponse.java @@ -0,0 +1,93 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.core.action.ActionResponse; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.core.xcontent.ToXContentObject; +import org.opensearch.core.xcontent.XContentBuilder; + +import java.io.IOException; +import java.util.List; + +/** + * Response for the delete API for resource limit groups + * + * @opensearch.internal + */ +public class DeleteResourceLimitGroupResponse extends ActionResponse implements ToXContent, ToXContentObject { + private final List resourceLimitGroups; + private RestStatus restStatus; + + /** + * Constructor for DeleteResourceLimitGroupResponse + */ + public DeleteResourceLimitGroupResponse() { + this.resourceLimitGroups = null; + } + + /** + * Constructor for DeleteResourceLimitGroupResponse + * @param resourceLimitGroups - The resource limit group list to be fetched + */ + public DeleteResourceLimitGroupResponse(final List resourceLimitGroups) { + this.resourceLimitGroups = resourceLimitGroups; + } + + /** + * Constructor for DeleteResourceLimitGroupResponse + * @param in - A {@link StreamInput} object + */ + public DeleteResourceLimitGroupResponse(StreamInput in) throws IOException { + this.resourceLimitGroups = in.readList(ResourceLimitGroup::new); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeList(resourceLimitGroups); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.startArray("deleted"); + for (ResourceLimitGroup rlg : resourceLimitGroups) { + rlg.toXContent(builder, params); + } + builder.endArray(); + builder.endObject(); + return builder; + } + + /** + * resourceLimitGroup getter + */ + public List getResourceLimitGroups() { + return resourceLimitGroups; + } + + /** + * restStatus getter + */ + public RestStatus getRestStatus() { + return restStatus; + } + + /** + * restStatus setter + * @param restStatus - A {@link RestStatus} object + */ + public void setRestStatus(RestStatus restStatus) { + this.restStatus = restStatus; + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupAction.java new file mode 100644 index 0000000000000..97285d75b65ed --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupAction.java @@ -0,0 +1,37 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.action.ActionType; + +/** + * Rest action to get Resource Limit Group + * + * @opensearch.api + */ +public class GetResourceLimitGroupAction extends ActionType { + + /** + /** + * An instance of GetResourceLimitGroupAction + */ + public static final GetResourceLimitGroupAction INSTANCE = new GetResourceLimitGroupAction(); + + /** + * Name for GetResourceLimitGroupAction + */ + public static final String NAME = "cluster:admin/opensearch/resource_limit_group/_get"; + + /** + * Default constructor + */ + private GetResourceLimitGroupAction() { + super(NAME, GetResourceLimitGroupResponse::new); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequest.java new file mode 100644 index 0000000000000..6cc09722f7e0f --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequest.java @@ -0,0 +1,94 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.action.ActionRequest; +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.common.io.stream.Writeable; +import org.opensearch.core.xcontent.XContentParser; + +import java.io.IOException; +import java.util.List; + +/** + * A request for get Resource Limit Group + * + * @opensearch.internal + */ +public class GetResourceLimitGroupRequest extends ActionRequest implements Writeable.Reader { + String name; + + /** + * Default constructor for GetResourceLimitGroupRequest + * @param name - name for the Resource Limit Group to get + */ + public GetResourceLimitGroupRequest(String name) { + this.name = name; + } + + /** + * Constructor for GetResourceLimitGroupRequest + * @param resourceLimitGroup - A {@link ResourceLimitGroup} object + */ + public GetResourceLimitGroupRequest(ResourceLimitGroup resourceLimitGroup) { + this.name = resourceLimitGroup.getName(); + } + + /** + * Constructor for GetResourceLimitGroupRequest + * @param in - A {@link StreamInput} object + */ + public GetResourceLimitGroupRequest(StreamInput in) throws IOException { + super(in); + name = in.readOptionalString(); + } + + @Override + public GetResourceLimitGroupRequest read(StreamInput in) throws IOException { + return new GetResourceLimitGroupRequest(in); + } + + /** + * Generate a GetResourceLimitGroupRequest from XContent + * @param parser - A {@link XContentParser} object + */ + public static GetResourceLimitGroupRequest fromXContent(XContentParser parser) throws IOException { + ResourceLimitGroup resourceLimitGroup = ResourceLimitGroup.fromXContent(parser); + return new GetResourceLimitGroupRequest(resourceLimitGroup); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + /** + * Name getter + */ + public String getName() { + return name; + } + + /** + * Name setter + * @param name - name to be set + */ + public void setName(String name) { + this.name = name; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeOptionalString(name); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponse.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponse.java new file mode 100644 index 0000000000000..f9b299af3a807 --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponse.java @@ -0,0 +1,93 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.core.action.ActionResponse; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.core.xcontent.ToXContentObject; +import org.opensearch.core.xcontent.XContentBuilder; + +import java.io.IOException; +import java.util.List; + +/** + * Response for the get API for resource limit groups + * + * @opensearch.internal + */ +public class GetResourceLimitGroupResponse extends ActionResponse implements ToXContent, ToXContentObject { + private final List resourceLimitGroups; + private RestStatus restStatus; + + /** + * Constructor for GetResourceLimitGroupResponse + */ + public GetResourceLimitGroupResponse() { + this.resourceLimitGroups = null; + } + + /** + * Constructor for GetResourceLimitGroupResponse + * @param resourceLimitGroups - The resource limit group list to be fetched + */ + public GetResourceLimitGroupResponse(final List resourceLimitGroups) { + this.resourceLimitGroups = resourceLimitGroups; + } + + /** + * Constructor for GetResourceLimitGroupResponse + * @param in - A {@link StreamInput} object + */ + public GetResourceLimitGroupResponse(StreamInput in) throws IOException { + this.resourceLimitGroups = in.readList(ResourceLimitGroup::new); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeList(resourceLimitGroups); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.startArray("resource_limit_groups"); + for (ResourceLimitGroup rlg : resourceLimitGroups) { + rlg.toXContent(builder, params); + } + builder.endArray(); + builder.endObject(); + return builder; + } + + /** + * resourceLimitGroup getter + */ + public List getResourceLimitGroups() { + return resourceLimitGroups; + } + + /** + * restStatus getter + */ + public RestStatus getRestStatus() { + return restStatus; + } + + /** + * restStatus setter + * @param restStatus - A {@link RestStatus} object + */ + public void setRestStatus(RestStatus restStatus) { + this.restStatus = restStatus; + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java index 1559c6c3e6316..27a927c93b4be 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java @@ -1,46 +1,59 @@ package org.opensearch.plugin.resource_limit_group; import org.opensearch.action.ActionRequest; -import org.opensearch.action.ActionType; -import org.opensearch.action.support.ActionFilter; import org.opensearch.cluster.metadata.IndexNameExpressionResolver; import org.opensearch.cluster.node.DiscoveryNodes; +import org.opensearch.common.inject.Module; import org.opensearch.common.settings.ClusterSettings; import org.opensearch.common.settings.IndexScopedSettings; import org.opensearch.common.settings.Settings; import org.opensearch.common.settings.SettingsFilter; import org.opensearch.core.action.ActionResponse; -import org.opensearch.plugin.resource_limit_group.rest.SampleRestAction; +import org.opensearch.plugin.resource_limit_group.rest.RestCreateResourceLimitGroupAction; +import org.opensearch.plugin.resource_limit_group.rest.RestDeleteResourceLimitGroupAction; +import org.opensearch.plugin.resource_limit_group.rest.RestGetResourceLimitGroupAction; +import org.opensearch.plugin.resource_limit_group.rest.RestUpdateResourceLimitGroupAction; import org.opensearch.plugins.ActionPlugin; import org.opensearch.plugins.Plugin; import org.opensearch.rest.RestController; import org.opensearch.rest.RestHandler; +import java.util.Collection; import java.util.List; import java.util.function.Supplier; +/** + * Plugin class for Resource Limit Group + */ public class ResourceLimitGroupPlugin extends Plugin implements ActionPlugin { + /** - * Actions added by this plugin. + * Default constructor */ + public ResourceLimitGroupPlugin() {} + @Override public List> getActions() { - return List.of(new ActionPlugin.ActionHandler<>(SampleAction.INSTANCE, SampleTransportAction.class)); + return List.of( + new ActionPlugin.ActionHandler<>(CreateResourceLimitGroupAction.INSTANCE, TransportCreateResourceLimitGroupAction.class), + new ActionPlugin.ActionHandler<>(GetResourceLimitGroupAction.INSTANCE, TransportGetResourceLimitGroupAction.class), + new ActionPlugin.ActionHandler<>(UpdateResourceLimitGroupAction.INSTANCE, TransportUpdateResourceLimitGroupAction.class), + new ActionPlugin.ActionHandler<>(DeleteResourceLimitGroupAction.INSTANCE, TransportDeleteResourceLimitGroupAction.class) + ); } - /** - * Rest handlers added by this plugin. - * - * @param settings - * @param restController - * @param clusterSettings - * @param indexScopedSettings - * @param settingsFilter - * @param indexNameExpressionResolver - * @param nodesInCluster - */ @Override public List getRestHandlers(Settings settings, RestController restController, ClusterSettings clusterSettings, IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter, IndexNameExpressionResolver indexNameExpressionResolver, Supplier nodesInCluster) { - return List.of(new SampleRestAction()); + return List.of( + new RestCreateResourceLimitGroupAction(), + new RestGetResourceLimitGroupAction(), + new RestUpdateResourceLimitGroupAction(), + new RestDeleteResourceLimitGroupAction() + ); + } + + @Override + public Collection createGuiceModules() { + return List.of(new ResourceLimitGroupPluginModule()); } } diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPluginModule.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPluginModule.java new file mode 100644 index 0000000000000..16411db4fb7ce --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPluginModule.java @@ -0,0 +1,31 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.common.inject.AbstractModule; +import org.opensearch.common.inject.TypeLiteral; +import org.opensearch.plugin.resource_limit_group.service.Persistable; +import org.opensearch.plugin.resource_limit_group.service.ResourceLimitGroupPersistenceService; + +/** + * Guice Module to manage ResourceLimitGroup related objects + */ +public class ResourceLimitGroupPluginModule extends AbstractModule { + + /** + * Constructor for ResourceLimitGroupPluginModule + */ + public ResourceLimitGroupPluginModule(){} + @Override + protected void configure() { + // bind(Persistable.class).to(ResourceLimitGroupPersistenceService.class).asEagerSingleton(); + bind(new TypeLiteral>() {}).to(ResourceLimitGroupPersistenceService.class).asEagerSingleton(); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleAction.java deleted file mode 100644 index ccd870178ae63..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleAction.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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.resource_limit_group; - -import org.opensearch.action.ActionType; - -public class SampleAction extends ActionType { - - public static final SampleAction INSTANCE = new SampleAction(); - private static final String NAME = "cluster:admin/opensearch/sample_rest"; - private SampleAction() { - super(NAME, SampleResponse::new); - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleRequest.java deleted file mode 100644 index a3d673c7de1da..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleRequest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.resource_limit_group; - -import org.opensearch.action.ActionRequest; -import org.opensearch.action.ActionRequestValidationException; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; - -import java.io.IOException; - -public class SampleRequest extends ActionRequest { - - public SampleRequest() { - } - - public SampleRequest(StreamInput in) throws IOException { - super(in); - } - - /** - * @return - */ - @Override - public ActionRequestValidationException validate() { - return null; - } - - /** - * @param out - * @throws IOException - */ - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleResponse.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleResponse.java deleted file mode 100644 index 56c64ba726c9c..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleResponse.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.resource_limit_group; - -import org.opensearch.core.action.ActionResponse; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.xcontent.ToXContentObject; -import org.opensearch.core.xcontent.XContentBuilder; - -import java.io.IOException; - -public class SampleResponse extends ActionResponse implements ToXContentObject { - - public SampleResponse() { - - } - - public SampleResponse(StreamInput in) throws IOException { - super(in); - } - - /** - * Write this into the {@linkplain StreamOutput}. - * - * @param out - */ - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeString("Hello from sample plugin!"); - } - - /** - * @param builder - * @param params - * @return - * @throws IOException - */ - @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject(); - builder.field("response", "Hello plugin"); - builder.endObject(); - return builder; - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleTransportAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleTransportAction.java deleted file mode 100644 index 5d877cfcdea87..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/SampleTransportAction.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.resource_limit_group; - -import org.opensearch.action.support.ActionFilters; -import org.opensearch.action.support.HandledTransportAction; -import org.opensearch.common.inject.Inject; -import org.opensearch.core.action.ActionListener; -import org.opensearch.tasks.Task; -import org.opensearch.transport.TransportService; - -public class SampleTransportAction extends HandledTransportAction { - @Inject - public SampleTransportAction(String actionName, ActionFilters actionFilters, TransportService transportService) { - super(actionName, transportService, actionFilters, SampleRequest::new); - } - - /** - * @param task - * @param request - * @param listener - */ - @Override - protected void doExecute(Task task, SampleRequest request, ActionListener listener) { - listener.onResponse(new SampleResponse()); - } - - -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportCreateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportCreateResourceLimitGroupAction.java new file mode 100644 index 0000000000000..94f79b94437a1 --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportCreateResourceLimitGroupAction.java @@ -0,0 +1,59 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.common.inject.Inject; +import org.opensearch.core.action.ActionListener; +import org.opensearch.plugin.resource_limit_group.service.Persistable; +import org.opensearch.tasks.Task; +import org.opensearch.threadpool.ThreadPool; +import org.opensearch.transport.TransportService; + +/** + * Transport action for create Resource Limit Group + * + * @opensearch.internal + */ +public class TransportCreateResourceLimitGroupAction extends HandledTransportAction { + + private final ThreadPool threadPool; + private final Persistable resourceLimitGroupPersistenceService; + + + /** + * Constructor for TransportCreateResourceLimitGroupAction + * + * @param actionName - acrtion name + * @param transportService - a {@link TransportService} object + * @param actionFilters - a {@link ActionFilters} object + * @param threadPool - a {@link ThreadPool} object + * @param resourceLimitGroupPersistenceService - a {@link Persistable} object + */ + @Inject + public TransportCreateResourceLimitGroupAction + (String actionName, + TransportService transportService, + ActionFilters actionFilters, + ThreadPool threadPool, + Persistable resourceLimitGroupPersistenceService + ) { + super(CreateResourceLimitGroupAction.NAME, transportService, actionFilters, CreateResourceLimitGroupRequest::new); + this.threadPool = threadPool; + this.resourceLimitGroupPersistenceService = resourceLimitGroupPersistenceService; + } + + @Override + protected void doExecute(Task task, CreateResourceLimitGroupRequest request, ActionListener listener) { + ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(request.getName(), request.getResourceLimits(), request.getEnforcement()); + threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> resourceLimitGroupPersistenceService.persist(resourceLimitGroup, listener)); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportDeleteResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportDeleteResourceLimitGroupAction.java new file mode 100644 index 0000000000000..12308ee894e36 --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportDeleteResourceLimitGroupAction.java @@ -0,0 +1,59 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.common.inject.Inject; +import org.opensearch.core.action.ActionListener; +import org.opensearch.plugin.resource_limit_group.service.Persistable; +import org.opensearch.tasks.Task; +import org.opensearch.threadpool.ThreadPool; +import org.opensearch.transport.TransportService; + +/** + * Transport action for delete Resource Limit Group + * + * @opensearch.internal + */ +public class TransportDeleteResourceLimitGroupAction extends HandledTransportAction { + + private final ThreadPool threadPool; + private final Persistable resourceLimitGroupPersistenceService; + + + /** + * Constructor for TransportDeleteResourceLimitGroupAction + * + * @param actionName - acrtion name + * @param transportService - a {@link TransportService} object + * @param actionFilters - a {@link ActionFilters} object + * @param threadPool - a {@link ThreadPool} object + * @param resourceLimitGroupPersistenceService - a {@link Persistable} object + */ + @Inject + public TransportDeleteResourceLimitGroupAction + (String actionName, + TransportService transportService, + ActionFilters actionFilters, + ThreadPool threadPool, + Persistable resourceLimitGroupPersistenceService + ) { + super(DeleteResourceLimitGroupAction.NAME, transportService, actionFilters, DeleteResourceLimitGroupRequest::new); + this.threadPool = threadPool; + this.resourceLimitGroupPersistenceService = resourceLimitGroupPersistenceService; + } + + @Override + protected void doExecute(Task task, DeleteResourceLimitGroupRequest request, ActionListener listener) { + String name = request.getName(); + threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> resourceLimitGroupPersistenceService.delete(name, listener)); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportGetResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportGetResourceLimitGroupAction.java new file mode 100644 index 0000000000000..4d2d60ce8f9d6 --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportGetResourceLimitGroupAction.java @@ -0,0 +1,59 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.common.inject.Inject; +import org.opensearch.core.action.ActionListener; +import org.opensearch.plugin.resource_limit_group.service.Persistable; +import org.opensearch.tasks.Task; +import org.opensearch.threadpool.ThreadPool; +import org.opensearch.transport.TransportService; + +/** + * Transport action for get Resource Limit Group + * + * @opensearch.internal + */ +public class TransportGetResourceLimitGroupAction extends HandledTransportAction { + + private final ThreadPool threadPool; + private final Persistable resourceLimitGroupPersistenceService; + + + /** + * Constructor for TransportGetResourceLimitGroupAction + * + * @param actionName - acrtion name + * @param transportService - a {@link TransportService} object + * @param actionFilters - a {@link ActionFilters} object + * @param threadPool - a {@link ThreadPool} object + * @param resourceLimitGroupPersistenceService - a {@link Persistable} object + */ + @Inject + public TransportGetResourceLimitGroupAction + (String actionName, + TransportService transportService, + ActionFilters actionFilters, + ThreadPool threadPool, + Persistable resourceLimitGroupPersistenceService + ) { + super(GetResourceLimitGroupAction.NAME, transportService, actionFilters, GetResourceLimitGroupRequest::new); + this.threadPool = threadPool; + this.resourceLimitGroupPersistenceService = resourceLimitGroupPersistenceService; + } + + @Override + protected void doExecute(Task task, GetResourceLimitGroupRequest request, ActionListener listener) { + String name = request.getName(); + threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> resourceLimitGroupPersistenceService.get(name, listener)); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportUpdateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportUpdateResourceLimitGroupAction.java new file mode 100644 index 0000000000000..cfe13550e548e --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportUpdateResourceLimitGroupAction.java @@ -0,0 +1,59 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.common.inject.Inject; +import org.opensearch.core.action.ActionListener; +import org.opensearch.plugin.resource_limit_group.service.Persistable; +import org.opensearch.tasks.Task; +import org.opensearch.threadpool.ThreadPool; +import org.opensearch.transport.TransportService; + +/** + * Transport action for update Resource Limit Group + * + * @opensearch.internal + */ +public class TransportUpdateResourceLimitGroupAction extends HandledTransportAction { + + private final ThreadPool threadPool; + private final Persistable resourceLimitGroupPersistenceService; + + + /** + * Constructor for TransportUpdateResourceLimitGroupAction + * + * @param actionName - acrtion name + * @param transportService - a {@link TransportService} object + * @param actionFilters - a {@link ActionFilters} object + * @param threadPool - a {@link ThreadPool} object + * @param resourceLimitGroupPersistenceService - a {@link Persistable} object + */ + @Inject + public TransportUpdateResourceLimitGroupAction + (String actionName, + TransportService transportService, + ActionFilters actionFilters, + ThreadPool threadPool, + Persistable resourceLimitGroupPersistenceService + ) { + super(UpdateResourceLimitGroupAction.NAME, transportService, actionFilters, UpdateResourceLimitGroupRequest::new); + this.threadPool = threadPool; + this.resourceLimitGroupPersistenceService = resourceLimitGroupPersistenceService; + } + + @Override + protected void doExecute(Task task, UpdateResourceLimitGroupRequest request, ActionListener listener) { + ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(request.getUpdatingName(), request.getResourceLimits(), request.getEnforcement()); + threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> resourceLimitGroupPersistenceService.update(resourceLimitGroup, request.getExistingName(), listener)); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupAction.java new file mode 100644 index 0000000000000..54a41fccc258e --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupAction.java @@ -0,0 +1,36 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.action.ActionType; + +/** + * Rest action to update Resource Limit Group + * + * @opensearch.api + */ +public class UpdateResourceLimitGroupAction extends ActionType { + + /** + * An instance of UpdateResourceLimitGroupAction + */ + public static final UpdateResourceLimitGroupAction INSTANCE = new UpdateResourceLimitGroupAction(); + + /** + * Name for UpdateResourceLimitGroupAction + */ + public static final String NAME = "cluster:admin/opensearch/resource_limit_group/_update"; + + /** + * Default constructor + */ + private UpdateResourceLimitGroupAction() { + super(NAME, UpdateResourceLimitGroupResponse::new); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequest.java new file mode 100644 index 0000000000000..d6e489709ff2d --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequest.java @@ -0,0 +1,158 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.action.ActionRequest; +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.common.io.stream.Writeable; +import org.opensearch.core.xcontent.XContentParser; + +import java.io.IOException; +import java.util.List; + +/** + * A request for update Resource Limit Group + * + * @opensearch.internal + */ +public class UpdateResourceLimitGroupRequest extends ActionRequest implements Writeable.Reader { + String existingName; + String updatingName; + List resourceLimits; + String enforcement; + + /** + * Default constructor for UpdateResourceLimitGroupRequest + * @param existingName - existing name for Resource Limit Group + */ + public UpdateResourceLimitGroupRequest(String existingName) { + this.existingName = existingName; + } + + /** + * Constructor for UpdateResourceLimitGroupRequest + * @param resourceLimitGroup - A {@link ResourceLimitGroup} object + */ + public UpdateResourceLimitGroupRequest(ResourceLimitGroup resourceLimitGroup) { + this.updatingName = resourceLimitGroup.getName(); + this.resourceLimits = resourceLimitGroup.getResourceLimits(); + this.enforcement = resourceLimitGroup.getEnforcement(); + } + + /** + * Constructor for UpdateResourceLimitGroupRequest + * @param in - A {@link StreamInput} object + */ + public UpdateResourceLimitGroupRequest(StreamInput in) throws IOException { + super(in); + existingName = in.readOptionalString(); + updatingName = in.readOptionalString(); + if (in.readBoolean()) { + resourceLimits = in.readList(ResourceLimit::new); + } + enforcement = in.readOptionalString(); + } + + @Override + public UpdateResourceLimitGroupRequest read(StreamInput in) throws IOException { + return new UpdateResourceLimitGroupRequest(in); + } + + /** + * Generate a UpdateResourceLimitGroupRequest from XContent + * @param parser - A {@link XContentParser} object + */ + public static UpdateResourceLimitGroupRequest fromXContent(XContentParser parser) throws IOException { + ResourceLimitGroup resourceLimitGroup = ResourceLimitGroup.fromXContentOptionalFields(parser); + return new UpdateResourceLimitGroupRequest(resourceLimitGroup); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + /** + * existingName getter + */ + public String getExistingName() { + return existingName; + } + + /** + * existingName setter + * @param existingName - name to be set + */ + public void setExistingName(String existingName) { + this.existingName = existingName; + } + + /** + * updatingName getter + */ + public String getUpdatingName() { + return updatingName; + } + + /** + * updatingName setter + * @param updatingName - name to be set + */ + public void setUpdatingName(String updatingName) { + this.updatingName = updatingName; + } + + /** + * ResourceLimits getter + */ + public List getResourceLimits() { + return resourceLimits; + } + + /** + * ResourceLimits setter + * @param resourceLimits - ResourceLimit to be set + */ + public void setResourceLimits(List resourceLimits) { + this.resourceLimits = resourceLimits; + } + + /** + * Enforcement getter + */ + public String getEnforcement() { + return enforcement; + } + + /** + * Enforcement setter + * @param enforcement - enforcement to be set + */ + public void setEnforcement(String enforcement) { + this.enforcement = enforcement; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeOptionalString(existingName); + out.writeOptionalString(updatingName); + if (resourceLimits == null || resourceLimits.isEmpty()) { + out.writeBoolean(false); + } else { + out.writeBoolean(true); + out.writeList(resourceLimits); + } + out.writeOptionalString(enforcement); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponse.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponse.java new file mode 100644 index 0000000000000..ffe1dabf8875c --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponse.java @@ -0,0 +1,86 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.core.action.ActionResponse; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.core.xcontent.ToXContentObject; +import org.opensearch.core.xcontent.XContentBuilder; + +import java.io.IOException; + +/** + * Response for the update API for resource limit groups + * + * @opensearch.internal + */ +public class UpdateResourceLimitGroupResponse extends ActionResponse implements ToXContent, ToXContentObject { + private final ResourceLimitGroup resourceLimitGroup; + private RestStatus restStatus; + + /** + * Constructor for UpdateResourceLimitGroupResponse + */ + public UpdateResourceLimitGroupResponse() { + this.resourceLimitGroup = null; + } + + /** + * Constructor for UpdateResourceLimitGroupResponse + * @param resourceLimitGroup - The resource limit group to be updated + */ + public UpdateResourceLimitGroupResponse(final ResourceLimitGroup resourceLimitGroup) { + this.resourceLimitGroup = resourceLimitGroup; + } + + /** + * Constructor for UpdateResourceLimitGroupResponse + * @param in - A {@link StreamInput} object + */ + public UpdateResourceLimitGroupResponse(StreamInput in) throws IOException { + resourceLimitGroup = new ResourceLimitGroup(in); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + resourceLimitGroup.writeTo(out); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + resourceLimitGroup.toXContent(builder, params); + return builder; + } + + /** + * resourceLimitGroup getter + */ + public ResourceLimitGroup getResourceLimitGroup() { + return resourceLimitGroup; + } + + /** + * restStatus getter + */ + public RestStatus getRestStatus() { + return restStatus; + } + + /** + * restStatus setter + * @param restStatus - A {@link RestStatus} object + */ + public void setRestStatus(RestStatus restStatus) { + this.restStatus = restStatus; + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/package-info.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/package-info.java new file mode 100644 index 0000000000000..4b54c3e635cdc --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/package-info.java @@ -0,0 +1,12 @@ +/* + * 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. + */ + +/** + * Base Package of CRUD API of resource limit group + */ +package org.opensearch.plugin.resource_limit_group; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestCreateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestCreateResourceLimitGroupAction.java new file mode 100644 index 0000000000000..fa03a0e36c531 --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestCreateResourceLimitGroupAction.java @@ -0,0 +1,75 @@ +/* + * 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.resource_limit_group.rest; + +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.plugin.resource_limit_group.*; +import org.opensearch.rest.*; +import org.opensearch.rest.action.RestResponseListener; + +import java.io.IOException; +import java.util.List; + +import static org.opensearch.rest.RestRequest.Method.POST; +import static org.opensearch.rest.RestRequest.Method.PUT; + +/** + * Rest action to create a resource limit group + * + * @opensearch.api + */ +public class RestCreateResourceLimitGroupAction extends BaseRestHandler { + + /** + * Constructor for RestCreateResourceLimitGroupAction + */ + public RestCreateResourceLimitGroupAction(){} + + @Override + public String getName() { + return "create_resource_limit_group"; + } + + /** + * The list of {@link Route}s that this RestHandler is responsible for handling. + */ + @Override + public List routes() { + return List.of( + new Route(POST, "_resource_limit_group/"), + new Route(PUT, "_resource_limit_group/") + ); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + CreateResourceLimitGroupRequest createResourceLimitGroupRequest = new CreateResourceLimitGroupRequest(); + request.applyContentParser((parser) -> parseRestRequest(createResourceLimitGroupRequest, parser)); + return channel -> client.execute(CreateResourceLimitGroupAction.INSTANCE, createResourceLimitGroupRequest, createResourceLimitGroupResponse(channel)); + } + + private void parseRestRequest(CreateResourceLimitGroupRequest request, XContentParser parser) throws IOException { + final CreateResourceLimitGroupRequest createResourceLimitGroupRequest = CreateResourceLimitGroupRequest.fromXContent(parser); + request.setName(createResourceLimitGroupRequest.getName()); + request.setResourceLimits(createResourceLimitGroupRequest.getResourceLimits()); + request.setEnforcement(createResourceLimitGroupRequest.getEnforcement()); + } + + private RestResponseListener createResourceLimitGroupResponse(final RestChannel channel) { + return new RestResponseListener<>(channel) { + @Override + public RestResponse buildResponse(final CreateResourceLimitGroupResponse response) throws Exception { + return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS)); + } + }; + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestDeleteResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestDeleteResourceLimitGroupAction.java new file mode 100644 index 0000000000000..51c3ad90a1784 --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestDeleteResourceLimitGroupAction.java @@ -0,0 +1,66 @@ +/* + * 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.resource_limit_group.rest; + +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.plugin.resource_limit_group.*; +import org.opensearch.rest.*; +import org.opensearch.rest.action.RestResponseListener; + +import java.io.IOException; +import java.util.List; + +import static org.opensearch.rest.RestRequest.Method.DELETE; + +/** + * Rest action to delete a resource limit group + * + * @opensearch.api + */ +public class RestDeleteResourceLimitGroupAction extends BaseRestHandler { + + /** + * Constructor for RestDeleteResourceLimitGroupAction + */ + public RestDeleteResourceLimitGroupAction(){} + + @Override + public String getName() { + return "delete_resource_limit_group"; + } + + /** + * The list of {@link Route}s that this RestHandler is responsible for handling. + */ + @Override + public List routes() { + return List.of( + new Route(DELETE, "_resource_limit_group/{name}"), + new Route(DELETE, "_resource_limit_group/") + ); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + String name = request.param("name"); + DeleteResourceLimitGroupRequest deleteResourceLimitGroupRequest = new DeleteResourceLimitGroupRequest(name); + return channel -> client.execute(DeleteResourceLimitGroupAction.INSTANCE, deleteResourceLimitGroupRequest, deleteResourceLimitGroupResponse(channel)); + } + + private RestResponseListener deleteResourceLimitGroupResponse(final RestChannel channel) { + return new RestResponseListener<>(channel) { + @Override + public RestResponse buildResponse(final DeleteResourceLimitGroupResponse response) throws Exception { + return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS)); + } + }; + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestGetResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestGetResourceLimitGroupAction.java new file mode 100644 index 0000000000000..c6cb588084559 --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestGetResourceLimitGroupAction.java @@ -0,0 +1,66 @@ +/* + * 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.resource_limit_group.rest; + +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.plugin.resource_limit_group.*; +import org.opensearch.rest.*; +import org.opensearch.rest.action.RestResponseListener; + +import java.io.IOException; +import java.util.List; + +import static org.opensearch.rest.RestRequest.Method.GET; + +/** + * Rest action to get a resource limit group + * + * @opensearch.api + */ +public class RestGetResourceLimitGroupAction extends BaseRestHandler { + + /** + * Constructor for RestGetResourceLimitGroupAction + */ + public RestGetResourceLimitGroupAction(){} + + @Override + public String getName() { + return "get_resource_limit_group"; + } + + /** + * The list of {@link Route}s that this RestHandler is responsible for handling. + */ + @Override + public List routes() { + return List.of( + new Route(GET, "_resource_limit_group/{name}"), + new Route(GET, "_resource_limit_group/") + ); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + String name = request.param("name"); + GetResourceLimitGroupRequest getResourceLimitGroupRequest = new GetResourceLimitGroupRequest(name); + return channel -> client.execute(GetResourceLimitGroupAction.INSTANCE, getResourceLimitGroupRequest, getResourceLimitGroupResponse(channel)); + } + + private RestResponseListener getResourceLimitGroupResponse(final RestChannel channel) { + return new RestResponseListener<>(channel) { + @Override + public RestResponse buildResponse(final GetResourceLimitGroupResponse response) throws Exception { + return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS)); + } + }; + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestUpdateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestUpdateResourceLimitGroupAction.java new file mode 100644 index 0000000000000..b849aab807b3a --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestUpdateResourceLimitGroupAction.java @@ -0,0 +1,76 @@ +/* + * 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.resource_limit_group.rest; + +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.plugin.resource_limit_group.*; +import org.opensearch.rest.*; +import org.opensearch.rest.action.RestResponseListener; + +import java.io.IOException; +import java.util.List; + +import static org.opensearch.rest.RestRequest.Method.POST; +import static org.opensearch.rest.RestRequest.Method.PUT; + +/** + * Rest action to update a resource limit group + * + * @opensearch.api + */ +public class RestUpdateResourceLimitGroupAction extends BaseRestHandler { + + /** + * Constructor for RestUpdateResourceLimitGroupAction + */ + public RestUpdateResourceLimitGroupAction(){} + + @Override + public String getName() { + return "update_resource_limit_group"; + } + + /** + * The list of {@link Route}s that this RestHandler is responsible for handling. + */ + @Override + public List routes() { + return List.of( + new Route(POST, "_resource_limit_group/{name}"), + new Route(PUT, "_resource_limit_group/{name}") + ); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + String name = request.param("name"); + UpdateResourceLimitGroupRequest updateResourceLimitGroupRequest = new UpdateResourceLimitGroupRequest(name); + request.applyContentParser((parser) -> { parseRestRequest(updateResourceLimitGroupRequest, parser); }); + return channel -> client.execute(UpdateResourceLimitGroupAction.INSTANCE, updateResourceLimitGroupRequest, updateResourceLimitGroupResponse(channel)); + } + + private void parseRestRequest(UpdateResourceLimitGroupRequest request, XContentParser parser) throws IOException { + final UpdateResourceLimitGroupRequest updateResourceLimitGroupRequest = UpdateResourceLimitGroupRequest.fromXContent(parser); + request.setUpdatingName(updateResourceLimitGroupRequest.getUpdatingName()); + request.setResourceLimits(updateResourceLimitGroupRequest.getResourceLimits()); + request.setEnforcement(updateResourceLimitGroupRequest.getEnforcement()); + } + + private RestResponseListener updateResourceLimitGroupResponse(final RestChannel channel) { + return new RestResponseListener<>(channel) { + @Override + public RestResponse buildResponse(final UpdateResourceLimitGroupResponse response) throws Exception { + return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS)); + } + }; + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/SampleRestAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/SampleRestAction.java deleted file mode 100644 index 4b5ee25e22dc7..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/SampleRestAction.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.resource_limit_group.rest; - -import org.opensearch.client.node.NodeClient; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.plugin.resource_limit_group.SampleAction; -import org.opensearch.plugin.resource_limit_group.SampleRequest; -import org.opensearch.plugin.resource_limit_group.SampleResponse; -import org.opensearch.rest.BaseRestHandler; -import org.opensearch.rest.BytesRestResponse; -import org.opensearch.rest.RestRequest; -import org.opensearch.rest.RestResponse; -import org.opensearch.rest.action.RestResponseListener; - -import java.io.IOException; -import java.util.List; - -public class SampleRestAction extends BaseRestHandler { - /** - * @return the name of this handler. The name should be human readable and - * should describe the action that will performed when this API is - * called. This name is used in the response to the - */ - @Override - public String getName() { - return this.getClass().getName(); - } - - /** - * The list of {@link Route}s that this RestHandler is responsible for handling. - */ - @Override - public List routes() { - return List.of( - new Route(RestRequest.Method.GET, "/_sample_rest") - ); - } - - /** - * Prepare the request for execution. Implementations should consume all request params before - * returning the runnable for actual execution. Unconsumed params will immediately terminate - * execution of the request. However, some params are only used in processing the response; - * implementations can override {@link BaseRestHandler#responseParams()} to indicate such - * params. - * - * @param request the request to execute - * @param client client for executing actions on the local node - * @return the action to execute - * @throws IOException if an I/O exception occurred parsing the request and preparing for - * execution - */ - @Override - protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { - return (channel) -> { - client.execute(SampleAction.INSTANCE, new SampleRequest(), new RestResponseListener(channel) { - @Override - public RestResponse buildResponse(SampleResponse sampleResponse) throws Exception { - return new BytesRestResponse(RestStatus.OK, sampleResponse.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS)); - } - }); - }; - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/package-info.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/package-info.java index 68aad78e4a9f3..f139daedf9fb9 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/package-info.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/package-info.java @@ -6,4 +6,7 @@ * compatible open source license. */ +/** + * Package for the rest classes for resource limit group CRUD operations + */ package org.opensearch.plugin.resource_limit_group.rest; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/Persistable.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/Persistable.java new file mode 100644 index 0000000000000..3f128081d1a3d --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/Persistable.java @@ -0,0 +1,52 @@ +/* + * 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.resource_limit_group.service; + +import org.opensearch.core.action.ActionListener; +import org.opensearch.plugin.resource_limit_group.CreateResourceLimitGroupResponse; +import org.opensearch.plugin.resource_limit_group.DeleteResourceLimitGroupResponse; +import org.opensearch.plugin.resource_limit_group.GetResourceLimitGroupResponse; +import org.opensearch.plugin.resource_limit_group.UpdateResourceLimitGroupResponse; + +/** + * This interface defines the key APIs for implementing resource limit group persistence + */ +public interface Persistable { + + // void persist(ResourceLimitGroup resourceLimitGroup, ActionListener listener); + + /** + * persists the resource limit group in a durable storage + * @param resourceLimitGroup + * @param listener + */ + void persist(T resourceLimitGroup, ActionListener listener); + + /** + * update the resource limit group in a durable storage + * @param resourceLimitGroup + * @param existingName + * @param listener + */ + void update(T resourceLimitGroup, String existingName, ActionListener listener); + + /** + * fetch the resource limit group in a durable storage + * @param name + * @param listener + */ + void get(String name, ActionListener listener); + + /** + * delete the resource limit group in a durable storage + * @param name + * @param listener + */ + void delete(String name, ActionListener listener); +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceService.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceService.java new file mode 100644 index 0000000000000..5223443544cdb --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceService.java @@ -0,0 +1,420 @@ +/* + * 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.resource_limit_group.service; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.cluster.ClusterState; +import org.opensearch.cluster.ClusterStateUpdateTask; +import org.opensearch.cluster.metadata.Metadata; +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; +import org.opensearch.cluster.service.ClusterManagerTaskThrottler.ThrottlingKey; +import org.opensearch.cluster.service.ClusterService; +import org.opensearch.common.Priority; +import org.opensearch.common.inject.Inject; +import org.opensearch.common.settings.ClusterSettings; +import org.opensearch.common.settings.Settings; +import org.opensearch.core.action.ActionListener; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.plugin.resource_limit_group.*; + +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.DoubleAdder; +import java.util.stream.Collectors; + +import static org.opensearch.search.resource_limit_group.ResourceLimitGroupServiceSettings.MAX_RESOURCE_LIMIT_GROUP_COUNT; +import static org.opensearch.search.resource_limit_group.ResourceLimitGroupServiceSettings.RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME; + +/** + * This class defines the functions for Resource Limit Group persistence + */ +public class ResourceLimitGroupPersistenceService implements Persistable { + private static final Logger logger = LogManager.getLogger(ResourceLimitGroupPersistenceService.class); + private final ClusterService clusterService; + private static final String SOURCE = "resource-limit-group-persistence-service"; + private static final String CREATE_RESOURCE_LIMIT_GROUP_THROTTLING_KEY = "create-resource-limit-group"; + private static final String UPDATE_RESOURCE_LIMIT_GROUP_THROTTLING_KEY = "update-resource-limit-group"; + private static final String DELETE_RESOURCE_LIMIT_GROUP_THROTTLING_KEY = "delete-resource-limit-group"; + private static AtomicInteger inflightCreateResourceLimitGroupRequestCount; + Map inflightResourceLimitValues; + private volatile int maxResourceLimitGroupCount; + final ThrottlingKey createResourceLimitGroupThrottlingKey; + final ThrottlingKey updateResourceLimitGroupThrottlingKey; + final ThrottlingKey deleteResourceLimitGroupThrottlingKey; + + /** + * Constructor for Resource Limit GroupPersistenceService + * + * @param clusterService {@link ClusterService} - The cluster service to be used by ResourceLimitGroupPersistenceService + * @param settings {@link Settings} - The settings to be used by ResourceLimitGroupPersistenceService + * @param clusterSettings {@link ClusterSettings} - The cluster settings to be used by ResourceLimitGroupPersistenceService + */ + @Inject + public ResourceLimitGroupPersistenceService(final ClusterService clusterService, final Settings settings, final ClusterSettings clusterSettings) { + this.clusterService = clusterService; + this.createResourceLimitGroupThrottlingKey = clusterService.registerClusterManagerTask(CREATE_RESOURCE_LIMIT_GROUP_THROTTLING_KEY, true); + this.deleteResourceLimitGroupThrottlingKey = clusterService.registerClusterManagerTask(DELETE_RESOURCE_LIMIT_GROUP_THROTTLING_KEY, true); + this.updateResourceLimitGroupThrottlingKey = clusterService.registerClusterManagerTask(UPDATE_RESOURCE_LIMIT_GROUP_THROTTLING_KEY, true); + maxResourceLimitGroupCount = MAX_RESOURCE_LIMIT_GROUP_COUNT.get(settings); + clusterSettings.addSettingsUpdateConsumer(MAX_RESOURCE_LIMIT_GROUP_COUNT, this::setMaxResourceLimitGroupCount); + inflightCreateResourceLimitGroupRequestCount = new AtomicInteger(); + inflightResourceLimitValues = new HashMap<>(); + } + + /** + * Set maxResourceLimitGroupCount to be newMaxResourceLimitGroupCount + * + * @param newMaxResourceLimitGroupCount - the max number of resource limit group allowed + */ + public void setMaxResourceLimitGroupCount(int newMaxResourceLimitGroupCount) { + if (newMaxResourceLimitGroupCount < 0) { + throw new IllegalArgumentException("node.resource_limit_group.max_count can't be negative"); + } + this.maxResourceLimitGroupCount = newMaxResourceLimitGroupCount; + } + + @Override + public void persist(ResourceLimitGroup resourceLimitGroup, ActionListener listener) { + persistInClusterStateMetadata(resourceLimitGroup, listener); + } + + @Override + public void update(ResourceLimitGroup resourceLimitGroup, String existingName, ActionListener listener) { + ClusterState currentState = clusterService.state(); + ResourceLimitGroup existingGroup; + Map currentGroupsMap = currentState.metadata().resourceLimitGroups(); + + if (currentGroupsMap.containsKey(existingName)) { + existingGroup = currentGroupsMap.get(existingName); + } else { + logger.warn("No Resource Limit Group exists with the provided name: {}", existingName); + Exception e = new RuntimeException("No Resource Limit Group exists with the provided name: " + existingName); + UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(); + response.setRestStatus(RestStatus.NOT_FOUND); + listener.onFailure(e); + return; + } + + + if (resourceLimitGroup.getName() != null && currentGroupsMap.containsKey(resourceLimitGroup.getName())) { + logger.warn("Resource Limit Group already exists with the updated name: {}", resourceLimitGroup.getName()); + Exception e = new RuntimeException("Resource Limit Group already exists with the provided name: " + resourceLimitGroup.getName()); + UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(); + response.setRestStatus(RestStatus.CONFLICT); + listener.onFailure(e); + return; + } + + if (resourceLimitGroup.getResourceLimits() != null) { + String resourceNameWithThresholdExceeded = ""; + for (ResourceLimit rl: resourceLimitGroup.getResourceLimits()) { + String currResourceName = rl.getResourceName(); + double existingUsage = 0; + for (ResourceLimitGroup group: new ArrayList<>(currentGroupsMap.values())) { + if (!group.getName().equals(existingName)) { + existingUsage += getResourceLimitValue(currResourceName, group); + } + } + double newGroupUsage = getResourceLimitValue(currResourceName, resourceLimitGroup); + if (!inflightResourceLimitValues.containsKey(currResourceName)) { + inflightResourceLimitValues.put(currResourceName, new DoubleAdder()); + } + inflightResourceLimitValues.get(currResourceName).add(newGroupUsage); + double totalUsage = existingUsage + inflightResourceLimitValues.get(currResourceName).doubleValue(); + if (totalUsage > 1) { + resourceNameWithThresholdExceeded = currResourceName; + } + } + if (!resourceNameWithThresholdExceeded.isEmpty()) { + for (ResourceLimit rl: resourceLimitGroup.getResourceLimits()) { + String currResourceName = rl.getResourceName(); + inflightResourceLimitValues.get(currResourceName).add(-getResourceLimitValue(currResourceName, resourceLimitGroup)); + } + Exception e = new RuntimeException("Total resource allocation for " + resourceNameWithThresholdExceeded + " will go above the max limit of 1.0"); + UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(); + response.setRestStatus(RestStatus.CONFLICT); + listener.onFailure(e); + return; + } + } + + // build the resource limit group with updated fields + String name = resourceLimitGroup.getName() == null ? existingGroup.getName() : resourceLimitGroup.getName(); + List resourceLimit; + if (resourceLimitGroup.getResourceLimits() == null || resourceLimitGroup.getResourceLimits().isEmpty()) { + resourceLimit = existingGroup.getResourceLimits(); + } else { + resourceLimit = new ArrayList<>(existingGroup.getResourceLimits()); + Map resourceLimitMap = resourceLimitGroup.getResourceLimits().stream() + .collect(Collectors.toMap(ResourceLimit::getResourceName, ResourceLimit::getValue)); + for (ResourceLimit rl: resourceLimit) { + String currResourceName = rl.getResourceName(); + if (resourceLimitMap.containsKey(currResourceName)) { + rl.setValue(resourceLimitMap.get(currResourceName)); + } + } + } + String enforcement = resourceLimitGroup.getEnforcement() == null ? existingGroup.getEnforcement() : resourceLimitGroup.getEnforcement(); + + ResourceLimitGroup updatedGroup = new ResourceLimitGroup(name, resourceLimit, enforcement); + updateInClusterStateMetadata(existingGroup, resourceLimitGroup, updatedGroup, listener); + } + + @Override + public void get(String name, ActionListener listener) { + ClusterState currentState = clusterService.state(); + List resourceLimitGroups; + Map currentGroupsMap = currentState.metadata().resourceLimitGroups(); + if (name == null || name.equals("")) { + resourceLimitGroups = new ArrayList<>(currentGroupsMap.values()); + } else if (currentGroupsMap.containsKey(name)) { + resourceLimitGroups = List.of(currentGroupsMap.get(name)); + } else { + logger.warn("No Resource Limit Group exists with the provided name: {}", name); + Exception e = new RuntimeException("No Resource Limit Group exists with the provided name: " + name); + GetResourceLimitGroupResponse response = new GetResourceLimitGroupResponse(); + response.setRestStatus(RestStatus.NOT_FOUND); + listener.onFailure(e); + return; + } + GetResourceLimitGroupResponse response = new GetResourceLimitGroupResponse(resourceLimitGroups); + response.setRestStatus(RestStatus.OK); + listener.onResponse(response); + } + + @Override + public void delete(String name, ActionListener listener) { + deleteInClusterStateMetadata(name, listener); + } + + /** + * Update cluster state to include the new Resource Limit Group + * @param resourceLimitGroup {@link ResourceLimitGroup} - the resource limit group we're currently creating + */ + void persistInClusterStateMetadata(ResourceLimitGroup resourceLimitGroup, ActionListener listener) { + clusterService.submitStateUpdateTask(SOURCE, new ClusterStateUpdateTask(Priority.URGENT) { + @Override + public ClusterState execute(ClusterState currentState) throws Exception { + return saveResourceLimitGroupInClusterState(resourceLimitGroup, currentState); + } + + @Override + public ThrottlingKey getClusterManagerThrottlingKey() { + return createResourceLimitGroupThrottlingKey; + } + + @Override + public void onFailure(String source, Exception e) { + inflightCreateResourceLimitGroupRequestCount.decrementAndGet(); + for (ResourceLimit rl: resourceLimitGroup.getResourceLimits()) { + String currResourceName = rl.getResourceName(); + inflightResourceLimitValues.get(currResourceName).add(-getResourceLimitValue(currResourceName, resourceLimitGroup)); + } + logger.warn("failed to save Resource Limit Group object due to error: {}, for source: {}", e.getMessage(), source); + CreateResourceLimitGroupResponse response = new CreateResourceLimitGroupResponse(); + response.setRestStatus(RestStatus.FAILED_DEPENDENCY); + listener.onFailure(e); + } + + @Override + public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { + inflightCreateResourceLimitGroupRequestCount.decrementAndGet(); + for (ResourceLimit rl: resourceLimitGroup.getResourceLimits()) { + String currResourceName = rl.getResourceName(); + inflightResourceLimitValues.get(currResourceName).add(-getResourceLimitValue(currResourceName, resourceLimitGroup)); + } + CreateResourceLimitGroupResponse response = new CreateResourceLimitGroupResponse(resourceLimitGroup); + response.setRestStatus(RestStatus.OK); + listener.onResponse(response); + } + }); + } + + /** + * Get the JVM allocation value for the Resource Limit Group + * @param resourceLimitGroup {@link ResourceLimitGroup} - the resource limit group from which to get the JVM allocation value + */ + private double getResourceLimitValue(String resourceName, final ResourceLimitGroup resourceLimitGroup) { + double value = 0.0; + List resourceLimits = resourceLimitGroup.getResourceLimits(); + for (ResourceLimit resourceLimit : resourceLimits) { + if (resourceLimit.getResourceName().equals(resourceName)) { + value = resourceLimit.getValue(); + break; + } + } + return value; + } + + /** + * This method will be executed before we submit the new cluster state + * @param resourceLimitGroup - the resource limit group we're currently creating + * @param currentClusterState - the cluster state before the update + */ + ClusterState saveResourceLimitGroupInClusterState(final ResourceLimitGroup resourceLimitGroup, final ClusterState currentClusterState) { + final Metadata metadata = currentClusterState.metadata(); + String groupName = resourceLimitGroup.getName(); + if (metadata.resourceLimitGroups().containsKey(groupName)) { + logger.warn("Resource Limit Group with name {} already exists. Not creating a new one.", groupName); + throw new RuntimeException("Resource Limit Group with name " + groupName + " already exists. Not creating a new one."); + } + final List previousGroups = new ArrayList<>(metadata.resourceLimitGroups().values()); + + String resourceNameWithThresholdExceeded = ""; + for (ResourceLimit rl: resourceLimitGroup.getResourceLimits()) { + String currResourceName = rl.getResourceName(); + double existingUsage = 0; + for (ResourceLimitGroup existingGroup: previousGroups) { + existingUsage += getResourceLimitValue(currResourceName, existingGroup); + } + double newGroupUsage = getResourceLimitValue(currResourceName, resourceLimitGroup); + if (!inflightResourceLimitValues.containsKey(currResourceName)) { + inflightResourceLimitValues.put(currResourceName, new DoubleAdder()); + } + inflightResourceLimitValues.get(currResourceName).add(newGroupUsage); + double totalUsage = existingUsage + inflightResourceLimitValues.get(currResourceName).doubleValue(); + if (totalUsage > 1) { + resourceNameWithThresholdExceeded = currResourceName; + } + } + if (inflightCreateResourceLimitGroupRequestCount.incrementAndGet() + previousGroups.size() > maxResourceLimitGroupCount) { + logger.error("{} value exceeded its assigned limit of {}", RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME, maxResourceLimitGroupCount); + throw new RuntimeException("Can't create more than " + maxResourceLimitGroupCount + " Resource Limit Groups in the system"); + } + if (!resourceNameWithThresholdExceeded.isEmpty()) { + logger.error("Total resource allocation for {} will go above the max limit of 1.0", resourceNameWithThresholdExceeded); + throw new RuntimeException("Total resource allocation for " + resourceNameWithThresholdExceeded+ " will go above the max limit of 1.0"); + } + + return ClusterState.builder(currentClusterState).metadata(Metadata.builder(metadata).put(resourceLimitGroup).build()).build(); + } + + /** + * Modify cluster state to update the Resource Limit Group + * @param existingGroup {@link ResourceLimitGroup} - the existing resource limit group that we want to update + * @param updatedGroup {@link ResourceLimitGroup} - the resource limit group we're updating to + */ + void updateInClusterStateMetadata(ResourceLimitGroup existingGroup, ResourceLimitGroup toUpdateGroup, ResourceLimitGroup updatedGroup, ActionListener listener) { + clusterService.submitStateUpdateTask(SOURCE, new ClusterStateUpdateTask(Priority.URGENT) { + @Override + public ClusterState execute(ClusterState currentState) { + return updateResourceLimitGroupInClusterState(existingGroup, updatedGroup, currentState); + } + + @Override + public ThrottlingKey getClusterManagerThrottlingKey() { + return updateResourceLimitGroupThrottlingKey; + } + + @Override + public void onFailure(String source, Exception e) { + logger.warn("Failed to update Resource Limit Group due to error: {}, for source: {}", e.getMessage(), source); + UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(); + response.setRestStatus(RestStatus.FAILED_DEPENDENCY); + listener.onFailure(e); + } + + @Override + public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { + if (toUpdateGroup.getResourceLimits() != null) { + for (ResourceLimit rl: toUpdateGroup.getResourceLimits()) { + String currResourceName = rl.getResourceName(); + inflightResourceLimitValues.get(currResourceName).add(-getResourceLimitValue(currResourceName, toUpdateGroup)); + } + } + UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(updatedGroup); + response.setRestStatus(RestStatus.OK); + listener.onResponse(response); + } + }); + } + + /** + * Modify cluster state to update the existing Resource Limit Group + * @param existingGroup {@link ResourceLimitGroup} - the existing resource limit group that we want to update + * @param updatedGroup {@link ResourceLimitGroup} - the resource limit group we're updating to + * @param currentState - current cluster state + */ + public ClusterState updateResourceLimitGroupInClusterState(ResourceLimitGroup existingGroup, ResourceLimitGroup updatedGroup, ClusterState currentState) { + final Metadata metadata = currentState.metadata(); + return ClusterState + .builder(currentState) + .metadata(Metadata + .builder(metadata) + .removeResourceLimitGroup(existingGroup.getName()) + .put(updatedGroup).build() + ) + .build(); + } + + /** + * Modify cluster state to delete the Resource Limit Group + * @param name - the name for resource limit group to be deleted + */ + void deleteInClusterStateMetadata(String name, ActionListener listener) { + clusterService.submitStateUpdateTask(SOURCE, new ClusterStateUpdateTask(Priority.URGENT) { + @Override + public ClusterState execute(ClusterState currentState) throws Exception { + return deleteResourceLimitGroupInClusterState(name, currentState); + } + + @Override + public ThrottlingKey getClusterManagerThrottlingKey() { + return deleteResourceLimitGroupThrottlingKey; + } + + @Override + public void onFailure(String source, Exception e) { + logger.warn("Failed to delete Resource Limit Group due to error: {}, for source: {}", e.getMessage(), source); + DeleteResourceLimitGroupResponse response = new DeleteResourceLimitGroupResponse(); + response.setRestStatus(RestStatus.NOT_FOUND); + listener.onFailure(e); + } + + @Override + public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { + final Map oldGroupsMap = oldState.metadata().resourceLimitGroups(); + final Map newGroupssMap = newState.metadata().resourceLimitGroups(); + List deletedGroups = new ArrayList<>(); + for (String name: oldGroupsMap.keySet()) { + if (!newGroupssMap.containsKey(name)) { + deletedGroups.add(oldGroupsMap.get(name)); + } + } + DeleteResourceLimitGroupResponse response = new DeleteResourceLimitGroupResponse(deletedGroups); + response.setRestStatus(RestStatus.OK); + listener.onResponse(response); + } + }); + } + + /** + * Modify cluster state to delete the Resource Limit Group + * @param name - the name for resource limit group to be deleted + * @param currentClusterState - current cluster state + */ + ClusterState deleteResourceLimitGroupInClusterState(final String name, final ClusterState currentClusterState) { + final Metadata metadata = currentClusterState.metadata(); + final Map previousGroups = metadata.resourceLimitGroups(); + Map resultGroups = new HashMap<>(previousGroups);; + if (name == null || name.equals("")) { + resultGroups = new HashMap<>(); + } else { + boolean nameExists = previousGroups.containsKey(name); + if (!nameExists) { + logger.error("The Resource Limit Group with provided name {} doesn't exist", name); + throw new RuntimeException("No Resource Limit Group exists with the provided name: " + name); + } + resultGroups.remove(name); + } + return ClusterState.builder(currentClusterState).metadata(Metadata.builder(metadata).resourceLimitGroups(resultGroups).build()).build(); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/package-info.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/package-info.java new file mode 100644 index 0000000000000..5e907f6ecbeec --- /dev/null +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/package-info.java @@ -0,0 +1,16 @@ +/* + * 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 for the rest classes for resource limit group CRUD operations + */ + +/** + * Package for the service classes for resource limit group CRUD operations + */ +package org.opensearch.plugin.resource_limit_group.service; diff --git a/server/src/main/java/org/opensearch/cluster/ClusterModule.java b/server/src/main/java/org/opensearch/cluster/ClusterModule.java index b846d382db89d..5ff312461500e 100644 --- a/server/src/main/java/org/opensearch/cluster/ClusterModule.java +++ b/server/src/main/java/org/opensearch/cluster/ClusterModule.java @@ -49,6 +49,7 @@ import org.opensearch.cluster.metadata.MetadataMappingService; import org.opensearch.cluster.metadata.MetadataUpdateSettingsService; import org.opensearch.cluster.metadata.RepositoriesMetadata; +import org.opensearch.cluster.metadata.ResourceLimitGroupMetadata; import org.opensearch.cluster.metadata.ViewMetadata; import org.opensearch.cluster.metadata.WeightedRoutingMetadata; import org.opensearch.cluster.routing.DelayedAllocationService; @@ -206,6 +207,12 @@ public static List getNamedWriteables() { DecommissionAttributeMetadata::new, DecommissionAttributeMetadata::readDiffFrom ); + registerMetadataCustom( + entries, + ResourceLimitGroupMetadata.TYPE, + ResourceLimitGroupMetadata::new, + ResourceLimitGroupMetadata::readDiffFrom + ); // Task Status (not Diffable) entries.add(new Entry(Task.Status.class, PersistentTasksNodeService.Status.NAME, PersistentTasksNodeService.Status::new)); return entries; diff --git a/server/src/main/java/org/opensearch/cluster/metadata/Metadata.java b/server/src/main/java/org/opensearch/cluster/metadata/Metadata.java index f6bb5f4c4a814..3ab132ddfb067 100644 --- a/server/src/main/java/org/opensearch/cluster/metadata/Metadata.java +++ b/server/src/main/java/org/opensearch/cluster/metadata/Metadata.java @@ -841,7 +841,6 @@ public Map resourceLimitGroups() { (ResourceLimitGroupMetadata) this.custom(ResourceLimitGroupMetadata.TYPE)). map(ResourceLimitGroupMetadata::resourceLimitGroups) .orElse(Collections.emptyMap()); - } public DecommissionAttributeMetadata decommissionAttributeMetadata() { diff --git a/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java b/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java index 84bdfccd570d7..e823b4802de5e 100644 --- a/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java +++ b/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.util.List; +import java.util.Locale; import java.util.Objects; /** @@ -33,7 +34,8 @@ * "resourceName": "jvm", * "value": 0.4 * } - * ] + * ], + * "enforcement": "monitor" * } */ @ExperimentalApi @@ -41,31 +43,73 @@ public class ResourceLimitGroup extends AbstractDiffable imp private final String name; private final List resourceLimits; + private final String enforcement; private static final List ALLOWED_RESOURCES = List.of("jvm"); + private static final List ALLOWED_ENFORCEMENTS = List.of("monitor"); public static final ParseField NAME_FIELD = new ParseField("name"); public static final ParseField RESOURCE_LIMITS_FIELD = new ParseField("resourceLimits"); + public static final ParseField ENFORCEMENT_FIELD = new ParseField("enforcement"); @SuppressWarnings("unchecked") private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( "ResourceLimitGroupParser", - args -> new ResourceLimitGroup((String) args[0], (List) args[1]) + args -> new ResourceLimitGroup((String) args[0], (List) args[1], (String) args[2]) ); static { PARSER.declareString(ConstructingObjectParser.constructorArg(), NAME_FIELD); PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), (p, c) -> ResourceLimit.fromXContent(p), RESOURCE_LIMITS_FIELD); + PARSER.declareString(ConstructingObjectParser.constructorArg(), ENFORCEMENT_FIELD); } - public ResourceLimitGroup(String name, List resourceLimits) { + private static final ConstructingObjectParser PARSER_OPTIONAL_FIELDS = new ConstructingObjectParser<>( + "ResourceLimitGroupParser", + args -> new ResourceLimitGroup((String) args[0], (List) args[1], (String) args[2]) + ); + + static { + PARSER_OPTIONAL_FIELDS.declareString(ConstructingObjectParser.optionalConstructorArg(), NAME_FIELD); + PARSER_OPTIONAL_FIELDS.declareObjectArray(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> ResourceLimit.fromXContent(p), RESOURCE_LIMITS_FIELD); + PARSER_OPTIONAL_FIELDS.declareString(ConstructingObjectParser.optionalConstructorArg(), ENFORCEMENT_FIELD); + } + + public ResourceLimitGroup(String name, List resourceLimits, String enforcement) { + isValidResourceLimitGroup(name, enforcement); this.name = name; this.resourceLimits = resourceLimits; + this.enforcement = enforcement; } public ResourceLimitGroup(StreamInput in) throws IOException { - this(in.readString(), in.readList(ResourceLimit::new)); + this(in.readString(), in.readList(ResourceLimit::new), in.readString()); + } + + private void isValidResourceLimitGroup(String name, String enforcement) { + if (name != null) { + if (name.isEmpty()) { + throw new IllegalArgumentException("Resource Limit Group name cannot be empty"); + } + if (name.startsWith("-") || name.startsWith("_")) { + throw new IllegalArgumentException("Resource Limit Group name cannot start with '_' or '-'."); + } + if (!name.toLowerCase(Locale.ROOT).equals(name)) { + throw new IllegalArgumentException("Resource Limit Group name must be lowercase"); + } + if (name.matches(".*[ ,:\"*+/\\\\|?#><].*")) { + throw new IllegalArgumentException( + "Resource Limit Group names can't contain spaces, commas, quotes, slashes, :, *, +, |, ?, #, >, or <" + ); + } + } + if (enforcement != null) { + if (!ALLOWED_ENFORCEMENTS.contains(enforcement)) { + throw new IllegalArgumentException("enforcement has to be valid, valid enforcements " + + ALLOWED_ENFORCEMENTS.stream().reduce((x, e) -> x + ", " + e).get()); + } + } } /** @@ -76,7 +120,7 @@ public ResourceLimitGroup(StreamInput in) throws IOException { @ExperimentalApi public static class ResourceLimit implements Writeable, ToXContentObject { private final String resourceName; - private final Double value; + private Double value; static final ParseField RESOURCE_NAME_FIELD = new ParseField("resourceName"); static final ParseField RESOURCE_VALUE_FIELD = new ParseField("value"); @@ -94,15 +138,7 @@ public static class ResourceLimit implements Writeable, ToXContentObject { public ResourceLimit(String resourceName, Double value) { Objects.requireNonNull(resourceName, "resourceName can't be null"); Objects.requireNonNull(value, "resource value can't be null"); - - if (Double.compare(value, 1.0) > 0) { - throw new IllegalArgumentException("resource value should be less than 1.0"); - } - - if (!ALLOWED_RESOURCES.contains(resourceName.toLowerCase())) { - throw new IllegalArgumentException("resource has to be valid, valid resources " - + ALLOWED_RESOURCES.stream().reduce((x, e) -> x + ", " + e).get()); - } + isValidResourceLimit(resourceName, value); this.resourceName = resourceName; this.value = value; } @@ -111,6 +147,20 @@ public ResourceLimit(StreamInput in) throws IOException { this(in.readString(), in.readDouble()); } + private static void isValidResourceLimit(String resourceName, double value) { + if (value < 0 || value > 1) { + throw new IllegalArgumentException("Resource limit value should be between 0 and 1."); + } + String str = String.valueOf(value); + if (str.contains(".") && str.split("\\.")[1].length() > 2) { + throw new IllegalArgumentException("Resource limit value should have at most two digits after the decimal point"); + } + if (!ALLOWED_RESOURCES.contains(resourceName.toLowerCase())) { + throw new IllegalArgumentException("resource has to be valid, valid resources " + + ALLOWED_RESOURCES.stream().reduce((x, e) -> x + ", " + e).get()); + } + } + /** * Write this into the {@linkplain StreamOutput}. * @@ -141,6 +191,18 @@ public static ResourceLimit fromXContent(final XContentParser parser) throws IOE return PARSER.parse(parser, null); } + public String getResourceName() { + return resourceName; + } + + public Double getValue() { + return value; + } + + public void setValue(Double value) { + this.value = value; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -155,7 +217,6 @@ public int hashCode() { } } - /** * Write this into the {@linkplain StreamOutput}. * @@ -163,8 +224,13 @@ public int hashCode() { */ @Override public void writeTo(StreamOutput out) throws IOException { + writeToOutputStream(out, name, resourceLimits, enforcement); + } + + public static void writeToOutputStream(StreamOutput out, String name, List resourceLimits, String enforcement) throws IOException { out.writeString(name); out.writeList(resourceLimits); + out.writeString(enforcement); } /** @@ -176,17 +242,20 @@ public void writeTo(StreamOutput out) throws IOException { @Override public XContentBuilder toXContent(final XContentBuilder builder, final Params params) throws IOException { builder.startObject(); - builder.field(NAME_FIELD.getPreferredName(),name); + builder.field(NAME_FIELD.getPreferredName(), name); builder.field(RESOURCE_LIMITS_FIELD.getPreferredName(), resourceLimits); + builder.field(ENFORCEMENT_FIELD.getPreferredName(), enforcement); builder.endObject(); return builder; } - public static ResourceLimitGroup fromXContent(final XContentParser parser) throws IOException { return PARSER.parse(parser, null); } + public static ResourceLimitGroup fromXContentOptionalFields(final XContentParser parser) throws IOException { + return PARSER_OPTIONAL_FIELDS.parse(parser, null); + } public static Diff readDiff(final StreamInput in) throws IOException { return readDiffFrom(ResourceLimitGroup::new, in); @@ -197,15 +266,23 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ResourceLimitGroup that = (ResourceLimitGroup) o; - return Objects.equals(name, that.name) && Objects.equals(resourceLimits, that.resourceLimits); + return Objects.equals(name, that.name) && Objects.equals(resourceLimits, that.resourceLimits) && Objects.equals(enforcement, that.enforcement); } @Override public int hashCode() { - return Objects.hash(name, resourceLimits); + return Objects.hash(name, resourceLimits, enforcement); } public String getName() { return name; } + + public List getResourceLimits() { + return resourceLimits; + } + + public String getEnforcement() { + return enforcement; + } } diff --git a/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroupMetadata.java b/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroupMetadata.java index 144b4c9e06227..4bf639f15e5ab 100644 --- a/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroupMetadata.java +++ b/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroupMetadata.java @@ -15,6 +15,7 @@ import org.opensearch.common.annotation.ExperimentalApi; import org.opensearch.core.ParseField; import org.opensearch.core.common.Strings; +import org.opensearch.core.common.io.stream.NamedWriteable; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.core.common.io.stream.StreamOutput; import org.opensearch.core.xcontent.ConstructingObjectParser; @@ -30,6 +31,11 @@ import static org.opensearch.cluster.metadata.Metadata.ALL_CONTEXTS; +/** + * {@link ResourceLimitGroupMetadata} is a custom {@link Metadata} implementation for Resource Limit Group + * + * @opensearch.internal + */ @ExperimentalApi public class ResourceLimitGroupMetadata implements Metadata.Custom { public static final String TYPE = "resourceLimitGroup"; @@ -58,6 +64,10 @@ public ResourceLimitGroupMetadata(Map resourceLimitG this.resourceLimitGroups = resourceLimitGroups; } + public ResourceLimitGroupMetadata(StreamInput in) throws IOException { + this.resourceLimitGroups = in.readMap(StreamInput::readString, ResourceLimitGroup::new); + } + public Map resourceLimitGroups() { return this.resourceLimitGroups; @@ -119,6 +129,10 @@ public Diff diff(final Metadata.Custom previousState) { return new ResourceLimitGroupMetadataDiff((ResourceLimitGroupMetadata) previousState, this); } + public static NamedDiff readDiffFrom(StreamInput in) throws IOException { + return new ResourceLimitGroupMetadataDiff(in); + } + /** * @return */ diff --git a/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java b/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java index d70b793b71741..2b46c5358eb10 100644 --- a/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java +++ b/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java @@ -154,7 +154,7 @@ import org.opensearch.search.backpressure.settings.SearchShardTaskSettings; import org.opensearch.search.backpressure.settings.SearchTaskSettings; import org.opensearch.search.fetch.subphase.highlight.FastVectorHighlighter; -import org.opensearch.search.sandbox.ResourceLimitGroupServiceSettings; +import org.opensearch.search.resource_limit_group.ResourceLimitGroupServiceSettings; import org.opensearch.snapshots.InternalSnapshotsInfoService; import org.opensearch.snapshots.SnapshotsService; import org.opensearch.tasks.TaskCancellationMonitoringSettings; @@ -316,6 +316,7 @@ public void apply(Settings value, Settings current, Settings previous) { DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_INCLUDE_RELOCATIONS_SETTING, DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_REROUTE_INTERVAL_SETTING, SameShardAllocationDecider.CLUSTER_ROUTING_ALLOCATION_SAME_HOST_SETTING, + ResourceLimitGroupServiceSettings.MAX_RESOURCE_LIMIT_GROUP_COUNT, ShardStateAction.FOLLOW_UP_REROUTE_PRIORITY_SETTING, InternalClusterInfoService.INTERNAL_CLUSTER_INFO_UPDATE_INTERVAL_SETTING, InternalClusterInfoService.INTERNAL_CLUSTER_INFO_TIMEOUT_SETTING, @@ -732,7 +733,7 @@ public void apply(Settings value, Settings current, Settings previous) { RemoteStoreSettings.CLUSTER_REMOTE_TRANSLOG_BUFFER_INTERVAL_SETTING, RemoteStoreSettings.CLUSTER_REMOTE_TRANSLOG_TRANSFER_TIMEOUT_SETTING, - // Sandbox settings + // Resource Limit Group settings ResourceLimitGroupServiceSettings.MAX_RESOURCE_LIMIT_GROUP_COUNT, ResourceLimitGroupServiceSettings.NODE_LEVEL_REJECTION_THRESHOLD, ResourceLimitGroupServiceSettings.NODE_LEVEL_CANCELLATION_THRESHOLD diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupService.java b/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupService.java index 02954aa140f06..4fd58d063f4e1 100644 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupService.java +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupService.java @@ -29,7 +29,7 @@ public class ResourceLimitGroupService extends AbstractLifecycleComponent { private final ResourceLimitGroupRequestCanceller requestCanceller; private final ResourceLimitGroupPruner resourceLimitGroupPruner; private volatile Scheduler.Cancellable scheduledFuture; - private final ResourceLimitGroupServiceSettings sandboxServiceSettings; + private final ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings; private final ThreadPool threadPool; /** @@ -37,7 +37,7 @@ public class ResourceLimitGroupService extends AbstractLifecycleComponent { * @param requestTrackerService * @param requestCanceller * @param resourceLimitGroupPruner - * @param sandboxServiceSettings + * @param resourceLimitGroupServiceSettings * @param threadPool */ @Inject @@ -45,13 +45,13 @@ public ResourceLimitGroupService( ResourceLimitGroupResourceUsageTracker requestTrackerService, ResourceLimitGroupRequestCanceller requestCanceller, ResourceLimitGroupPruner resourceLimitGroupPruner, - ResourceLimitGroupServiceSettings sandboxServiceSettings, + ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings, ThreadPool threadPool ) { this.requestTracker = requestTrackerService; this.requestCanceller = requestCanceller; this.resourceLimitGroupPruner = resourceLimitGroupPruner; - this.sandboxServiceSettings = sandboxServiceSettings; + this.resourceLimitGroupServiceSettings = resourceLimitGroupServiceSettings; this.threadPool = threadPool; } @@ -73,9 +73,9 @@ protected void doStart() { try { doRun(); } catch (Exception e) { - logger.debug("Exception occurred in Query Sandbox service", e); + logger.debug("Exception occurred in Resource Limit Group service", e); } - }, sandboxServiceSettings.getRunIntervalMillis(), ThreadPool.Names.GENERIC); + }, resourceLimitGroupServiceSettings.getRunIntervalMillis(), ThreadPool.Names.GENERIC); } @Override @@ -87,8 +87,4 @@ protected void doStop() { @Override protected void doClose() throws IOException {} - - // public SandboxStatsHolder stats() { - // return requestTrackerService.getSandboxLevelStats(); - // } } diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/module/ResourceLimitGroupModule.java b/server/src/main/java/org/opensearch/search/resource_limit_group/module/ResourceLimitGroupModule.java index 9700612a71edc..3b7c1bb0fa722 100644 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/module/ResourceLimitGroupModule.java +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/module/ResourceLimitGroupModule.java @@ -8,7 +8,9 @@ package org.opensearch.search.resource_limit_group.module; +import org.opensearch.cluster.metadata.ResourceLimitGroup; import org.opensearch.common.inject.AbstractModule; +import org.opensearch.common.inject.TypeLiteral; import org.opensearch.search.resource_limit_group.ResourceLimitGroupPruner; import org.opensearch.search.resource_limit_group.tracker.ResourceLimitGroupResourceUsageTracker; import org.opensearch.search.resource_limit_group.cancellation.ResourceLimitGroupRequestCanceller; diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitsGroupResourceUsageTrackerService.java b/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitsGroupResourceUsageTrackerService.java index cb2994b85b829..f0034b46a65ea 100644 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitsGroupResourceUsageTrackerService.java +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitsGroupResourceUsageTrackerService.java @@ -28,7 +28,7 @@ */ public class ResourceLimitsGroupResourceUsageTrackerService implements - TaskManager.TaskEventListeners, + TaskManager.TaskEventListeners, ResourceLimitGroupResourceUsageTracker, ResourceLimitGroupRequestCanceller, ResourceLimitGroupPruner { @@ -48,7 +48,7 @@ public class ResourceLimitsGroupResourceUsageTrackerService private final TaskResourceTrackingService taskResourceTrackingService; /** - * SandboxResourceTrackerService constructor + * ResourceLimitsGroupResourceUsageTrackerService constructor * @param taskManager * @param taskResourceTrackingService */ @@ -68,11 +68,6 @@ public void updateResourceLimitGroupsResourceUsage() { } - // @Override - // public SandboxStatsHolder getStats() { - // return null; - // } - private AbsoluteResourceUsage calculateAbsoluteResourceUsageFor(Task task) { TaskResourceUsage taskResourceUsage = task.getTotalResourceStats(); long cpuTimeInNanos = taskResourceUsage.getCpuTimeInNanos(); @@ -113,7 +108,7 @@ public double getAbsoluteJvmAllocationsUsageInPercent() { } /** - * filter out the deleted sandboxes which still has unfi + * filter out the deleted Resource Limit Groups which still has unfinished tasks */ public void pruneResourceLimitGroup() { toDeleteResourceLimitGroups = toDeleteResourceLimitGroups.stream().filter(this::hasUnfinishedTasks).collect(Collectors.toList()); @@ -131,12 +126,12 @@ private boolean hasUnfinishedTasks(String sandboxId) { public void onTaskCompleted(Task task) {} /** - * This method will select the sandboxes violating the enforced constraints - * and cancel the tasks from the violating sandboxes + * This method will select the Resource Limit Groups violating the enforced constraints + * and cancel the tasks from the violating Resource Limit Groups * Cancellation happens in two scenarios *
    - *
  1. If the sandbox is of enforced type and it is breaching its cancellation limit for the threshold
  2. - *
  3. Node is in duress and sandboxes which are breaching the cancellation thresholds will have cancellations
  4. + *
  5. If the Resource Limit Group is of enforced type and it is breaching its cancellation limit for the threshold
  6. + *
  7. Node is in duress and Resource Limit Groups which are breaching the cancellation thresholds will have cancellations
  8. *
*/ @Override @@ -152,17 +147,12 @@ public void cancelViolatingTasks() { * @return list of cancellable tasks */ private List getCancellableTasks() { - // get cancellations from enforced type sandboxes + // get cancellations from enforced type Resource Limit Groups List inViolationSandboxes = getBreachingSandboxIds(); List cancellableTasks = new ArrayList<>(); for (String sandboxId : inViolationSandboxes) { cancellableTasks.addAll(getCancellableTasksFrom(sandboxId)); } - - // get cancellations from soft type sandboxes if the node is in duress (hitting node level cancellation - // threshold) - - return cancellableTasks; } From ea727b9948e884cc27771f92419379bead6f26a5 Mon Sep 17 00:00:00 2001 From: Ruirui Zhang Date: Fri, 19 Apr 2024 15:44:55 -0700 Subject: [PATCH 06/15] unit tests for resource limit group Signed-off-by: Ruirui Zhang --- .../ResourceLimitGroupPlugin.java | 8 + .../RestCreateResourceLimitGroupAction.java | 10 +- .../RestDeleteResourceLimitGroupAction.java | 10 +- .../rest/RestGetResourceLimitGroupAction.java | 10 +- .../RestUpdateResourceLimitGroupAction.java | 10 +- .../ResourceLimitGroupPersistenceService.java | 54 ++++--- .../CreateResourceLimitGroupRequestTests.java | 38 +++++ ...CreateResourceLimitGroupResponseTests.java | 41 +++++ .../DeleteResourceLimitGroupRequestTests.java | 40 +++++ ...DeleteResourceLimitGroupResponseTests.java | 74 +++++++++ .../GetResourceLimitGroupRequestTests.java | 40 +++++ .../GetResourceLimitGroupResponseTests.java | 77 +++++++++ .../ResourceLimitGroupTestUtils.java | 91 +++++++++++ .../UpdateResourceLimitGroupRequestTests.java | 66 ++++++++ ...UpdateResourceLimitGroupResponseTests.java | 41 +++++ ...urceLimitGroupPersistenceServiceTests.java | 147 ++++++++++++++++++ .../action/search/SearchRequest.java | 3 +- .../org/opensearch/cluster/ClusterModule.java | 2 +- .../opensearch/cluster/metadata/Metadata.java | 8 +- .../cluster/metadata/ResourceLimitGroup.java | 33 ++-- .../metadata/ResourceLimitGroupMetadata.java | 30 ++-- .../ResourceLimitGroupService.java | 8 +- .../ResourceLimitGroupServiceSettings.java | 14 +- .../module/ResourceLimitGroupModule.java | 4 +- ...imitsGroupResourceUsageTrackerService.java | 8 +- ...esourceLimitGroupServiceSettingsTests.java | 37 ++--- .../ResourceLimitGroupTests.java | 115 ++++++++++++++ 27 files changed, 917 insertions(+), 102 deletions(-) create mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequestTests.java create mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponseTests.java create mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupRequestTests.java create mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponseTests.java create mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequestTests.java create mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponseTests.java create mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupTestUtils.java create mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequestTests.java create mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponseTests.java create mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceServiceTests.java rename server/src/test/java/org/opensearch/search/{sandbox => resource_limit_group}/ResourceLimitGroupServiceSettingsTests.java (78%) create mode 100644 server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupTests.java diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java index 27a927c93b4be..d2634f8fd3506 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java @@ -1,3 +1,11 @@ +/* + * 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.resource_limit_group; import org.opensearch.action.ActionRequest; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestCreateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestCreateResourceLimitGroupAction.java index fa03a0e36c531..0e8ecc3c1cbe8 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestCreateResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestCreateResourceLimitGroupAction.java @@ -12,8 +12,14 @@ import org.opensearch.core.xcontent.XContentParser; import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.plugin.resource_limit_group.*; -import org.opensearch.rest.*; +import org.opensearch.plugin.resource_limit_group.CreateResourceLimitGroupAction; +import org.opensearch.plugin.resource_limit_group.CreateResourceLimitGroupRequest; +import org.opensearch.plugin.resource_limit_group.CreateResourceLimitGroupResponse; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.BytesRestResponse; +import org.opensearch.rest.RestChannel; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.RestResponse; import org.opensearch.rest.action.RestResponseListener; import java.io.IOException; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestDeleteResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestDeleteResourceLimitGroupAction.java index 51c3ad90a1784..b47225badb9ac 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestDeleteResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestDeleteResourceLimitGroupAction.java @@ -11,8 +11,14 @@ import org.opensearch.client.node.NodeClient; import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.plugin.resource_limit_group.*; -import org.opensearch.rest.*; +import org.opensearch.plugin.resource_limit_group.DeleteResourceLimitGroupAction; +import org.opensearch.plugin.resource_limit_group.DeleteResourceLimitGroupRequest; +import org.opensearch.plugin.resource_limit_group.DeleteResourceLimitGroupResponse; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.BytesRestResponse; +import org.opensearch.rest.RestChannel; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.RestResponse; import org.opensearch.rest.action.RestResponseListener; import java.io.IOException; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestGetResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestGetResourceLimitGroupAction.java index c6cb588084559..ffc57d5b95098 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestGetResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestGetResourceLimitGroupAction.java @@ -11,8 +11,14 @@ import org.opensearch.client.node.NodeClient; import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.plugin.resource_limit_group.*; -import org.opensearch.rest.*; +import org.opensearch.plugin.resource_limit_group.GetResourceLimitGroupAction; +import org.opensearch.plugin.resource_limit_group.GetResourceLimitGroupRequest; +import org.opensearch.plugin.resource_limit_group.GetResourceLimitGroupResponse; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.BytesRestResponse; +import org.opensearch.rest.RestChannel; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.RestResponse; import org.opensearch.rest.action.RestResponseListener; import java.io.IOException; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestUpdateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestUpdateResourceLimitGroupAction.java index b849aab807b3a..948c224e79637 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestUpdateResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestUpdateResourceLimitGroupAction.java @@ -12,8 +12,14 @@ import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; import org.opensearch.core.xcontent.XContentParser; -import org.opensearch.plugin.resource_limit_group.*; -import org.opensearch.rest.*; +import org.opensearch.plugin.resource_limit_group.UpdateResourceLimitGroupAction; +import org.opensearch.plugin.resource_limit_group.UpdateResourceLimitGroupRequest; +import org.opensearch.plugin.resource_limit_group.UpdateResourceLimitGroupResponse; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.BytesRestResponse; +import org.opensearch.rest.RestChannel; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.RestResponse; import org.opensearch.rest.action.RestResponseListener; import java.io.IOException; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceService.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceService.java index 5223443544cdb..2f4432592c8a1 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceService.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceService.java @@ -23,7 +23,10 @@ import org.opensearch.common.settings.Settings; import org.opensearch.core.action.ActionListener; import org.opensearch.core.rest.RestStatus; -import org.opensearch.plugin.resource_limit_group.*; +import org.opensearch.plugin.resource_limit_group.CreateResourceLimitGroupResponse; +import org.opensearch.plugin.resource_limit_group.DeleteResourceLimitGroupResponse; +import org.opensearch.plugin.resource_limit_group.GetResourceLimitGroupResponse; +import org.opensearch.plugin.resource_limit_group.UpdateResourceLimitGroupResponse; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; @@ -103,7 +106,6 @@ public void update(ResourceLimitGroup resourceLimitGroup, String existingName, A return; } - if (resourceLimitGroup.getName() != null && currentGroupsMap.containsKey(resourceLimitGroup.getName())) { logger.warn("Resource Limit Group already exists with the updated name: {}", resourceLimitGroup.getName()); Exception e = new RuntimeException("Resource Limit Group already exists with the provided name: " + resourceLimitGroup.getName()); @@ -171,13 +173,8 @@ public void update(ResourceLimitGroup resourceLimitGroup, String existingName, A @Override public void get(String name, ActionListener listener) { ClusterState currentState = clusterService.state(); - List resourceLimitGroups; - Map currentGroupsMap = currentState.metadata().resourceLimitGroups(); - if (name == null || name.equals("")) { - resourceLimitGroups = new ArrayList<>(currentGroupsMap.values()); - } else if (currentGroupsMap.containsKey(name)) { - resourceLimitGroups = List.of(currentGroupsMap.get(name)); - } else { + List resultGroups = getFromClusterStateMetadata(name, currentState); + if (resultGroups.isEmpty() && name != null && !name.isEmpty()) { logger.warn("No Resource Limit Group exists with the provided name: {}", name); Exception e = new RuntimeException("No Resource Limit Group exists with the provided name: " + name); GetResourceLimitGroupResponse response = new GetResourceLimitGroupResponse(); @@ -185,7 +182,7 @@ public void get(String name, ActionListener liste listener.onFailure(e); return; } - GetResourceLimitGroupResponse response = new GetResourceLimitGroupResponse(resourceLimitGroups); + GetResourceLimitGroupResponse response = new GetResourceLimitGroupResponse(resultGroups); response.setRestStatus(RestStatus.OK); listener.onResponse(response); } @@ -213,11 +210,6 @@ public ThrottlingKey getClusterManagerThrottlingKey() { @Override public void onFailure(String source, Exception e) { - inflightCreateResourceLimitGroupRequestCount.decrementAndGet(); - for (ResourceLimit rl: resourceLimitGroup.getResourceLimits()) { - String currResourceName = rl.getResourceName(); - inflightResourceLimitValues.get(currResourceName).add(-getResourceLimitValue(currResourceName, resourceLimitGroup)); - } logger.warn("failed to save Resource Limit Group object due to error: {}, for source: {}", e.getMessage(), source); CreateResourceLimitGroupResponse response = new CreateResourceLimitGroupResponse(); response.setRestStatus(RestStatus.FAILED_DEPENDENCY); @@ -226,11 +218,6 @@ public void onFailure(String source, Exception e) { @Override public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { - inflightCreateResourceLimitGroupRequestCount.decrementAndGet(); - for (ResourceLimit rl: resourceLimitGroup.getResourceLimits()) { - String currResourceName = rl.getResourceName(); - inflightResourceLimitValues.get(currResourceName).add(-getResourceLimitValue(currResourceName, resourceLimitGroup)); - } CreateResourceLimitGroupResponse response = new CreateResourceLimitGroupResponse(resourceLimitGroup); response.setRestStatus(RestStatus.OK); listener.onResponse(response); @@ -286,17 +273,32 @@ ClusterState saveResourceLimitGroupInClusterState(final ResourceLimitGroup resou } } if (inflightCreateResourceLimitGroupRequestCount.incrementAndGet() + previousGroups.size() > maxResourceLimitGroupCount) { + restoreInflightValues(resourceLimitGroup); logger.error("{} value exceeded its assigned limit of {}", RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME, maxResourceLimitGroupCount); throw new RuntimeException("Can't create more than " + maxResourceLimitGroupCount + " Resource Limit Groups in the system"); } if (!resourceNameWithThresholdExceeded.isEmpty()) { + restoreInflightValues(resourceLimitGroup); logger.error("Total resource allocation for {} will go above the max limit of 1.0", resourceNameWithThresholdExceeded); throw new RuntimeException("Total resource allocation for " + resourceNameWithThresholdExceeded+ " will go above the max limit of 1.0"); } + restoreInflightValues(resourceLimitGroup); return ClusterState.builder(currentClusterState).metadata(Metadata.builder(metadata).put(resourceLimitGroup).build()).build(); } + /** + * This method restores the inflight values to be before the resource limit group is processed + * @param resourceLimitGroup - the resource limit group we're currently creating + */ + void restoreInflightValues(ResourceLimitGroup resourceLimitGroup) { + inflightCreateResourceLimitGroupRequestCount.decrementAndGet(); + for (ResourceLimit rl: resourceLimitGroup.getResourceLimits()) { + String currResourceName = rl.getResourceName(); + inflightResourceLimitValues.get(currResourceName).add(-getResourceLimitValue(currResourceName, resourceLimitGroup)); + } + } + /** * Modify cluster state to update the Resource Limit Group * @param existingGroup {@link ResourceLimitGroup} - the existing resource limit group that we want to update @@ -417,4 +419,16 @@ ClusterState deleteResourceLimitGroupInClusterState(final String name, final Clu } return ClusterState.builder(currentClusterState).metadata(Metadata.builder(metadata).resourceLimitGroups(resultGroups).build()).build(); } + + List getFromClusterStateMetadata(String name, ClusterState currentState) { + Map currentGroupsMap = currentState.getMetadata().resourceLimitGroups(); + List currentGroups = new ArrayList<>(currentGroupsMap.values()); + List resultGroups = new ArrayList<>(); + if (name == null || name.equals("")) { + resultGroups = currentGroups; + } else if (currentGroupsMap.containsKey(name)) { + resultGroups = List.of(currentGroupsMap.get(name)); + } + return resultGroups; + } } diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequestTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequestTests.java new file mode 100644 index 0000000000000..e0626e6fd9834 --- /dev/null +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequestTests.java @@ -0,0 +1,38 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.test.OpenSearchTestCase; + +import java.io.IOException; +import java.util.List; + +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_ONE; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.MONITOR; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimits; + +public class CreateResourceLimitGroupRequestTests extends OpenSearchTestCase { + + public void testSerialization() throws IOException { + ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(NAME_ONE, List.of(new ResourceLimit("jvm", 0.4)), MONITOR); + CreateResourceLimitGroupRequest request = new CreateResourceLimitGroupRequest(resourceLimitGroup); + BytesStreamOutput out = new BytesStreamOutput(); + request.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + CreateResourceLimitGroupRequest otherRequest = new CreateResourceLimitGroupRequest(streamInput); + assertEquals(request.getName(), otherRequest.getName()); + assertEquals(request.getResourceLimits().size(), otherRequest.getResourceLimits().size()); + assertEquals(request.getEnforcement(), otherRequest.getEnforcement()); + compareResourceLimits(request.getResourceLimits(), otherRequest.getResourceLimits()); + } +} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponseTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponseTests.java new file mode 100644 index 0000000000000..7b0e6d9222c6a --- /dev/null +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponseTests.java @@ -0,0 +1,41 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.test.OpenSearchTestCase; + +import java.io.IOException; +import java.util.List; + +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_ONE; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.MONITOR; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimits; + +public class CreateResourceLimitGroupResponseTests extends OpenSearchTestCase { + + public void testSerialization() throws IOException { + ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(NAME_ONE, List.of(new ResourceLimit("jvm", 0.4)), MONITOR); + CreateResourceLimitGroupResponse response = new CreateResourceLimitGroupResponse(resourceLimitGroup); + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + CreateResourceLimitGroupResponse otherResponse = new CreateResourceLimitGroupResponse(streamInput); + assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); + ResourceLimitGroup responseGroup = response.getResourceLimitGroup(); + ResourceLimitGroup otherResponseGroup = otherResponse.getResourceLimitGroup(); + assertEquals(responseGroup.getName(), otherResponseGroup.getName()); + assertEquals(responseGroup.getResourceLimits().size(), otherResponseGroup.getResourceLimits().size()); + assertEquals(responseGroup.getEnforcement(), otherResponseGroup.getEnforcement()); + compareResourceLimits(responseGroup.getResourceLimits(), otherResponseGroup.getResourceLimits()); + } +} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupRequestTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupRequestTests.java new file mode 100644 index 0000000000000..a77ddb6521736 --- /dev/null +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupRequestTests.java @@ -0,0 +1,40 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.test.OpenSearchTestCase; + +import java.io.IOException; + +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_ONE; + +public class DeleteResourceLimitGroupRequestTests extends OpenSearchTestCase { + + public void testSerialization() throws IOException { + DeleteResourceLimitGroupRequest request = new DeleteResourceLimitGroupRequest(NAME_ONE); + assertEquals(NAME_ONE, request.getName()); + BytesStreamOutput out = new BytesStreamOutput(); + request.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + DeleteResourceLimitGroupRequest otherRequest = new DeleteResourceLimitGroupRequest(streamInput); + assertEquals(request.getName(), otherRequest.getName()); + } + + public void testSerializationWithNull() throws IOException { + DeleteResourceLimitGroupRequest request = new DeleteResourceLimitGroupRequest((String) null); + assertNull(request.getName()); + BytesStreamOutput out = new BytesStreamOutput(); + request.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + DeleteResourceLimitGroupRequest otherRequest = new DeleteResourceLimitGroupRequest(streamInput); + assertEquals(request.getName(), otherRequest.getName()); + } +} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponseTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponseTests.java new file mode 100644 index 0000000000000..25e7b33101b79 --- /dev/null +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponseTests.java @@ -0,0 +1,74 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.test.OpenSearchTestCase; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.*; + +public class DeleteResourceLimitGroupResponseTests extends OpenSearchTestCase { + + public void testSerializationSingleResourceLimitGroup() throws IOException { + // create a list of sandboxes as the response + List list = List.of(resourceLimitGroupOne); + DeleteResourceLimitGroupResponse response = new DeleteResourceLimitGroupResponse(list); + assertEquals(response.getResourceLimitGroups(), list); + + // serialize the response + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + + // deserialize the response and check whether each field equals the original list of sandbox + DeleteResourceLimitGroupResponse otherResponse = new DeleteResourceLimitGroupResponse(streamInput); + assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); + compareResourceLimitGroups(response.getResourceLimitGroups(), otherResponse.getResourceLimitGroups()); + } + + public void testSerializationMultipleResourceLimitGroup() throws IOException { + // create a list of sandboxes as the response + DeleteResourceLimitGroupResponse response = new DeleteResourceLimitGroupResponse(resourceLimitGroupList); + assertEquals(response.getResourceLimitGroups(), resourceLimitGroupList); + + // serialize the response + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + + // deserialize the response and check whether each field equals the original list of sandbox + DeleteResourceLimitGroupResponse otherResponse = new DeleteResourceLimitGroupResponse(streamInput); + assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); + assertEquals(2, otherResponse.getResourceLimitGroups().size()); + compareResourceLimitGroups(response.getResourceLimitGroups(), otherResponse.getResourceLimitGroups()); + } + + public void testSerializationNull() throws IOException { + // create a list of sandboxes (empty list) as the response + List list = new ArrayList<>(); + DeleteResourceLimitGroupResponse response = new DeleteResourceLimitGroupResponse(list); + assertEquals(response.getResourceLimitGroups(), list); + + // serialize the response + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + + // deserialize the response and check whether each field equals the original list of sandbox + DeleteResourceLimitGroupResponse otherResponse = new DeleteResourceLimitGroupResponse(streamInput); + assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); + assertEquals(0, otherResponse.getResourceLimitGroups().size()); + } +} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequestTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequestTests.java new file mode 100644 index 0000000000000..ac933c5b2a5a2 --- /dev/null +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequestTests.java @@ -0,0 +1,40 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.test.OpenSearchTestCase; + +import java.io.IOException; + +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_ONE; + +public class GetResourceLimitGroupRequestTests extends OpenSearchTestCase { + + public void testSerialization() throws IOException { + GetResourceLimitGroupRequest request = new GetResourceLimitGroupRequest(NAME_ONE); + assertEquals(NAME_ONE, request.getName()); + BytesStreamOutput out = new BytesStreamOutput(); + request.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + GetResourceLimitGroupRequest otherRequest = new GetResourceLimitGroupRequest(streamInput); + assertEquals(request.getName(), otherRequest.getName()); + } + + public void testSerializationWithNull() throws IOException { + GetResourceLimitGroupRequest request = new GetResourceLimitGroupRequest((String) null); + assertNull(request.getName()); + BytesStreamOutput out = new BytesStreamOutput(); + request.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + GetResourceLimitGroupRequest otherRequest = new GetResourceLimitGroupRequest(streamInput); + assertEquals(request.getName(), otherRequest.getName()); + } +} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponseTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponseTests.java new file mode 100644 index 0000000000000..cd8e3afc3cad3 --- /dev/null +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponseTests.java @@ -0,0 +1,77 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.test.OpenSearchTestCase; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.*; + +public class GetResourceLimitGroupResponseTests extends OpenSearchTestCase { + + public void testSerializationSingleResourceLimitGroup() throws IOException { + // create a list of sandboxes as the response + ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(NAME_ONE, List.of(new ResourceLimit("jvm", 0.4)), MONITOR); + List list = new ArrayList<>(); + list.add(resourceLimitGroup); + GetResourceLimitGroupResponse response = new GetResourceLimitGroupResponse(list); + assertEquals(response.getResourceLimitGroups(), list); + + // serialize the response + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + + // deserialize the response and check whether each field equals the original list of sandbox + GetResourceLimitGroupResponse otherResponse = new GetResourceLimitGroupResponse(streamInput); + assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); + compareResourceLimitGroups(response.getResourceLimitGroups(), otherResponse.getResourceLimitGroups()); + } + + public void testSerializationMultipleResourceLimitGroup() throws IOException { + // create a list of sandboxes as the response + GetResourceLimitGroupResponse response = new GetResourceLimitGroupResponse(resourceLimitGroupList); + assertEquals(response.getResourceLimitGroups(), resourceLimitGroupList); + + // serialize the response + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + + // deserialize the response and check whether each field equals the original list of sandbox + GetResourceLimitGroupResponse otherResponse = new GetResourceLimitGroupResponse(streamInput); + assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); + assertEquals(2, otherResponse.getResourceLimitGroups().size()); + compareResourceLimitGroups(response.getResourceLimitGroups(), otherResponse.getResourceLimitGroups()); + } + + public void testSerializationNull() throws IOException { + // create a list of sandboxes (empty list) as the response + List list = new ArrayList<>(); + GetResourceLimitGroupResponse response = new GetResourceLimitGroupResponse(list); + assertEquals(response.getResourceLimitGroups(), list); + + // serialize the response + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + + // deserialize the response and check whether each field equals the original list of sandbox + GetResourceLimitGroupResponse otherResponse = new GetResourceLimitGroupResponse(streamInput); + assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); + assertEquals(0, otherResponse.getResourceLimitGroups().size()); + } +} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupTestUtils.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupTestUtils.java new file mode 100644 index 0000000000000..85af6152db1b8 --- /dev/null +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupTestUtils.java @@ -0,0 +1,91 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.cluster.ClusterName; +import org.opensearch.cluster.ClusterState; +import org.opensearch.cluster.metadata.Metadata; +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; +import org.opensearch.cluster.service.ClusterService; +import org.opensearch.common.settings.ClusterSettings; +import org.opensearch.common.settings.Settings; +import org.opensearch.plugin.resource_limit_group.service.ResourceLimitGroupPersistenceService; +import org.opensearch.test.OpenSearchTestCase; +import org.opensearch.threadpool.ThreadPool; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.mockito.Mockito.mock; + +public class ResourceLimitGroupTestUtils extends OpenSearchTestCase { + public static final String SANDBOX_MAX_SETTING_NAME = "node.sandbox.max_count"; + public static final String NAME_ONE = "sandbox_one"; + public static final String NAME_TWO = "sandbox_two"; + public static final String NAME_NONE_EXISTED = "sandbox_none_existed"; + public static final String MONITOR = "monitor"; + public static final ResourceLimitGroup resourceLimitGroupOne = new ResourceLimitGroup(NAME_ONE, List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.3)), MONITOR); + public static final ResourceLimitGroup resourceLimitGroupTwo = new ResourceLimitGroup(NAME_TWO, List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.6)), MONITOR); + public static final Map resourceLimitGroupMap = Map.of( + NAME_ONE, resourceLimitGroupOne, + NAME_TWO, resourceLimitGroupTwo + ); + public static final List resourceLimitGroupList= List.of(resourceLimitGroupOne, resourceLimitGroupTwo); + public static final Metadata metadata = Metadata.builder().resourceLimitGroups(resourceLimitGroupMap).build(); + public static final ClusterState clusterState = ClusterState.builder(new ClusterName("_name")).metadata(metadata).build(); + + public static final Settings settings = Settings.builder().build(); + public static final ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + public static final ClusterService clusterService = new ClusterService(settings, clusterSettings, mock(ThreadPool.class)); + public static final ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService = new ResourceLimitGroupPersistenceService(clusterService, settings, clusterSettings); + + + public static List prepareSandboxPersistenceService(List resourceLimitGroups) { + Map resourceLimitGroupMap = new HashMap<>(); + for (ResourceLimitGroup group : resourceLimitGroups) { + resourceLimitGroupMap.put(group.getName(), group); + } + Metadata metadata = Metadata.builder().resourceLimitGroups(resourceLimitGroupMap).build(); + Settings settings = Settings.builder().build(); + ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + ClusterService clusterService = new ClusterService(settings, clusterSettings, mock(ThreadPool.class)); + ClusterState clusterState = ClusterState.builder(new ClusterName("_name")).metadata(metadata).build(); + ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService = new ResourceLimitGroupPersistenceService(clusterService, settings, clusterSettings); + return List.of(resourceLimitGroupPersistenceService, clusterState); + } + + public static void compareResourceLimits(List limitsOne, List limitsTwo) { + assertEquals(limitsOne.size(), limitsTwo.size()); + Map resourceLimitMapOne = limitsOne.stream() + .collect(Collectors.toMap(ResourceLimitGroup.ResourceLimit::getResourceName, ResourceLimitGroup.ResourceLimit::getValue)); + Map resourceLimitMapTwo = limitsTwo.stream() + .collect(Collectors.toMap(ResourceLimitGroup.ResourceLimit::getResourceName, ResourceLimitGroup.ResourceLimit::getValue)); + for (String resourceName : resourceLimitMapOne.keySet()) { + assertTrue(resourceLimitMapTwo.containsKey(resourceName)); + assertEquals(resourceLimitMapOne.get(resourceName), resourceLimitMapTwo.get(resourceName)); + } + } + + public static void compareResourceLimitGroups(List listOne, List listTwo) { + assertEquals(listOne.size(), listTwo.size()); + for (ResourceLimitGroup groupOne : listOne) { + String groupOneName = groupOne.getName(); + List groupTwoList = listTwo.stream().filter(sb -> sb.getName().equals(groupOneName)).collect(Collectors.toList()); + assertEquals(1, groupTwoList.size()); + ResourceLimitGroup groupTwo = groupTwoList.get(0); + assertEquals(groupOne.getName(), groupTwo.getName()); + compareResourceLimits(groupOne.getResourceLimits(), groupTwo.getResourceLimits()); + assertEquals(groupOne.getEnforcement(), groupTwo.getEnforcement()); + } + } +} + diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequestTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequestTests.java new file mode 100644 index 0000000000000..5653a6d7a8156 --- /dev/null +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequestTests.java @@ -0,0 +1,66 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.test.OpenSearchTestCase; + +import java.io.IOException; +import java.util.List; + +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_ONE; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.MONITOR; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimits; + +public class UpdateResourceLimitGroupRequestTests extends OpenSearchTestCase { + + public void testSerialization() throws IOException { + ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(NAME_ONE, List.of(new ResourceLimit("jvm", 0.4)), MONITOR); + UpdateResourceLimitGroupRequest request = new UpdateResourceLimitGroupRequest(resourceLimitGroup); + BytesStreamOutput out = new BytesStreamOutput(); + request.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + UpdateResourceLimitGroupRequest otherRequest = new UpdateResourceLimitGroupRequest(streamInput); + assertEquals(request.getExistingName(), otherRequest.getExistingName()); + assertEquals(request.getUpdatingName(), otherRequest.getUpdatingName()); + assertEquals(request.getResourceLimits().size(), otherRequest.getResourceLimits().size()); + assertEquals(request.getEnforcement(), otherRequest.getEnforcement()); + compareResourceLimits(request.getResourceLimits(), otherRequest.getResourceLimits()); + } + + public void testSerializationOnlyName() throws IOException { + ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(NAME_ONE, null, null); + UpdateResourceLimitGroupRequest request = new UpdateResourceLimitGroupRequest(resourceLimitGroup); + BytesStreamOutput out = new BytesStreamOutput(); + request.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + UpdateResourceLimitGroupRequest otherRequest = new UpdateResourceLimitGroupRequest(streamInput); + assertEquals(request.getExistingName(), otherRequest.getExistingName()); + assertEquals(request.getUpdatingName(), otherRequest.getUpdatingName()); + assertEquals(request.getResourceLimits(), otherRequest.getResourceLimits()); + assertEquals(request.getEnforcement(), otherRequest.getEnforcement()); + } + + public void testSerializationOnlyResourceLimit() throws IOException { + ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(null, List.of(new ResourceLimit("jvm", 0.4)), null); + UpdateResourceLimitGroupRequest request = new UpdateResourceLimitGroupRequest(resourceLimitGroup); + BytesStreamOutput out = new BytesStreamOutput(); + request.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + UpdateResourceLimitGroupRequest otherRequest = new UpdateResourceLimitGroupRequest(streamInput); + assertEquals(request.getExistingName(), otherRequest.getExistingName()); + assertEquals(request.getUpdatingName(), otherRequest.getUpdatingName()); + assertEquals(request.getResourceLimits().size(), otherRequest.getResourceLimits().size()); + compareResourceLimits(request.getResourceLimits(), otherRequest.getResourceLimits()); + assertEquals(request.getEnforcement(), otherRequest.getEnforcement()); + } +} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponseTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponseTests.java new file mode 100644 index 0000000000000..95e580ea184da --- /dev/null +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponseTests.java @@ -0,0 +1,41 @@ +/* + * 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.resource_limit_group; + +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.test.OpenSearchTestCase; + +import java.io.IOException; +import java.util.List; + +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_ONE; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.MONITOR; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimits; + +public class UpdateResourceLimitGroupResponseTests extends OpenSearchTestCase { + + public void testSerialization() throws IOException { + ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(NAME_ONE, List.of(new ResourceLimit("jvm", 0.4)), MONITOR); + UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(resourceLimitGroup); + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + UpdateResourceLimitGroupResponse otherResponse = new UpdateResourceLimitGroupResponse(streamInput); + assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); + ResourceLimitGroup responseGroup = response.getResourceLimitGroup(); + ResourceLimitGroup otherResponseGroup = otherResponse.getResourceLimitGroup(); + assertEquals(responseGroup.getName(), otherResponseGroup.getName()); + assertEquals(responseGroup.getResourceLimits().size(), otherResponseGroup.getResourceLimits().size()); + compareResourceLimits(responseGroup.getResourceLimits(), otherResponseGroup.getResourceLimits()); + assertEquals(responseGroup.getEnforcement(), otherResponseGroup.getEnforcement()); + } +} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceServiceTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceServiceTests.java new file mode 100644 index 0000000000000..30741b2796b10 --- /dev/null +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceServiceTests.java @@ -0,0 +1,147 @@ +/* + * 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.resource_limit_group.service; + +import org.opensearch.cluster.ClusterName; +import org.opensearch.cluster.ClusterState; +import org.opensearch.cluster.metadata.Metadata; +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.cluster.service.ClusterService; +import org.opensearch.common.settings.ClusterSettings; +import org.opensearch.common.settings.Settings; +import org.opensearch.test.OpenSearchTestCase; +import org.opensearch.threadpool.ThreadPool; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.*; +import static org.mockito.Mockito.mock; + +public class ResourceLimitGroupPersistenceServiceTests extends OpenSearchTestCase { + + public void testGetSingleResourceLimitGroup() { + List groups = resourceLimitGroupPersistenceService.getFromClusterStateMetadata(NAME_ONE, clusterState); + assertEquals(1, groups.size()); + ResourceLimitGroup resourceLimitGroup = groups.get(0); + assertEquals(NAME_ONE, resourceLimitGroup.getName()); + assertEquals(MONITOR, resourceLimitGroup.getEnforcement()); + compareResourceLimits(resourceLimitGroupOne.getResourceLimits(), resourceLimitGroup.getResourceLimits()); + } + + public void testGetAllResourceLimitGroups() { + List res = resourceLimitGroupPersistenceService.getFromClusterStateMetadata(null, clusterState); + assertEquals(2, res.size()); + Set currentNAME = res.stream().map(ResourceLimitGroup::getName).collect(Collectors.toSet()); + assertTrue(currentNAME.contains(NAME_ONE)); + assertTrue(currentNAME.contains(NAME_TWO)); + compareResourceLimitGroups(resourceLimitGroupList, res); + } + + public void testGetZeroResourceLimitGroups() { + Settings settings = Settings.builder().build(); + ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + ResourceLimitGroupPersistenceService sandboxPersistenceService = new ResourceLimitGroupPersistenceService(mock(ClusterService.class), settings, clusterSettings); + List res = sandboxPersistenceService.getFromClusterStateMetadata(NAME_NONE_EXISTED, clusterState); + assertEquals(0, res.size()); + } + + public void testDeleteSingleResourceLimitGroup() { + ClusterState newClusterState = resourceLimitGroupPersistenceService.deleteResourceLimitGroupInClusterState(NAME_TWO, clusterState); + Map afterDeletionGroups = newClusterState.getMetadata().resourceLimitGroups(); + assertEquals(1, afterDeletionGroups.size()); + List oldSandbox = List.of(resourceLimitGroupMap.get(NAME_ONE)); + compareResourceLimitGroups(new ArrayList<>(afterDeletionGroups.values()), oldSandbox); + } + + public void testDeleteAllResourceLimitGroups() { + ClusterState newClusterState = resourceLimitGroupPersistenceService.deleteResourceLimitGroupInClusterState(null, clusterState); + Map sandboxes = newClusterState.getMetadata().resourceLimitGroups(); + assertEquals(0, sandboxes.size()); + } + + public void testDeleteNonExistedResourceLimitGroup() { + assertThrows( + RuntimeException.class, + () -> resourceLimitGroupPersistenceService.deleteResourceLimitGroupInClusterState(NAME_NONE_EXISTED, clusterState) + ); + } + + public void testUpdateResourceLimitGroupAllFields() { + ResourceLimitGroup current = resourceLimitGroupOne; + ResourceLimitGroup updated = resourceLimitGroupTwo; + ClusterState newClusterState = resourceLimitGroupPersistenceService.updateResourceLimitGroupInClusterState(current, updated, clusterState); + List updatedSandboxes = new ArrayList<>(newClusterState.getMetadata().resourceLimitGroups().values()); + assertEquals(1, updatedSandboxes.size()); + compareResourceLimitGroups(List.of(updated), updatedSandboxes); + } + + public void testUpdateResourceLimitGroupNameOnly() { + ResourceLimitGroup current = resourceLimitGroupOne; + String updatedName = NAME_ONE + "_updated"; + ResourceLimitGroup updated = new ResourceLimitGroup(updatedName, List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.3)), MONITOR); + ClusterState newClusterState = resourceLimitGroupPersistenceService.updateResourceLimitGroupInClusterState(current, updated, clusterState); + Map updatedSandboxesMap = newClusterState.getMetadata().resourceLimitGroups(); + assertEquals(2, updatedSandboxesMap.size()); + assertTrue(updatedSandboxesMap.containsKey(updatedName)); + assertFalse(updatedSandboxesMap.containsKey(NAME_ONE)); + compareResourceLimitGroups(List.of(updated), List.of(updatedSandboxesMap.get(updatedName))); + } + + public void testCreateResourceLimitGroup() { + List setup = prepareSandboxPersistenceService(new ArrayList<>()); + ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService1 = (ResourceLimitGroupPersistenceService) setup.get(0); + ClusterState clusterState = (ClusterState) setup.get(1); + ClusterState newClusterState = resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState(resourceLimitGroupOne, clusterState); + Map updatedGroupsMap = newClusterState.getMetadata().resourceLimitGroups(); + assertEquals(1, updatedGroupsMap.size()); + assertTrue(updatedGroupsMap.containsKey(NAME_ONE)); + compareResourceLimitGroups(List.of(resourceLimitGroupOne), List.of(updatedGroupsMap.get(NAME_ONE))); + } + + public void testCreateAnotherResourceLimitGroup() { + List setup = prepareSandboxPersistenceService(List.of(resourceLimitGroupOne)); + ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService1 = (ResourceLimitGroupPersistenceService) setup.get(0); + ClusterState clusterState = (ClusterState) setup.get(1); + ClusterState newClusterState = resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState(resourceLimitGroupTwo, clusterState); + Map updatedGroupsMap = newClusterState.getMetadata().resourceLimitGroups(); + assertEquals(2, updatedGroupsMap.size()); + compareResourceLimitGroups(resourceLimitGroupList, new ArrayList<>(updatedGroupsMap.values())); + } + + public void testCreateResourceLimitGroupDuplicateName() { + List setup = prepareSandboxPersistenceService(List.of(resourceLimitGroupOne)); + ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService1 = (ResourceLimitGroupPersistenceService) setup.get(0); + ClusterState clusterState = (ClusterState) setup.get(1); + ResourceLimitGroup toCreate = new ResourceLimitGroup(NAME_ONE, List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.3)), MONITOR); + assertThrows(RuntimeException.class, () -> resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState(toCreate, clusterState)); + } + + public void testCreateResourceLimitGroupOverflowAllocation() { + List setup = prepareSandboxPersistenceService(List.of(resourceLimitGroupTwo)); + ResourceLimitGroup toCreate = new ResourceLimitGroup(NAME_TWO, List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.5)), MONITOR); + ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService1 = (ResourceLimitGroupPersistenceService) setup.get(0); + ClusterState clusterState = (ClusterState) setup.get(1); + assertThrows(RuntimeException.class, () -> resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState(toCreate, clusterState)); + } + + public void testCreateResourceLimitGroupOverflowCount() { + ResourceLimitGroup toCreate = new ResourceLimitGroup(NAME_NONE_EXISTED, List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.5)), MONITOR); + Metadata metadata = Metadata.builder().resourceLimitGroups(resourceLimitGroupMap).build(); + Settings settings = Settings.builder().put(SANDBOX_MAX_SETTING_NAME, 2).build(); + ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + ClusterService clusterService = new ClusterService(settings, clusterSettings, mock(ThreadPool.class)); + ClusterState clusterState = ClusterState.builder(new ClusterName("_name")).metadata(metadata).build(); + ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService1 = new ResourceLimitGroupPersistenceService(clusterService, settings, clusterSettings); + assertThrows(RuntimeException.class, () -> resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState(toCreate, clusterState)); + } +} diff --git a/server/src/main/java/org/opensearch/action/search/SearchRequest.java b/server/src/main/java/org/opensearch/action/search/SearchRequest.java index 2b6c64883a9fb..24a349c3964a9 100644 --- a/server/src/main/java/org/opensearch/action/search/SearchRequest.java +++ b/server/src/main/java/org/opensearch/action/search/SearchRequest.java @@ -840,6 +840,7 @@ public String toString() { + ", phaseTook=" + phaseTook + ", resourceLimitGroupId=" - + resourceLimitGroupId + "}"; + + resourceLimitGroupId + + "}"; } } diff --git a/server/src/main/java/org/opensearch/cluster/ClusterModule.java b/server/src/main/java/org/opensearch/cluster/ClusterModule.java index 5ff312461500e..f805d69fcebde 100644 --- a/server/src/main/java/org/opensearch/cluster/ClusterModule.java +++ b/server/src/main/java/org/opensearch/cluster/ClusterModule.java @@ -208,7 +208,7 @@ public static List getNamedWriteables() { DecommissionAttributeMetadata::readDiffFrom ); registerMetadataCustom( - entries, + entries, ResourceLimitGroupMetadata.TYPE, ResourceLimitGroupMetadata::new, ResourceLimitGroupMetadata::readDiffFrom diff --git a/server/src/main/java/org/opensearch/cluster/metadata/Metadata.java b/server/src/main/java/org/opensearch/cluster/metadata/Metadata.java index 3ab132ddfb067..d9aa19842ef38 100644 --- a/server/src/main/java/org/opensearch/cluster/metadata/Metadata.java +++ b/server/src/main/java/org/opensearch/cluster/metadata/Metadata.java @@ -836,11 +836,9 @@ public Map views() { } public Map resourceLimitGroups() { - return - Optional.ofNullable( - (ResourceLimitGroupMetadata) this.custom(ResourceLimitGroupMetadata.TYPE)). - map(ResourceLimitGroupMetadata::resourceLimitGroups) - .orElse(Collections.emptyMap()); + return Optional.ofNullable((ResourceLimitGroupMetadata) this.custom(ResourceLimitGroupMetadata.TYPE)) + .map(ResourceLimitGroupMetadata::resourceLimitGroups) + .orElse(Collections.emptyMap()); } public DecommissionAttributeMetadata decommissionAttributeMetadata() { diff --git a/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java b/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java index e823b4802de5e..f3391a684efab 100644 --- a/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java +++ b/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java @@ -52,7 +52,6 @@ public class ResourceLimitGroup extends AbstractDiffable imp public static final ParseField RESOURCE_LIMITS_FIELD = new ParseField("resourceLimits"); public static final ParseField ENFORCEMENT_FIELD = new ParseField("enforcement"); - @SuppressWarnings("unchecked") private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( "ResourceLimitGroupParser", @@ -61,7 +60,11 @@ public class ResourceLimitGroup extends AbstractDiffable imp static { PARSER.declareString(ConstructingObjectParser.constructorArg(), NAME_FIELD); - PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), (p, c) -> ResourceLimit.fromXContent(p), RESOURCE_LIMITS_FIELD); + PARSER.declareObjectArray( + ConstructingObjectParser.constructorArg(), + (p, c) -> ResourceLimit.fromXContent(p), + RESOURCE_LIMITS_FIELD + ); PARSER.declareString(ConstructingObjectParser.constructorArg(), ENFORCEMENT_FIELD); } @@ -72,7 +75,11 @@ public class ResourceLimitGroup extends AbstractDiffable imp static { PARSER_OPTIONAL_FIELDS.declareString(ConstructingObjectParser.optionalConstructorArg(), NAME_FIELD); - PARSER_OPTIONAL_FIELDS.declareObjectArray(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> ResourceLimit.fromXContent(p), RESOURCE_LIMITS_FIELD); + PARSER_OPTIONAL_FIELDS.declareObjectArray( + ConstructingObjectParser.optionalConstructorArg(), + (p, c) -> ResourceLimit.fromXContent(p), + RESOURCE_LIMITS_FIELD + ); PARSER_OPTIONAL_FIELDS.declareString(ConstructingObjectParser.optionalConstructorArg(), ENFORCEMENT_FIELD); } @@ -106,8 +113,10 @@ private void isValidResourceLimitGroup(String name, String enforcement) { } if (enforcement != null) { if (!ALLOWED_ENFORCEMENTS.contains(enforcement)) { - throw new IllegalArgumentException("enforcement has to be valid, valid enforcements " - + ALLOWED_ENFORCEMENTS.stream().reduce((x, e) -> x + ", " + e).get()); + throw new IllegalArgumentException( + "enforcement has to be valid, valid enforcements are: " + + ALLOWED_ENFORCEMENTS.stream().reduce((x, e) -> x + ", " + e).get() + ); } } } @@ -155,9 +164,10 @@ private static void isValidResourceLimit(String resourceName, double value) { if (str.contains(".") && str.split("\\.")[1].length() > 2) { throw new IllegalArgumentException("Resource limit value should have at most two digits after the decimal point"); } - if (!ALLOWED_RESOURCES.contains(resourceName.toLowerCase())) { - throw new IllegalArgumentException("resource has to be valid, valid resources " - + ALLOWED_RESOURCES.stream().reduce((x, e) -> x + ", " + e).get()); + if (!ALLOWED_RESOURCES.contains(resourceName.toLowerCase(Locale.ROOT))) { + throw new IllegalArgumentException( + "resource has to be valid, valid resources are: " + ALLOWED_RESOURCES.stream().reduce((x, e) -> x + ", " + e).get() + ); } } @@ -227,7 +237,8 @@ public void writeTo(StreamOutput out) throws IOException { writeToOutputStream(out, name, resourceLimits, enforcement); } - public static void writeToOutputStream(StreamOutput out, String name, List resourceLimits, String enforcement) throws IOException { + public static void writeToOutputStream(StreamOutput out, String name, List resourceLimits, String enforcement) + throws IOException { out.writeString(name); out.writeList(resourceLimits); out.writeString(enforcement); @@ -266,7 +277,9 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ResourceLimitGroup that = (ResourceLimitGroup) o; - return Objects.equals(name, that.name) && Objects.equals(resourceLimits, that.resourceLimits) && Objects.equals(enforcement, that.enforcement); + return Objects.equals(name, that.name) + && Objects.equals(resourceLimits, that.resourceLimits) + && Objects.equals(enforcement, that.enforcement); } @Override diff --git a/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroupMetadata.java b/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroupMetadata.java index 4bf639f15e5ab..3107bd8f44136 100644 --- a/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroupMetadata.java +++ b/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroupMetadata.java @@ -15,7 +15,6 @@ import org.opensearch.common.annotation.ExperimentalApi; import org.opensearch.core.ParseField; import org.opensearch.core.common.Strings; -import org.opensearch.core.common.io.stream.NamedWriteable; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.core.common.io.stream.StreamOutput; import org.opensearch.core.xcontent.ConstructingObjectParser; @@ -44,7 +43,7 @@ public class ResourceLimitGroupMetadata implements Metadata.Custom { @SuppressWarnings("unchecked") static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( "resourceLimitGroupParser", - args -> new ResourceLimitGroupMetadata((Map) args [0]) + args -> new ResourceLimitGroupMetadata((Map) args[0]) ); static { @@ -57,7 +56,6 @@ public class ResourceLimitGroupMetadata implements Metadata.Custom { }, RESOURCE_LIMIT_GROUP_FIELD); } - private final Map resourceLimitGroups; public ResourceLimitGroupMetadata(Map resourceLimitGroups) { @@ -68,7 +66,6 @@ public ResourceLimitGroupMetadata(StreamInput in) throws IOException { this.resourceLimitGroups = in.readMap(StreamInput::readString, ResourceLimitGroup::new); } - public Map resourceLimitGroups() { return this.resourceLimitGroups; } @@ -108,7 +105,7 @@ public void writeTo(StreamOutput out) throws IOException { @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(RESOURCE_LIMIT_GROUP_FIELD.getPreferredName()); - for (Map.Entry entry: resourceLimitGroups.entrySet()) { + for (Map.Entry entry : resourceLimitGroups.entrySet()) { builder.field(entry.getKey(), entry.getValue()); } builder.endObject(); @@ -147,19 +144,21 @@ public EnumSet context() { static class ResourceLimitGroupMetadataDiff implements NamedDiff { final Diff> dataStreanDiff; - - ResourceLimitGroupMetadataDiff(final ResourceLimitGroupMetadata before, - final ResourceLimitGroupMetadata after) { - dataStreanDiff = DiffableUtils.diff(before.resourceLimitGroups, - after.resourceLimitGroups, - DiffableUtils.getStringKeySerializer()); + ResourceLimitGroupMetadataDiff(final ResourceLimitGroupMetadata before, final ResourceLimitGroupMetadata after) { + dataStreanDiff = DiffableUtils.diff( + before.resourceLimitGroups, + after.resourceLimitGroups, + DiffableUtils.getStringKeySerializer() + ); } ResourceLimitGroupMetadataDiff(final StreamInput in) throws IOException { - this.dataStreanDiff = DiffableUtils.readJdkMapDiff(in, + this.dataStreanDiff = DiffableUtils.readJdkMapDiff( + in, DiffableUtils.getStringKeySerializer(), ResourceLimitGroup::new, - ResourceLimitGroup::readDiff); + ResourceLimitGroup::readDiff + ); } /** @@ -187,13 +186,10 @@ public void writeTo(StreamOutput out) throws IOException { */ @Override public Metadata.Custom apply(Metadata.Custom part) { - return new ResourceLimitGroupMetadata(dataStreanDiff.apply( - ((ResourceLimitGroupMetadata) part).resourceLimitGroups) - ); + return new ResourceLimitGroupMetadata(dataStreanDiff.apply(((ResourceLimitGroupMetadata) part).resourceLimitGroups)); } } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupService.java b/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupService.java index 4fd58d063f4e1..97c9aac64a9a2 100644 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupService.java +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupService.java @@ -12,8 +12,8 @@ import org.apache.logging.log4j.Logger; import org.opensearch.common.inject.Inject; import org.opensearch.common.lifecycle.AbstractLifecycleComponent; -import org.opensearch.search.resource_limit_group.tracker.ResourceLimitGroupResourceUsageTracker; import org.opensearch.search.resource_limit_group.cancellation.ResourceLimitGroupRequestCanceller; +import org.opensearch.search.resource_limit_group.tracker.ResourceLimitGroupResourceUsageTracker; import org.opensearch.threadpool.Scheduler; import org.opensearch.threadpool.ThreadPool; @@ -59,9 +59,9 @@ public ResourceLimitGroupService( * run at regular interval */ private void doRun() { - requestTracker.updateResourceLimitGroupsResourceUsage(); - requestCanceller.cancelViolatingTasks(); - resourceLimitGroupPruner.pruneResourceLimitGroup(); + requestTracker.updateResourceLimitGroupsResourceUsage(); + requestCanceller.cancelViolatingTasks(); + resourceLimitGroupPruner.pruneResourceLimitGroup(); } /** diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettings.java b/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettings.java index 56bdfbae87168..9f792390fd8ff 100644 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettings.java +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettings.java @@ -41,8 +41,9 @@ public class ResourceLimitGroupServiceSettings { DEFAULT_MAX_RESOURCE_LIMIT_GROUP_COUNT_VALUE, 0, (newVal) -> { - if (newVal > 100 || newVal < 1) - throw new IllegalArgumentException(RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME + " should be in range [1-100]"); + if (newVal > 100 || newVal < 1) throw new IllegalArgumentException( + RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME + " should be in range [1-100]" + ); }, Setting.Property.Dynamic, Setting.Property.NodeScope @@ -142,8 +143,7 @@ public Double getNodeLevelJvmCancellationThreshold() { public void setNodeLevelJvmCancellationThreshold(Double nodeLevelJvmCancellationThreshold) { if (Double.compare(nodeLevelJvmCancellationThreshold, NODE_LEVEL_CANCELLATION_THRESHOLD_MAX_VALUE) > 0) { throw new IllegalArgumentException( - NODE_CANCELLATION_THRESHOLD_SETTING_NAME - + " value should not be greater than 0.95 as it pose a threat of node drop" + NODE_CANCELLATION_THRESHOLD_SETTING_NAME + " value should not be greater than 0.95 as it pose a threat of node drop" ); } @@ -181,11 +181,9 @@ private void ensureRejectionThresholdIsLessThanCancellation( Double nodeLevelJvmRejectionThreshold, Double nodeLevelJvmCancellationThreshold ) { - if (Double.compare(nodeLevelJvmCancellationThreshold , nodeLevelJvmRejectionThreshold) < 0) { + if (Double.compare(nodeLevelJvmCancellationThreshold, nodeLevelJvmRejectionThreshold) < 0) { throw new IllegalArgumentException( - NODE_CANCELLATION_THRESHOLD_SETTING_NAME - + " value should not be less than " - + NODE_REJECTION_THRESHOLD_SETTING_NAME + NODE_CANCELLATION_THRESHOLD_SETTING_NAME + " value should not be less than " + NODE_REJECTION_THRESHOLD_SETTING_NAME ); } } diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/module/ResourceLimitGroupModule.java b/server/src/main/java/org/opensearch/search/resource_limit_group/module/ResourceLimitGroupModule.java index 3b7c1bb0fa722..fb2d607e4f774 100644 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/module/ResourceLimitGroupModule.java +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/module/ResourceLimitGroupModule.java @@ -8,12 +8,10 @@ package org.opensearch.search.resource_limit_group.module; -import org.opensearch.cluster.metadata.ResourceLimitGroup; import org.opensearch.common.inject.AbstractModule; -import org.opensearch.common.inject.TypeLiteral; import org.opensearch.search.resource_limit_group.ResourceLimitGroupPruner; -import org.opensearch.search.resource_limit_group.tracker.ResourceLimitGroupResourceUsageTracker; import org.opensearch.search.resource_limit_group.cancellation.ResourceLimitGroupRequestCanceller; +import org.opensearch.search.resource_limit_group.tracker.ResourceLimitGroupResourceUsageTracker; import org.opensearch.search.resource_limit_group.tracker.ResourceLimitsGroupResourceUsageTrackerService; /** diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitsGroupResourceUsageTrackerService.java b/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitsGroupResourceUsageTrackerService.java index f0034b46a65ea..5e14b6935c564 100644 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitsGroupResourceUsageTrackerService.java +++ b/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitsGroupResourceUsageTrackerService.java @@ -28,10 +28,10 @@ */ public class ResourceLimitsGroupResourceUsageTrackerService implements - TaskManager.TaskEventListeners, - ResourceLimitGroupResourceUsageTracker, - ResourceLimitGroupRequestCanceller, - ResourceLimitGroupPruner { + TaskManager.TaskEventListeners, + ResourceLimitGroupResourceUsageTracker, + ResourceLimitGroupRequestCanceller, + ResourceLimitGroupPruner { private static final String CPU = "CPU"; private static final String JVM_ALLOCATIONS = "JVM_Allocations"; diff --git a/server/src/test/java/org/opensearch/search/sandbox/ResourceLimitGroupServiceSettingsTests.java b/server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettingsTests.java similarity index 78% rename from server/src/test/java/org/opensearch/search/sandbox/ResourceLimitGroupServiceSettingsTests.java rename to server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettingsTests.java index 0e500434ea488..cc31caccc42f2 100644 --- a/server/src/test/java/org/opensearch/search/sandbox/ResourceLimitGroupServiceSettingsTests.java +++ b/server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettingsTests.java @@ -6,15 +6,15 @@ * compatible open source license. */ -package org.opensearch.search.sandbox; +package org.opensearch.search.resource_limit_group; import org.opensearch.common.settings.ClusterSettings; import org.opensearch.common.settings.Settings; import org.opensearch.test.OpenSearchTestCase; -import static org.opensearch.search.sandbox.ResourceLimitGroupServiceSettings.NODE_CANCELLATION_THRESHOLD_SETTING_NAME; -import static org.opensearch.search.sandbox.ResourceLimitGroupServiceSettings.NODE_REJECTION_THRESHOLD_SETTING_NAME; -import static org.opensearch.search.sandbox.ResourceLimitGroupServiceSettings.RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME; +import static org.opensearch.search.resource_limit_group.ResourceLimitGroupServiceSettings.NODE_CANCELLATION_THRESHOLD_SETTING_NAME; +import static org.opensearch.search.resource_limit_group.ResourceLimitGroupServiceSettings.NODE_REJECTION_THRESHOLD_SETTING_NAME; +import static org.opensearch.search.resource_limit_group.ResourceLimitGroupServiceSettings.RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME; public class ResourceLimitGroupServiceSettingsTests extends OpenSearchTestCase { @@ -28,15 +28,13 @@ public void testValidMaxSandboxCountSetting() { assertEquals(100, resourceLimitGroupServiceSettings.getMaxResourceLimitGroupCount()); } - /** * test the invalid value of {@code node.sandbox.max_count} */ public void testInValidMaxSandboxCountSetting() { Settings settings = Settings.builder().put(RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME, -100).build(); ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - assertThrows(IllegalArgumentException.class, - () -> new ResourceLimitGroupServiceSettings(settings, cs)); + assertThrows(IllegalArgumentException.class, () -> new ResourceLimitGroupServiceSettings(settings, cs)); } /** @@ -57,8 +55,7 @@ public void testInValidNodeLevelRejectionThresholdCase1() { Settings settings = Settings.builder().put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.80).build(); ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); - assertThrows(IllegalArgumentException.class, - () -> resourceLimitGroupServiceSettings.setNodeLevelJvmRejectionThreshold(0.95)); + assertThrows(IllegalArgumentException.class, () -> resourceLimitGroupServiceSettings.setNodeLevelJvmRejectionThreshold(0.95)); } /** @@ -66,16 +63,15 @@ public void testInValidNodeLevelRejectionThresholdCase1() { * When the value is set more than {@code query_sandbox.node.cancellation_threshold} */ public void testInValidNodeLevelRejectionThresholdCase2() { - Settings settings = Settings.builder().put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.70) + Settings settings = Settings.builder() + .put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.70) .put(NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80) .build(); ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); - assertThrows(IllegalArgumentException.class, - () -> resourceLimitGroupServiceSettings.setNodeLevelJvmRejectionThreshold(0.85)); + assertThrows(IllegalArgumentException.class, () -> resourceLimitGroupServiceSettings.setNodeLevelJvmRejectionThreshold(0.85)); } - /** * Tests the invalid value for {@code query_sandbox.node.rejection_threshold} * When the value is set more than {@code query_sandbox.node.cancellation_threshold} accidentally during @@ -83,13 +79,13 @@ public void testInValidNodeLevelRejectionThresholdCase2() { * invariant {@code nodeLevelRejectionThreshold < nodeLevelCancellationThreshold} */ public void testInValidInstantiationOfQuerySandboxServiceSettings() { - Settings settings = Settings.builder().put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.80) + Settings settings = Settings.builder() + .put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.80) .put(NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.70) .build(); ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - assertThrows(IllegalArgumentException.class, - () -> new ResourceLimitGroupServiceSettings(settings, cs)); + assertThrows(IllegalArgumentException.class, () -> new ResourceLimitGroupServiceSettings(settings, cs)); } /** @@ -110,8 +106,7 @@ public void testInValidNodeLevelCancellationThresholdCase1() { Settings settings = Settings.builder().put(NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80).build(); ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); - assertThrows(IllegalArgumentException.class, - () -> resourceLimitGroupServiceSettings.setNodeLevelJvmRejectionThreshold(0.96)); + assertThrows(IllegalArgumentException.class, () -> resourceLimitGroupServiceSettings.setNodeLevelJvmRejectionThreshold(0.96)); } /** @@ -119,13 +114,13 @@ public void testInValidNodeLevelCancellationThresholdCase1() { * When the value is set less than {@code query_sandbox.node.rejection_threshold} */ public void testInValidNodeLevelCancellationThresholdCase2() { - Settings settings = Settings.builder().put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.70) + Settings settings = Settings.builder() + .put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.70) .put(NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80) .build(); ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); - assertThrows(IllegalArgumentException.class, - () -> resourceLimitGroupServiceSettings.setNodeLevelJvmRejectionThreshold(0.85)); + assertThrows(IllegalArgumentException.class, () -> resourceLimitGroupServiceSettings.setNodeLevelJvmRejectionThreshold(0.85)); } } diff --git a/server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupTests.java b/server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupTests.java new file mode 100644 index 0000000000000..6b1e58acffab3 --- /dev/null +++ b/server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupTests.java @@ -0,0 +1,115 @@ +/* + * 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.search.resource_limit_group; + +import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.test.OpenSearchTestCase; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class ResourceLimitGroupTests extends OpenSearchTestCase { + + public static final String JVM = "jvm"; + public static final String NAME_ONE = "resource_limit_group_one"; + public static final String MONITOR = "monitor"; + public static final ResourceLimitGroup resourceLimitGroupOne = new ResourceLimitGroup( + NAME_ONE, + List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), + MONITOR + ); + + public static void compareResourceLimits( + List limitsOne, + List limitsTwo + ) { + assertEquals(limitsOne.size(), limitsTwo.size()); + Map resourceLimitMapOne = limitsOne.stream() + .collect(Collectors.toMap(ResourceLimitGroup.ResourceLimit::getResourceName, ResourceLimitGroup.ResourceLimit::getValue)); + Map resourceLimitMapTwo = limitsTwo.stream() + .collect(Collectors.toMap(ResourceLimitGroup.ResourceLimit::getResourceName, ResourceLimitGroup.ResourceLimit::getValue)); + for (String resourceName : resourceLimitMapOne.keySet()) { + assertTrue(resourceLimitMapTwo.containsKey(resourceName)); + assertEquals(resourceLimitMapOne.get(resourceName), resourceLimitMapTwo.get(resourceName)); + } + } + + public static void compareResourceLimitGroups(List listOne, List listTwo) { + assertEquals(listOne.size(), listTwo.size()); + for (ResourceLimitGroup groupOne : listOne) { + String groupOneName = groupOne.getName(); + List groupTwoList = listTwo.stream() + .filter(sb -> sb.getName().equals(groupOneName)) + .collect(Collectors.toList()); + assertEquals(1, groupTwoList.size()); + ResourceLimitGroup groupTwo = groupTwoList.get(0); + assertEquals(groupOne.getName(), groupTwo.getName()); + compareResourceLimits(groupOne.getResourceLimits(), groupTwo.getResourceLimits()); + assertEquals(groupOne.getEnforcement(), groupTwo.getEnforcement()); + } + } + + public void testSerializationResourceLimitGroup() throws IOException { + BytesStreamOutput out = new BytesStreamOutput(); + resourceLimitGroupOne.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + ResourceLimitGroup otherGroup = new ResourceLimitGroup(streamInput); + compareResourceLimitGroups(List.of(resourceLimitGroupOne), List.of(otherGroup)); + } + + public void testInvalidName() { + assertThrows( + IllegalArgumentException.class, + () -> new ResourceLimitGroup("", List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR) + ); + assertThrows( + IllegalArgumentException.class, + () -> new ResourceLimitGroup("-test", List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR) + ); + assertThrows( + IllegalArgumentException.class, + () -> new ResourceLimitGroup("_test", List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR) + ); + assertThrows( + IllegalArgumentException.class, + () -> new ResourceLimitGroup(":test", List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR) + ); + assertThrows( + IllegalArgumentException.class, + () -> new ResourceLimitGroup("te*st", List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR) + ); + assertThrows( + IllegalArgumentException.class, + () -> new ResourceLimitGroup("test?", List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR) + ); + assertThrows( + IllegalArgumentException.class, + () -> new ResourceLimitGroup("Test", List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR) + ); + } + + public void testInvalidEnforcement() { + assertThrows( + IllegalArgumentException.class, + () -> new ResourceLimitGroup(NAME_ONE, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), "random") + ); + } + + public void testInvalidResourceLimit() { + assertThrows(IllegalArgumentException.class, () -> new ResourceLimit(JVM, -3.0)); + assertThrows(IllegalArgumentException.class, () -> new ResourceLimit(JVM, 12.0)); + assertThrows(IllegalArgumentException.class, () -> new ResourceLimit(JVM, 0.345)); + assertThrows(IllegalArgumentException.class, () -> new ResourceLimit("cpu", 0.3)); + } +} From cd09285f4e4a16491a19b2420fc0b72807bfaa03 Mon Sep 17 00:00:00 2001 From: Ruirui Zhang Date: Fri, 19 Apr 2024 16:29:24 -0700 Subject: [PATCH 07/15] modify changelog Signed-off-by: Ruirui Zhang --- CHANGELOG-3.0.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG-3.0.md b/CHANGELOG-3.0.md index 964383078c38d..1f5942af52742 100644 --- a/CHANGELOG-3.0.md +++ b/CHANGELOG-3.0.md @@ -24,6 +24,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Add task completion count in search backpressure stats API ([#10028](https://github.com/opensearch-project/OpenSearch/pull/10028/)) - Deprecate CamelCase `PathHierarchy` tokenizer name in favor to lowercase `path_hierarchy` ([#10894](https://github.com/opensearch-project/OpenSearch/pull/10894)) - Breaking change: Do not request "search_pipelines" metrics by default in NodesInfoRequest ([#12497](https://github.com/opensearch-project/OpenSearch/pull/12497)) +- [Query Sandbox] Add Resource Limit Group CRUD APIs ([#13315](https://github.com/opensearch-project/OpenSearch/pull/13315)) ### Deprecated From 14e9d7b533e1024ef59a7a74a304ff550314e2b9 Mon Sep 17 00:00:00 2001 From: Ruirui Zhang Date: Sat, 27 Apr 2024 15:22:55 -0700 Subject: [PATCH 08/15] add id, create and update timestamp to resource limit group Signed-off-by: Ruirui Zhang --- .../CreateResourceLimitGroupRequest.java | 72 ++++++- .../GetResourceLimitGroupRequest.java | 1 - .../ResourceLimitGroupPlugin.java | 10 +- .../ResourceLimitGroupPluginModule.java | 6 +- ...ansportCreateResourceLimitGroupAction.java | 37 ++-- ...ansportDeleteResourceLimitGroupAction.java | 25 ++- .../TransportGetResourceLimitGroupAction.java | 19 +- ...ansportUpdateResourceLimitGroupAction.java | 37 ++-- .../UpdateResourceLimitGroupRequest.java | 65 +++--- .../RestCreateResourceLimitGroupAction.java | 18 +- .../RestDeleteResourceLimitGroupAction.java | 13 +- .../rest/RestGetResourceLimitGroupAction.java | 13 +- .../RestUpdateResourceLimitGroupAction.java | 17 +- .../service/Persistable.java | 3 +- .../ResourceLimitGroupPersistenceService.java | 192 ++++++++++-------- .../CreateResourceLimitGroupRequestTests.java | 11 +- ...CreateResourceLimitGroupResponseTests.java | 14 +- ...DeleteResourceLimitGroupResponseTests.java | 13 +- .../GetResourceLimitGroupResponseTests.java | 17 +- .../ResourceLimitGroupTestUtils.java | 53 +++-- .../UpdateResourceLimitGroupRequestTests.java | 29 ++- ...UpdateResourceLimitGroupResponseTests.java | 14 +- ...urceLimitGroupPersistenceServiceTests.java | 114 +++++++++-- .../search/AbstractSearchAsyncAction.java | 3 - .../action/search/SearchRequest.java | 26 +-- .../action/search/SearchShardTask.java | 9 - .../opensearch/action/search/SearchTask.java | 9 - .../action/search/TransportSearchAction.java | 3 - .../cluster/metadata/ResourceLimitGroup.java | 83 +++++++- .../rest/action/search/RestSearchAction.java | 5 - .../org/opensearch/search/SearchService.java | 3 - .../search/internal/ShardSearchRequest.java | 16 -- .../ResourceLimitGroupTests.java | 41 +++- 33 files changed, 604 insertions(+), 387 deletions(-) diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequest.java index 11c08d41191df..c897957a66438 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequest.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequest.java @@ -26,9 +26,12 @@ * @opensearch.internal */ public class CreateResourceLimitGroupRequest extends ActionRequest implements Writeable.Reader { - String name; - List resourceLimits; - String enforcement; + private String name; + private String uuid; + private List resourceLimits; + private String enforcement; + private String createdAt; + private String updatedAt; /** * Default constructor for CreateResourceLimitGroupRequest @@ -41,8 +44,11 @@ public CreateResourceLimitGroupRequest() {} */ public CreateResourceLimitGroupRequest(ResourceLimitGroup resourceLimitGroup) { this.name = resourceLimitGroup.getName(); + this.uuid = resourceLimitGroup.getUUID(); this.resourceLimits = resourceLimitGroup.getResourceLimits(); this.enforcement = resourceLimitGroup.getEnforcement(); + this.createdAt = resourceLimitGroup.getCreatedAt(); + this.updatedAt = resourceLimitGroup.getUpdatedAt(); } /** @@ -52,8 +58,11 @@ public CreateResourceLimitGroupRequest(ResourceLimitGroup resourceLimitGroup) { public CreateResourceLimitGroupRequest(StreamInput in) throws IOException { super(in); name = in.readString(); + uuid = in.readString(); resourceLimits = in.readList(ResourceLimit::new); enforcement = in.readString(); + createdAt = in.readString(); + updatedAt = in.readString(); } @Override @@ -76,14 +85,14 @@ public ActionRequestValidationException validate() { } /** - * Name getter + * name getter */ public String getName() { return name; } /** - * Name setter + * name setter * @param name - name to be set */ public void setName(String name) { @@ -91,15 +100,15 @@ public void setName(String name) { } /** - * ResourceLimits getter + * resourceLimits getter */ public List getResourceLimits() { return resourceLimits; } /** - * ResourceLimits setter - * @param resourceLimits - ResourceLimit to be set + * resourceLimits setter + * @param resourceLimits - resourceLimit to be set */ public void setResourceLimits(List resourceLimits) { this.resourceLimits = resourceLimits; @@ -123,6 +132,51 @@ public void setEnforcement(String enforcement) { @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); - ResourceLimitGroup.writeToOutputStream(out, name, resourceLimits, enforcement); + ResourceLimitGroup.writeToOutputStream(out, name, uuid, resourceLimits, enforcement, createdAt, updatedAt); + } + + /** + * UUID getter + */ + public String getUUID() { + return uuid; + } + + /** + * UUID setter + * @param uuid - uuid to be set + */ + public void setUUID(String uuid) { + this.uuid = uuid; + } + + /** + * createdAt getter + */ + public String getCreatedAt() { + return createdAt; + } + + /** + * createdAt setter + * @param createdAt - createdAt to be set + */ + public void setCreatedAt(String createdAt) { + this.createdAt = createdAt; + } + + /** + * updatedAt getter + */ + public String getUpdatedAt() { + return updatedAt; + } + + /** + * updatedAt setter + * @param updatedAt - updatedAt to be set + */ + public void setUpdatedAt(String updatedAt) { + this.updatedAt = updatedAt; } } diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequest.java index 6cc09722f7e0f..efba50ab1beb8 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequest.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequest.java @@ -17,7 +17,6 @@ import org.opensearch.core.xcontent.XContentParser; import java.io.IOException; -import java.util.List; /** * A request for get Resource Limit Group diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java index d2634f8fd3506..af66821f7a68d 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java @@ -51,7 +51,15 @@ public ResourceLimitGroupPlugin() {} } @Override - public List getRestHandlers(Settings settings, RestController restController, ClusterSettings clusterSettings, IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter, IndexNameExpressionResolver indexNameExpressionResolver, Supplier nodesInCluster) { + public List getRestHandlers( + Settings settings, + RestController restController, + ClusterSettings clusterSettings, + IndexScopedSettings indexScopedSettings, + SettingsFilter settingsFilter, + IndexNameExpressionResolver indexNameExpressionResolver, + Supplier nodesInCluster + ) { return List.of( new RestCreateResourceLimitGroupAction(), new RestGetResourceLimitGroupAction(), diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPluginModule.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPluginModule.java index 16411db4fb7ce..bebf3f24b32f0 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPluginModule.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPluginModule.java @@ -22,10 +22,12 @@ public class ResourceLimitGroupPluginModule extends AbstractModule { /** * Constructor for ResourceLimitGroupPluginModule */ - public ResourceLimitGroupPluginModule(){} + public ResourceLimitGroupPluginModule() {} + @Override protected void configure() { // bind(Persistable.class).to(ResourceLimitGroupPersistenceService.class).asEagerSingleton(); - bind(new TypeLiteral>() {}).to(ResourceLimitGroupPersistenceService.class).asEagerSingleton(); + bind(new TypeLiteral>() { + }).to(ResourceLimitGroupPersistenceService.class).asEagerSingleton(); } } diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportCreateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportCreateResourceLimitGroupAction.java index 94f79b94437a1..05b9c34a01907 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportCreateResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportCreateResourceLimitGroupAction.java @@ -23,12 +23,13 @@ * * @opensearch.internal */ -public class TransportCreateResourceLimitGroupAction extends HandledTransportAction { +public class TransportCreateResourceLimitGroupAction extends HandledTransportAction< + CreateResourceLimitGroupRequest, + CreateResourceLimitGroupResponse> { private final ThreadPool threadPool; private final Persistable resourceLimitGroupPersistenceService; - /** * Constructor for TransportCreateResourceLimitGroupAction * @@ -39,21 +40,33 @@ public class TransportCreateResourceLimitGroupAction extends HandledTransportAct * @param resourceLimitGroupPersistenceService - a {@link Persistable} object */ @Inject - public TransportCreateResourceLimitGroupAction - (String actionName, - TransportService transportService, - ActionFilters actionFilters, - ThreadPool threadPool, - Persistable resourceLimitGroupPersistenceService - ) { + public TransportCreateResourceLimitGroupAction( + String actionName, + TransportService transportService, + ActionFilters actionFilters, + ThreadPool threadPool, + Persistable resourceLimitGroupPersistenceService + ) { super(CreateResourceLimitGroupAction.NAME, transportService, actionFilters, CreateResourceLimitGroupRequest::new); this.threadPool = threadPool; this.resourceLimitGroupPersistenceService = resourceLimitGroupPersistenceService; } @Override - protected void doExecute(Task task, CreateResourceLimitGroupRequest request, ActionListener listener) { - ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(request.getName(), request.getResourceLimits(), request.getEnforcement()); - threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> resourceLimitGroupPersistenceService.persist(resourceLimitGroup, listener)); + protected void doExecute( + Task task, + CreateResourceLimitGroupRequest request, + ActionListener listener + ) { + ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup( + request.getName(), + request.getUUID(), + request.getResourceLimits(), + request.getEnforcement(), + request.getCreatedAt(), + request.getUpdatedAt() + ); + threadPool.executor(ThreadPool.Names.GENERIC) + .execute(() -> resourceLimitGroupPersistenceService.persist(resourceLimitGroup, listener)); } } diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportDeleteResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportDeleteResourceLimitGroupAction.java index 12308ee894e36..be0107b0d9d77 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportDeleteResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportDeleteResourceLimitGroupAction.java @@ -23,12 +23,13 @@ * * @opensearch.internal */ -public class TransportDeleteResourceLimitGroupAction extends HandledTransportAction { +public class TransportDeleteResourceLimitGroupAction extends HandledTransportAction< + DeleteResourceLimitGroupRequest, + DeleteResourceLimitGroupResponse> { private final ThreadPool threadPool; private final Persistable resourceLimitGroupPersistenceService; - /** * Constructor for TransportDeleteResourceLimitGroupAction * @@ -39,20 +40,24 @@ public class TransportDeleteResourceLimitGroupAction extends HandledTransportAct * @param resourceLimitGroupPersistenceService - a {@link Persistable} object */ @Inject - public TransportDeleteResourceLimitGroupAction - (String actionName, - TransportService transportService, - ActionFilters actionFilters, - ThreadPool threadPool, - Persistable resourceLimitGroupPersistenceService - ) { + public TransportDeleteResourceLimitGroupAction( + String actionName, + TransportService transportService, + ActionFilters actionFilters, + ThreadPool threadPool, + Persistable resourceLimitGroupPersistenceService + ) { super(DeleteResourceLimitGroupAction.NAME, transportService, actionFilters, DeleteResourceLimitGroupRequest::new); this.threadPool = threadPool; this.resourceLimitGroupPersistenceService = resourceLimitGroupPersistenceService; } @Override - protected void doExecute(Task task, DeleteResourceLimitGroupRequest request, ActionListener listener) { + protected void doExecute( + Task task, + DeleteResourceLimitGroupRequest request, + ActionListener listener + ) { String name = request.getName(); threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> resourceLimitGroupPersistenceService.delete(name, listener)); } diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportGetResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportGetResourceLimitGroupAction.java index 4d2d60ce8f9d6..8f2b1cf4c2c86 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportGetResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportGetResourceLimitGroupAction.java @@ -23,12 +23,13 @@ * * @opensearch.internal */ -public class TransportGetResourceLimitGroupAction extends HandledTransportAction { +public class TransportGetResourceLimitGroupAction extends HandledTransportAction< + GetResourceLimitGroupRequest, + GetResourceLimitGroupResponse> { private final ThreadPool threadPool; private final Persistable resourceLimitGroupPersistenceService; - /** * Constructor for TransportGetResourceLimitGroupAction * @@ -39,13 +40,13 @@ public class TransportGetResourceLimitGroupAction extends HandledTransportAction * @param resourceLimitGroupPersistenceService - a {@link Persistable} object */ @Inject - public TransportGetResourceLimitGroupAction - (String actionName, - TransportService transportService, - ActionFilters actionFilters, - ThreadPool threadPool, - Persistable resourceLimitGroupPersistenceService - ) { + public TransportGetResourceLimitGroupAction( + String actionName, + TransportService transportService, + ActionFilters actionFilters, + ThreadPool threadPool, + Persistable resourceLimitGroupPersistenceService + ) { super(GetResourceLimitGroupAction.NAME, transportService, actionFilters, GetResourceLimitGroupRequest::new); this.threadPool = threadPool; this.resourceLimitGroupPersistenceService = resourceLimitGroupPersistenceService; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportUpdateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportUpdateResourceLimitGroupAction.java index cfe13550e548e..a77cc3c5a6505 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportUpdateResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportUpdateResourceLimitGroupAction.java @@ -23,12 +23,13 @@ * * @opensearch.internal */ -public class TransportUpdateResourceLimitGroupAction extends HandledTransportAction { +public class TransportUpdateResourceLimitGroupAction extends HandledTransportAction< + UpdateResourceLimitGroupRequest, + UpdateResourceLimitGroupResponse> { private final ThreadPool threadPool; private final Persistable resourceLimitGroupPersistenceService; - /** * Constructor for TransportUpdateResourceLimitGroupAction * @@ -39,21 +40,33 @@ public class TransportUpdateResourceLimitGroupAction extends HandledTransportAct * @param resourceLimitGroupPersistenceService - a {@link Persistable} object */ @Inject - public TransportUpdateResourceLimitGroupAction - (String actionName, - TransportService transportService, - ActionFilters actionFilters, - ThreadPool threadPool, - Persistable resourceLimitGroupPersistenceService - ) { + public TransportUpdateResourceLimitGroupAction( + String actionName, + TransportService transportService, + ActionFilters actionFilters, + ThreadPool threadPool, + Persistable resourceLimitGroupPersistenceService + ) { super(UpdateResourceLimitGroupAction.NAME, transportService, actionFilters, UpdateResourceLimitGroupRequest::new); this.threadPool = threadPool; this.resourceLimitGroupPersistenceService = resourceLimitGroupPersistenceService; } @Override - protected void doExecute(Task task, UpdateResourceLimitGroupRequest request, ActionListener listener) { - ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(request.getUpdatingName(), request.getResourceLimits(), request.getEnforcement()); - threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> resourceLimitGroupPersistenceService.update(resourceLimitGroup, request.getExistingName(), listener)); + protected void doExecute( + Task task, + UpdateResourceLimitGroupRequest request, + ActionListener listener + ) { + ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup( + request.getName(), + null, + request.getResourceLimits(), + request.getEnforcement(), + null, + request.getUpdatedAt() + ); + threadPool.executor(ThreadPool.Names.GENERIC) + .execute(() -> resourceLimitGroupPersistenceService.update(resourceLimitGroup, listener)); } } diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequest.java index d6e489709ff2d..c75c1d6c57dab 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequest.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequest.java @@ -26,17 +26,17 @@ * @opensearch.internal */ public class UpdateResourceLimitGroupRequest extends ActionRequest implements Writeable.Reader { - String existingName; - String updatingName; + String name; List resourceLimits; String enforcement; + String updatedAt; /** * Default constructor for UpdateResourceLimitGroupRequest - * @param existingName - existing name for Resource Limit Group + * @param name - name for Resource Limit Group */ - public UpdateResourceLimitGroupRequest(String existingName) { - this.existingName = existingName; + public UpdateResourceLimitGroupRequest(String name) { + this.name = name; } /** @@ -44,9 +44,10 @@ public UpdateResourceLimitGroupRequest(String existingName) { * @param resourceLimitGroup - A {@link ResourceLimitGroup} object */ public UpdateResourceLimitGroupRequest(ResourceLimitGroup resourceLimitGroup) { - this.updatingName = resourceLimitGroup.getName(); + this.name = resourceLimitGroup.getName(); this.resourceLimits = resourceLimitGroup.getResourceLimits(); this.enforcement = resourceLimitGroup.getEnforcement(); + this.updatedAt = resourceLimitGroup.getUpdatedAt(); } /** @@ -55,12 +56,12 @@ public UpdateResourceLimitGroupRequest(ResourceLimitGroup resourceLimitGroup) { */ public UpdateResourceLimitGroupRequest(StreamInput in) throws IOException { super(in); - existingName = in.readOptionalString(); - updatingName = in.readOptionalString(); + name = in.readString(); if (in.readBoolean()) { resourceLimits = in.readList(ResourceLimit::new); } enforcement = in.readOptionalString(); + updatedAt = in.readString(); } @Override @@ -83,33 +84,18 @@ public ActionRequestValidationException validate() { } /** - * existingName getter + * name getter */ - public String getExistingName() { - return existingName; + public String getName() { + return name; } /** - * existingName setter - * @param existingName - name to be set + * name setter + * @param name - name to be set */ - public void setExistingName(String existingName) { - this.existingName = existingName; - } - - /** - * updatingName getter - */ - public String getUpdatingName() { - return updatingName; - } - - /** - * updatingName setter - * @param updatingName - name to be set - */ - public void setUpdatingName(String updatingName) { - this.updatingName = updatingName; + public void setName(String name) { + this.name = name; } /** @@ -142,11 +128,25 @@ public void setEnforcement(String enforcement) { this.enforcement = enforcement; } + /** + * updatedAt getter + */ + public String getUpdatedAt() { + return updatedAt; + } + + /** + * updatedAt setter + * @param updatedAt - updatedAt to be set + */ + public void setUpdatedAt(String updatedAt) { + this.updatedAt = updatedAt; + } + @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); - out.writeOptionalString(existingName); - out.writeOptionalString(updatingName); + out.writeString(name); if (resourceLimits == null || resourceLimits.isEmpty()) { out.writeBoolean(false); } else { @@ -154,5 +154,6 @@ public void writeTo(StreamOutput out) throws IOException { out.writeList(resourceLimits); } out.writeOptionalString(enforcement); + out.writeString(updatedAt); } } diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestCreateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestCreateResourceLimitGroupAction.java index 0e8ecc3c1cbe8..17ebb48ca9dc8 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestCreateResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestCreateResourceLimitGroupAction.java @@ -9,9 +9,9 @@ package org.opensearch.plugin.resource_limit_group.rest; import org.opensearch.client.node.NodeClient; -import org.opensearch.core.xcontent.XContentParser; import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.core.xcontent.XContentParser; import org.opensearch.plugin.resource_limit_group.CreateResourceLimitGroupAction; import org.opensearch.plugin.resource_limit_group.CreateResourceLimitGroupRequest; import org.opensearch.plugin.resource_limit_group.CreateResourceLimitGroupResponse; @@ -38,7 +38,7 @@ public class RestCreateResourceLimitGroupAction extends BaseRestHandler { /** * Constructor for RestCreateResourceLimitGroupAction */ - public RestCreateResourceLimitGroupAction(){} + public RestCreateResourceLimitGroupAction() {} @Override public String getName() { @@ -50,24 +50,28 @@ public String getName() { */ @Override public List routes() { - return List.of( - new Route(POST, "_resource_limit_group/"), - new Route(PUT, "_resource_limit_group/") - ); + return List.of(new Route(POST, "_resource_limit_group/"), new Route(PUT, "_resource_limit_group/")); } @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { CreateResourceLimitGroupRequest createResourceLimitGroupRequest = new CreateResourceLimitGroupRequest(); request.applyContentParser((parser) -> parseRestRequest(createResourceLimitGroupRequest, parser)); - return channel -> client.execute(CreateResourceLimitGroupAction.INSTANCE, createResourceLimitGroupRequest, createResourceLimitGroupResponse(channel)); + return channel -> client.execute( + CreateResourceLimitGroupAction.INSTANCE, + createResourceLimitGroupRequest, + createResourceLimitGroupResponse(channel) + ); } private void parseRestRequest(CreateResourceLimitGroupRequest request, XContentParser parser) throws IOException { final CreateResourceLimitGroupRequest createResourceLimitGroupRequest = CreateResourceLimitGroupRequest.fromXContent(parser); request.setName(createResourceLimitGroupRequest.getName()); + request.setUUID(createResourceLimitGroupRequest.getUUID()); request.setResourceLimits(createResourceLimitGroupRequest.getResourceLimits()); request.setEnforcement(createResourceLimitGroupRequest.getEnforcement()); + request.setCreatedAt(createResourceLimitGroupRequest.getCreatedAt()); + request.setUpdatedAt(createResourceLimitGroupRequest.getUpdatedAt()); } private RestResponseListener createResourceLimitGroupResponse(final RestChannel channel) { diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestDeleteResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestDeleteResourceLimitGroupAction.java index b47225badb9ac..558e4fa796ecd 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestDeleteResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestDeleteResourceLimitGroupAction.java @@ -36,7 +36,7 @@ public class RestDeleteResourceLimitGroupAction extends BaseRestHandler { /** * Constructor for RestDeleteResourceLimitGroupAction */ - public RestDeleteResourceLimitGroupAction(){} + public RestDeleteResourceLimitGroupAction() {} @Override public String getName() { @@ -48,17 +48,18 @@ public String getName() { */ @Override public List routes() { - return List.of( - new Route(DELETE, "_resource_limit_group/{name}"), - new Route(DELETE, "_resource_limit_group/") - ); + return List.of(new Route(DELETE, "_resource_limit_group/{name}"), new Route(DELETE, "_resource_limit_group/")); } @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { String name = request.param("name"); DeleteResourceLimitGroupRequest deleteResourceLimitGroupRequest = new DeleteResourceLimitGroupRequest(name); - return channel -> client.execute(DeleteResourceLimitGroupAction.INSTANCE, deleteResourceLimitGroupRequest, deleteResourceLimitGroupResponse(channel)); + return channel -> client.execute( + DeleteResourceLimitGroupAction.INSTANCE, + deleteResourceLimitGroupRequest, + deleteResourceLimitGroupResponse(channel) + ); } private RestResponseListener deleteResourceLimitGroupResponse(final RestChannel channel) { diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestGetResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestGetResourceLimitGroupAction.java index ffc57d5b95098..5d53e970970ae 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestGetResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestGetResourceLimitGroupAction.java @@ -36,7 +36,7 @@ public class RestGetResourceLimitGroupAction extends BaseRestHandler { /** * Constructor for RestGetResourceLimitGroupAction */ - public RestGetResourceLimitGroupAction(){} + public RestGetResourceLimitGroupAction() {} @Override public String getName() { @@ -48,17 +48,18 @@ public String getName() { */ @Override public List routes() { - return List.of( - new Route(GET, "_resource_limit_group/{name}"), - new Route(GET, "_resource_limit_group/") - ); + return List.of(new Route(GET, "_resource_limit_group/{name}"), new Route(GET, "_resource_limit_group/")); } @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { String name = request.param("name"); GetResourceLimitGroupRequest getResourceLimitGroupRequest = new GetResourceLimitGroupRequest(name); - return channel -> client.execute(GetResourceLimitGroupAction.INSTANCE, getResourceLimitGroupRequest, getResourceLimitGroupResponse(channel)); + return channel -> client.execute( + GetResourceLimitGroupAction.INSTANCE, + getResourceLimitGroupRequest, + getResourceLimitGroupResponse(channel) + ); } private RestResponseListener getResourceLimitGroupResponse(final RestChannel channel) { diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestUpdateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestUpdateResourceLimitGroupAction.java index 948c224e79637..d4de15043a8b1 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestUpdateResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestUpdateResourceLimitGroupAction.java @@ -38,7 +38,7 @@ public class RestUpdateResourceLimitGroupAction extends BaseRestHandler { /** * Constructor for RestUpdateResourceLimitGroupAction */ - public RestUpdateResourceLimitGroupAction(){} + public RestUpdateResourceLimitGroupAction() {} @Override public String getName() { @@ -50,25 +50,26 @@ public String getName() { */ @Override public List routes() { - return List.of( - new Route(POST, "_resource_limit_group/{name}"), - new Route(PUT, "_resource_limit_group/{name}") - ); + return List.of(new Route(POST, "_resource_limit_group/{name}"), new Route(PUT, "_resource_limit_group/{name}")); } @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { String name = request.param("name"); UpdateResourceLimitGroupRequest updateResourceLimitGroupRequest = new UpdateResourceLimitGroupRequest(name); - request.applyContentParser((parser) -> { parseRestRequest(updateResourceLimitGroupRequest, parser); }); - return channel -> client.execute(UpdateResourceLimitGroupAction.INSTANCE, updateResourceLimitGroupRequest, updateResourceLimitGroupResponse(channel)); + request.applyContentParser((parser) -> parseRestRequest(updateResourceLimitGroupRequest, parser)); + return channel -> client.execute( + UpdateResourceLimitGroupAction.INSTANCE, + updateResourceLimitGroupRequest, + updateResourceLimitGroupResponse(channel) + ); } private void parseRestRequest(UpdateResourceLimitGroupRequest request, XContentParser parser) throws IOException { final UpdateResourceLimitGroupRequest updateResourceLimitGroupRequest = UpdateResourceLimitGroupRequest.fromXContent(parser); - request.setUpdatingName(updateResourceLimitGroupRequest.getUpdatingName()); request.setResourceLimits(updateResourceLimitGroupRequest.getResourceLimits()); request.setEnforcement(updateResourceLimitGroupRequest.getEnforcement()); + request.setUpdatedAt(updateResourceLimitGroupRequest.getUpdatedAt()); } private RestResponseListener updateResourceLimitGroupResponse(final RestChannel channel) { diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/Persistable.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/Persistable.java index 3f128081d1a3d..b5758ba3ec627 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/Persistable.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/Persistable.java @@ -31,10 +31,9 @@ public interface Persistable { /** * update the resource limit group in a durable storage * @param resourceLimitGroup - * @param existingName * @param listener */ - void update(T resourceLimitGroup, String existingName, ActionListener listener); + void update(T resourceLimitGroup, ActionListener listener); /** * fetch the resource limit group in a durable storage diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceService.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceService.java index 2f4432592c8a1..8eb3821a2cd5f 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceService.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceService.java @@ -28,7 +28,10 @@ import org.opensearch.plugin.resource_limit_group.GetResourceLimitGroupResponse; import org.opensearch.plugin.resource_limit_group.UpdateResourceLimitGroupResponse; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.DoubleAdder; import java.util.stream.Collectors; @@ -61,11 +64,24 @@ public class ResourceLimitGroupPersistenceService implements Persistable listener) { + public void update(ResourceLimitGroup resourceLimitGroup, ActionListener listener) { ClusterState currentState = clusterService.state(); - ResourceLimitGroup existingGroup; Map currentGroupsMap = currentState.metadata().resourceLimitGroups(); + List currentGroupsList = new ArrayList<>(currentGroupsMap.values()); + String name = resourceLimitGroup.getName(); - if (currentGroupsMap.containsKey(existingName)) { - existingGroup = currentGroupsMap.get(existingName); - } else { - logger.warn("No Resource Limit Group exists with the provided name: {}", existingName); - Exception e = new RuntimeException("No Resource Limit Group exists with the provided name: " + existingName); + if (!currentGroupsMap.containsKey(name)) { + logger.warn("No Resource Limit Group exists with the provided name: {}", name); + Exception e = new RuntimeException("No Resource Limit Group exists with the provided name: " + name); UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(); response.setRestStatus(RestStatus.NOT_FOUND); listener.onFailure(e); return; } - if (resourceLimitGroup.getName() != null && currentGroupsMap.containsKey(resourceLimitGroup.getName())) { - logger.warn("Resource Limit Group already exists with the updated name: {}", resourceLimitGroup.getName()); - Exception e = new RuntimeException("Resource Limit Group already exists with the provided name: " + resourceLimitGroup.getName()); - UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(); - response.setRestStatus(RestStatus.CONFLICT); - listener.onFailure(e); - return; - } - + // check if there's any resource allocation that exceed limit of 1.0 if (resourceLimitGroup.getResourceLimits() != null) { String resourceNameWithThresholdExceeded = ""; - for (ResourceLimit rl: resourceLimitGroup.getResourceLimits()) { - String currResourceName = rl.getResourceName(); - double existingUsage = 0; - for (ResourceLimitGroup group: new ArrayList<>(currentGroupsMap.values())) { - if (!group.getName().equals(existingName)) { - existingUsage += getResourceLimitValue(currResourceName, group); - } - } - double newGroupUsage = getResourceLimitValue(currResourceName, resourceLimitGroup); - if (!inflightResourceLimitValues.containsKey(currResourceName)) { - inflightResourceLimitValues.put(currResourceName, new DoubleAdder()); - } - inflightResourceLimitValues.get(currResourceName).add(newGroupUsage); - double totalUsage = existingUsage + inflightResourceLimitValues.get(currResourceName).doubleValue(); + for (ResourceLimit resourceLimit : resourceLimitGroup.getResourceLimits()) { + String resourceName = resourceLimit.getResourceName(); + double existingUsage = calculateExistingUsage(resourceName, currentGroupsList, name); + double newGroupUsage = getResourceLimitValue(resourceName, resourceLimitGroup); + inflightResourceLimitValues.computeIfAbsent(resourceName, k -> new DoubleAdder()).add(newGroupUsage); + double totalUsage = existingUsage + inflightResourceLimitValues.get(resourceName).doubleValue(); if (totalUsage > 1) { - resourceNameWithThresholdExceeded = currResourceName; + resourceNameWithThresholdExceeded = resourceName; } } if (!resourceNameWithThresholdExceeded.isEmpty()) { - for (ResourceLimit rl: resourceLimitGroup.getResourceLimits()) { - String currResourceName = rl.getResourceName(); - inflightResourceLimitValues.get(currResourceName).add(-getResourceLimitValue(currResourceName, resourceLimitGroup)); - } - Exception e = new RuntimeException("Total resource allocation for " + resourceNameWithThresholdExceeded + " will go above the max limit of 1.0"); + restoreInflightValues(resourceLimitGroup); + Exception e = new RuntimeException( + "Total resource allocation for " + resourceNameWithThresholdExceeded + " will go above the max limit of 1.0" + ); UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(); response.setRestStatus(RestStatus.CONFLICT); listener.onFailure(e); @@ -149,24 +147,30 @@ public void update(ResourceLimitGroup resourceLimitGroup, String existingName, A } // build the resource limit group with updated fields - String name = resourceLimitGroup.getName() == null ? existingGroup.getName() : resourceLimitGroup.getName(); + ResourceLimitGroup existingGroup = currentGroupsMap.get(name); + String uuid = existingGroup.getUUID(); + String createdAt = existingGroup.getCreatedAt(); + String updatedAt = resourceLimitGroup.getUpdatedAt(); List resourceLimit; if (resourceLimitGroup.getResourceLimits() == null || resourceLimitGroup.getResourceLimits().isEmpty()) { resourceLimit = existingGroup.getResourceLimits(); } else { resourceLimit = new ArrayList<>(existingGroup.getResourceLimits()); - Map resourceLimitMap = resourceLimitGroup.getResourceLimits().stream() + Map resourceLimitMap = resourceLimitGroup.getResourceLimits() + .stream() .collect(Collectors.toMap(ResourceLimit::getResourceName, ResourceLimit::getValue)); - for (ResourceLimit rl: resourceLimit) { + for (ResourceLimit rl : resourceLimit) { String currResourceName = rl.getResourceName(); if (resourceLimitMap.containsKey(currResourceName)) { rl.setValue(resourceLimitMap.get(currResourceName)); } } } - String enforcement = resourceLimitGroup.getEnforcement() == null ? existingGroup.getEnforcement() : resourceLimitGroup.getEnforcement(); + String enforcement = resourceLimitGroup.getEnforcement() == null + ? existingGroup.getEnforcement() + : resourceLimitGroup.getEnforcement(); - ResourceLimitGroup updatedGroup = new ResourceLimitGroup(name, resourceLimit, enforcement); + ResourceLimitGroup updatedGroup = new ResourceLimitGroup(name, uuid, resourceLimit, enforcement, createdAt, updatedAt); updateInClusterStateMetadata(existingGroup, resourceLimitGroup, updatedGroup, listener); } @@ -255,35 +259,35 @@ ClusterState saveResourceLimitGroupInClusterState(final ResourceLimitGroup resou } final List previousGroups = new ArrayList<>(metadata.resourceLimitGroups().values()); + // check if there's any resource allocation that exceed limit of 1.0 String resourceNameWithThresholdExceeded = ""; - for (ResourceLimit rl: resourceLimitGroup.getResourceLimits()) { - String currResourceName = rl.getResourceName(); - double existingUsage = 0; - for (ResourceLimitGroup existingGroup: previousGroups) { - existingUsage += getResourceLimitValue(currResourceName, existingGroup); - } - double newGroupUsage = getResourceLimitValue(currResourceName, resourceLimitGroup); - if (!inflightResourceLimitValues.containsKey(currResourceName)) { - inflightResourceLimitValues.put(currResourceName, new DoubleAdder()); - } - inflightResourceLimitValues.get(currResourceName).add(newGroupUsage); - double totalUsage = existingUsage + inflightResourceLimitValues.get(currResourceName).doubleValue(); + for (ResourceLimit resourceLimit : resourceLimitGroup.getResourceLimits()) { + String resourceName = resourceLimit.getResourceName(); + double existingUsage = calculateExistingUsage(resourceName, previousGroups, groupName); + double newGroupUsage = getResourceLimitValue(resourceName, resourceLimitGroup); + inflightResourceLimitValues.computeIfAbsent(resourceName, k -> new DoubleAdder()).add(newGroupUsage); + double totalUsage = existingUsage + inflightResourceLimitValues.get(resourceName).doubleValue(); if (totalUsage > 1) { - resourceNameWithThresholdExceeded = currResourceName; + resourceNameWithThresholdExceeded = resourceName; } } - if (inflightCreateResourceLimitGroupRequestCount.incrementAndGet() + previousGroups.size() > maxResourceLimitGroupCount) { - restoreInflightValues(resourceLimitGroup); - logger.error("{} value exceeded its assigned limit of {}", RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME, maxResourceLimitGroupCount); - throw new RuntimeException("Can't create more than " + maxResourceLimitGroupCount + " Resource Limit Groups in the system"); - } + restoreInflightValues(resourceLimitGroup); if (!resourceNameWithThresholdExceeded.isEmpty()) { - restoreInflightValues(resourceLimitGroup); logger.error("Total resource allocation for {} will go above the max limit of 1.0", resourceNameWithThresholdExceeded); - throw new RuntimeException("Total resource allocation for " + resourceNameWithThresholdExceeded+ " will go above the max limit of 1.0"); + throw new RuntimeException( + "Total resource allocation for " + resourceNameWithThresholdExceeded + " will go above the max limit of 1.0" + ); + } + + // check if group count exceed max + boolean groupCountExceeded = inflightCreateResourceLimitGroupRequestCount.incrementAndGet() + previousGroups + .size() > maxResourceLimitGroupCount; + inflightCreateResourceLimitGroupRequestCount.decrementAndGet(); + if (groupCountExceeded) { + logger.error("{} value exceeded its assigned limit of {}", RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME, maxResourceLimitGroupCount); + throw new RuntimeException("Can't create more than " + maxResourceLimitGroupCount + " Resource Limit Groups in the system"); } - restoreInflightValues(resourceLimitGroup); return ClusterState.builder(currentClusterState).metadata(Metadata.builder(metadata).put(resourceLimitGroup).build()).build(); } @@ -292,19 +296,39 @@ ClusterState saveResourceLimitGroupInClusterState(final ResourceLimitGroup resou * @param resourceLimitGroup - the resource limit group we're currently creating */ void restoreInflightValues(ResourceLimitGroup resourceLimitGroup) { - inflightCreateResourceLimitGroupRequestCount.decrementAndGet(); - for (ResourceLimit rl: resourceLimitGroup.getResourceLimits()) { + for (ResourceLimit rl : resourceLimitGroup.getResourceLimits()) { String currResourceName = rl.getResourceName(); inflightResourceLimitValues.get(currResourceName).add(-getResourceLimitValue(currResourceName, resourceLimitGroup)); } } + /** + * This method calculates the existing total usage of the resource (except the group that we're updating here) + * @param resourceName - the resource name we're calculating + * @param groupsList - existing resource limit groups + * @param groupName - the resource limit group name we're updating + */ + private double calculateExistingUsage(String resourceName, List groupsList, String groupName) { + double existingUsage = 0; + for (ResourceLimitGroup group : groupsList) { + if (!group.getName().equals(groupName)) { + existingUsage += getResourceLimitValue(resourceName, group); + } + } + return existingUsage; + } + /** * Modify cluster state to update the Resource Limit Group * @param existingGroup {@link ResourceLimitGroup} - the existing resource limit group that we want to update * @param updatedGroup {@link ResourceLimitGroup} - the resource limit group we're updating to */ - void updateInClusterStateMetadata(ResourceLimitGroup existingGroup, ResourceLimitGroup toUpdateGroup, ResourceLimitGroup updatedGroup, ActionListener listener) { + void updateInClusterStateMetadata( + ResourceLimitGroup existingGroup, + ResourceLimitGroup toUpdateGroup, + ResourceLimitGroup updatedGroup, + ActionListener listener + ) { clusterService.submitStateUpdateTask(SOURCE, new ClusterStateUpdateTask(Priority.URGENT) { @Override public ClusterState execute(ClusterState currentState) { @@ -327,7 +351,7 @@ public void onFailure(String source, Exception e) { @Override public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { if (toUpdateGroup.getResourceLimits() != null) { - for (ResourceLimit rl: toUpdateGroup.getResourceLimits()) { + for (ResourceLimit rl : toUpdateGroup.getResourceLimits()) { String currResourceName = rl.getResourceName(); inflightResourceLimitValues.get(currResourceName).add(-getResourceLimitValue(currResourceName, toUpdateGroup)); } @@ -345,15 +369,14 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS * @param updatedGroup {@link ResourceLimitGroup} - the resource limit group we're updating to * @param currentState - current cluster state */ - public ClusterState updateResourceLimitGroupInClusterState(ResourceLimitGroup existingGroup, ResourceLimitGroup updatedGroup, ClusterState currentState) { + public ClusterState updateResourceLimitGroupInClusterState( + ResourceLimitGroup existingGroup, + ResourceLimitGroup updatedGroup, + ClusterState currentState + ) { final Metadata metadata = currentState.metadata(); - return ClusterState - .builder(currentState) - .metadata(Metadata - .builder(metadata) - .removeResourceLimitGroup(existingGroup.getName()) - .put(updatedGroup).build() - ) + return ClusterState.builder(currentState) + .metadata(Metadata.builder(metadata).removeResourceLimitGroup(existingGroup.getName()).put(updatedGroup).build()) .build(); } @@ -386,7 +409,7 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS final Map oldGroupsMap = oldState.metadata().resourceLimitGroups(); final Map newGroupssMap = newState.metadata().resourceLimitGroups(); List deletedGroups = new ArrayList<>(); - for (String name: oldGroupsMap.keySet()) { + for (String name : oldGroupsMap.keySet()) { if (!newGroupssMap.containsKey(name)) { deletedGroups.add(oldGroupsMap.get(name)); } @@ -406,7 +429,8 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS ClusterState deleteResourceLimitGroupInClusterState(final String name, final ClusterState currentClusterState) { final Metadata metadata = currentClusterState.metadata(); final Map previousGroups = metadata.resourceLimitGroups(); - Map resultGroups = new HashMap<>(previousGroups);; + Map resultGroups = new HashMap<>(previousGroups); + ; if (name == null || name.equals("")) { resultGroups = new HashMap<>(); } else { @@ -416,8 +440,10 @@ ClusterState deleteResourceLimitGroupInClusterState(final String name, final Clu throw new RuntimeException("No Resource Limit Group exists with the provided name: " + name); } resultGroups.remove(name); - } - return ClusterState.builder(currentClusterState).metadata(Metadata.builder(metadata).resourceLimitGroups(resultGroups).build()).build(); + } + return ClusterState.builder(currentClusterState) + .metadata(Metadata.builder(metadata).resourceLimitGroups(resultGroups).build()) + .build(); } List getFromClusterStateMetadata(String name, ClusterState currentState) { diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequestTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequestTests.java index e0626e6fd9834..c9f1c7bc3f5d5 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequestTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequestTests.java @@ -9,23 +9,18 @@ package org.opensearch.plugin.resource_limit_group; import org.opensearch.common.io.stream.BytesStreamOutput; -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.test.OpenSearchTestCase; import java.io.IOException; -import java.util.List; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_ONE; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.MONITOR; import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimits; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupOne; public class CreateResourceLimitGroupRequestTests extends OpenSearchTestCase { public void testSerialization() throws IOException { - ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(NAME_ONE, List.of(new ResourceLimit("jvm", 0.4)), MONITOR); - CreateResourceLimitGroupRequest request = new CreateResourceLimitGroupRequest(resourceLimitGroup); + CreateResourceLimitGroupRequest request = new CreateResourceLimitGroupRequest(resourceLimitGroupOne); BytesStreamOutput out = new BytesStreamOutput(); request.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); @@ -34,5 +29,7 @@ public void testSerialization() throws IOException { assertEquals(request.getResourceLimits().size(), otherRequest.getResourceLimits().size()); assertEquals(request.getEnforcement(), otherRequest.getEnforcement()); compareResourceLimits(request.getResourceLimits(), otherRequest.getResourceLimits()); + assertEquals(request.getCreatedAt(), otherRequest.getCreatedAt()); + assertEquals(request.getUpdatedAt(), otherRequest.getUpdatedAt()); } } diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponseTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponseTests.java index 7b0e6d9222c6a..8db619cb7e0a9 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponseTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponseTests.java @@ -9,7 +9,6 @@ package org.opensearch.plugin.resource_limit_group; import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.test.OpenSearchTestCase; @@ -17,15 +16,13 @@ import java.io.IOException; import java.util.List; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_ONE; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.MONITOR; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimits; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimitGroups; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupOne; public class CreateResourceLimitGroupResponseTests extends OpenSearchTestCase { public void testSerialization() throws IOException { - ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(NAME_ONE, List.of(new ResourceLimit("jvm", 0.4)), MONITOR); - CreateResourceLimitGroupResponse response = new CreateResourceLimitGroupResponse(resourceLimitGroup); + CreateResourceLimitGroupResponse response = new CreateResourceLimitGroupResponse(resourceLimitGroupOne); BytesStreamOutput out = new BytesStreamOutput(); response.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); @@ -33,9 +30,6 @@ public void testSerialization() throws IOException { assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); ResourceLimitGroup responseGroup = response.getResourceLimitGroup(); ResourceLimitGroup otherResponseGroup = otherResponse.getResourceLimitGroup(); - assertEquals(responseGroup.getName(), otherResponseGroup.getName()); - assertEquals(responseGroup.getResourceLimits().size(), otherResponseGroup.getResourceLimits().size()); - assertEquals(responseGroup.getEnforcement(), otherResponseGroup.getEnforcement()); - compareResourceLimits(responseGroup.getResourceLimits(), otherResponseGroup.getResourceLimits()); + compareResourceLimitGroups(List.of(responseGroup), List.of(otherResponseGroup)); } } diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponseTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponseTests.java index 25e7b33101b79..81722501714b8 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponseTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponseTests.java @@ -17,38 +17,34 @@ import java.util.ArrayList; import java.util.List; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.*; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimitGroups; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupList; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupOne; public class DeleteResourceLimitGroupResponseTests extends OpenSearchTestCase { public void testSerializationSingleResourceLimitGroup() throws IOException { - // create a list of sandboxes as the response List list = List.of(resourceLimitGroupOne); DeleteResourceLimitGroupResponse response = new DeleteResourceLimitGroupResponse(list); assertEquals(response.getResourceLimitGroups(), list); - // serialize the response BytesStreamOutput out = new BytesStreamOutput(); response.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); - // deserialize the response and check whether each field equals the original list of sandbox DeleteResourceLimitGroupResponse otherResponse = new DeleteResourceLimitGroupResponse(streamInput); assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); compareResourceLimitGroups(response.getResourceLimitGroups(), otherResponse.getResourceLimitGroups()); } public void testSerializationMultipleResourceLimitGroup() throws IOException { - // create a list of sandboxes as the response DeleteResourceLimitGroupResponse response = new DeleteResourceLimitGroupResponse(resourceLimitGroupList); assertEquals(response.getResourceLimitGroups(), resourceLimitGroupList); - // serialize the response BytesStreamOutput out = new BytesStreamOutput(); response.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); - // deserialize the response and check whether each field equals the original list of sandbox DeleteResourceLimitGroupResponse otherResponse = new DeleteResourceLimitGroupResponse(streamInput); assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); assertEquals(2, otherResponse.getResourceLimitGroups().size()); @@ -56,17 +52,14 @@ public void testSerializationMultipleResourceLimitGroup() throws IOException { } public void testSerializationNull() throws IOException { - // create a list of sandboxes (empty list) as the response List list = new ArrayList<>(); DeleteResourceLimitGroupResponse response = new DeleteResourceLimitGroupResponse(list); assertEquals(response.getResourceLimitGroups(), list); - // serialize the response BytesStreamOutput out = new BytesStreamOutput(); response.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); - // deserialize the response and check whether each field equals the original list of sandbox DeleteResourceLimitGroupResponse otherResponse = new DeleteResourceLimitGroupResponse(streamInput); assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); assertEquals(0, otherResponse.getResourceLimitGroups().size()); diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponseTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponseTests.java index cd8e3afc3cad3..e705e0e76c1d2 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponseTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponseTests.java @@ -9,7 +9,6 @@ package org.opensearch.plugin.resource_limit_group; import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.test.OpenSearchTestCase; @@ -18,40 +17,35 @@ import java.util.ArrayList; import java.util.List; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.*; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimitGroups; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupList; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupOne; public class GetResourceLimitGroupResponseTests extends OpenSearchTestCase { public void testSerializationSingleResourceLimitGroup() throws IOException { - // create a list of sandboxes as the response - ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(NAME_ONE, List.of(new ResourceLimit("jvm", 0.4)), MONITOR); List list = new ArrayList<>(); - list.add(resourceLimitGroup); + list.add(resourceLimitGroupOne); GetResourceLimitGroupResponse response = new GetResourceLimitGroupResponse(list); assertEquals(response.getResourceLimitGroups(), list); - // serialize the response BytesStreamOutput out = new BytesStreamOutput(); response.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); - // deserialize the response and check whether each field equals the original list of sandbox GetResourceLimitGroupResponse otherResponse = new GetResourceLimitGroupResponse(streamInput); assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); compareResourceLimitGroups(response.getResourceLimitGroups(), otherResponse.getResourceLimitGroups()); } public void testSerializationMultipleResourceLimitGroup() throws IOException { - // create a list of sandboxes as the response GetResourceLimitGroupResponse response = new GetResourceLimitGroupResponse(resourceLimitGroupList); assertEquals(response.getResourceLimitGroups(), resourceLimitGroupList); - // serialize the response BytesStreamOutput out = new BytesStreamOutput(); response.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); - // deserialize the response and check whether each field equals the original list of sandbox GetResourceLimitGroupResponse otherResponse = new GetResourceLimitGroupResponse(streamInput); assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); assertEquals(2, otherResponse.getResourceLimitGroups().size()); @@ -59,17 +53,14 @@ public void testSerializationMultipleResourceLimitGroup() throws IOException { } public void testSerializationNull() throws IOException { - // create a list of sandboxes (empty list) as the response List list = new ArrayList<>(); GetResourceLimitGroupResponse response = new GetResourceLimitGroupResponse(list); assertEquals(response.getResourceLimitGroups(), list); - // serialize the response BytesStreamOutput out = new BytesStreamOutput(); response.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); - // deserialize the response and check whether each field equals the original list of sandbox GetResourceLimitGroupResponse otherResponse = new GetResourceLimitGroupResponse(streamInput); assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); assertEquals(0, otherResponse.getResourceLimitGroups().size()); diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupTestUtils.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupTestUtils.java index 85af6152db1b8..574640ef5b16d 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupTestUtils.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupTestUtils.java @@ -17,7 +17,6 @@ import org.opensearch.common.settings.ClusterSettings; import org.opensearch.common.settings.Settings; import org.opensearch.plugin.resource_limit_group.service.ResourceLimitGroupPersistenceService; -import org.opensearch.test.OpenSearchTestCase; import org.opensearch.threadpool.ThreadPool; import java.util.HashMap; @@ -25,29 +24,51 @@ import java.util.Map; import java.util.stream.Collectors; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; -public class ResourceLimitGroupTestUtils extends OpenSearchTestCase { +public class ResourceLimitGroupTestUtils { public static final String SANDBOX_MAX_SETTING_NAME = "node.sandbox.max_count"; public static final String NAME_ONE = "sandbox_one"; public static final String NAME_TWO = "sandbox_two"; + public static final String UUID_ONE = "AgfUO5Ja9yfsYlONlYi3TQ=="; + public static final String UUID_TWO = "G5iIqHy4g7eK1qIAAAAIH53=1"; public static final String NAME_NONE_EXISTED = "sandbox_none_existed"; public static final String MONITOR = "monitor"; - public static final ResourceLimitGroup resourceLimitGroupOne = new ResourceLimitGroup(NAME_ONE, List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.3)), MONITOR); - public static final ResourceLimitGroup resourceLimitGroupTwo = new ResourceLimitGroup(NAME_TWO, List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.6)), MONITOR); + public static final String TIMESTAMP_ONE = "2024-04-26 23:02:21"; + public static final String TIMESTAMP_TWO = "2024-04-21 19:08:06"; + public static final ResourceLimitGroup resourceLimitGroupOne = new ResourceLimitGroup( + NAME_ONE, + UUID_ONE, + List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.3)), + MONITOR, + TIMESTAMP_ONE, + TIMESTAMP_ONE + ); + public static final ResourceLimitGroup resourceLimitGroupTwo = new ResourceLimitGroup( + NAME_TWO, + UUID_TWO, + List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.6)), + MONITOR, + TIMESTAMP_TWO, + TIMESTAMP_TWO + ); public static final Map resourceLimitGroupMap = Map.of( - NAME_ONE, resourceLimitGroupOne, - NAME_TWO, resourceLimitGroupTwo + NAME_ONE, + resourceLimitGroupOne, + NAME_TWO, + resourceLimitGroupTwo ); - public static final List resourceLimitGroupList= List.of(resourceLimitGroupOne, resourceLimitGroupTwo); + public static final List resourceLimitGroupList = List.of(resourceLimitGroupOne, resourceLimitGroupTwo); public static final Metadata metadata = Metadata.builder().resourceLimitGroups(resourceLimitGroupMap).build(); public static final ClusterState clusterState = ClusterState.builder(new ClusterName("_name")).metadata(metadata).build(); public static final Settings settings = Settings.builder().build(); public static final ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); public static final ClusterService clusterService = new ClusterService(settings, clusterSettings, mock(ThreadPool.class)); - public static final ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService = new ResourceLimitGroupPersistenceService(clusterService, settings, clusterSettings); - + public static final ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService = + new ResourceLimitGroupPersistenceService(clusterService, settings, clusterSettings); public static List prepareSandboxPersistenceService(List resourceLimitGroups) { Map resourceLimitGroupMap = new HashMap<>(); @@ -59,7 +80,11 @@ public static List prepareSandboxPersistenceService(List listOne, assertEquals(listOne.size(), listTwo.size()); for (ResourceLimitGroup groupOne : listOne) { String groupOneName = groupOne.getName(); - List groupTwoList = listTwo.stream().filter(sb -> sb.getName().equals(groupOneName)).collect(Collectors.toList()); + List groupTwoList = listTwo.stream() + .filter(sb -> sb.getName().equals(groupOneName)) + .collect(Collectors.toList()); assertEquals(1, groupTwoList.size()); ResourceLimitGroup groupTwo = groupTwoList.get(0); assertEquals(groupOne.getName(), groupTwo.getName()); + assertEquals(groupOne.getUUID(), groupTwo.getUUID()); compareResourceLimits(groupOne.getResourceLimits(), groupTwo.getResourceLimits()); assertEquals(groupOne.getEnforcement(), groupTwo.getEnforcement()); + assertEquals(groupOne.getCreatedAt(), groupTwo.getCreatedAt()); + assertEquals(groupOne.getUpdatedAt(), groupTwo.getUpdatedAt()); } } } - diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequestTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequestTests.java index 5653a6d7a8156..404069310dfe8 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequestTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequestTests.java @@ -18,49 +18,56 @@ import java.util.List; import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_ONE; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.MONITOR; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.TIMESTAMP_ONE; import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimits; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupOne; public class UpdateResourceLimitGroupRequestTests extends OpenSearchTestCase { public void testSerialization() throws IOException { - ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(NAME_ONE, List.of(new ResourceLimit("jvm", 0.4)), MONITOR); - UpdateResourceLimitGroupRequest request = new UpdateResourceLimitGroupRequest(resourceLimitGroup); + UpdateResourceLimitGroupRequest request = new UpdateResourceLimitGroupRequest(resourceLimitGroupOne); BytesStreamOutput out = new BytesStreamOutput(); request.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); UpdateResourceLimitGroupRequest otherRequest = new UpdateResourceLimitGroupRequest(streamInput); - assertEquals(request.getExistingName(), otherRequest.getExistingName()); - assertEquals(request.getUpdatingName(), otherRequest.getUpdatingName()); + assertEquals(request.getName(), otherRequest.getName()); assertEquals(request.getResourceLimits().size(), otherRequest.getResourceLimits().size()); assertEquals(request.getEnforcement(), otherRequest.getEnforcement()); compareResourceLimits(request.getResourceLimits(), otherRequest.getResourceLimits()); + assertEquals(request.getUpdatedAt(), otherRequest.getUpdatedAt()); } public void testSerializationOnlyName() throws IOException { - ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(NAME_ONE, null, null); + ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(NAME_ONE, null, null, null, null, TIMESTAMP_ONE); UpdateResourceLimitGroupRequest request = new UpdateResourceLimitGroupRequest(resourceLimitGroup); BytesStreamOutput out = new BytesStreamOutput(); request.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); UpdateResourceLimitGroupRequest otherRequest = new UpdateResourceLimitGroupRequest(streamInput); - assertEquals(request.getExistingName(), otherRequest.getExistingName()); - assertEquals(request.getUpdatingName(), otherRequest.getUpdatingName()); + assertEquals(request.getName(), otherRequest.getName()); assertEquals(request.getResourceLimits(), otherRequest.getResourceLimits()); assertEquals(request.getEnforcement(), otherRequest.getEnforcement()); + assertEquals(request.getUpdatedAt(), otherRequest.getUpdatedAt()); } public void testSerializationOnlyResourceLimit() throws IOException { - ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(null, List.of(new ResourceLimit("jvm", 0.4)), null); + ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup( + NAME_ONE, + null, + List.of(new ResourceLimit("jvm", 0.4)), + null, + null, + TIMESTAMP_ONE + ); UpdateResourceLimitGroupRequest request = new UpdateResourceLimitGroupRequest(resourceLimitGroup); BytesStreamOutput out = new BytesStreamOutput(); request.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); UpdateResourceLimitGroupRequest otherRequest = new UpdateResourceLimitGroupRequest(streamInput); - assertEquals(request.getExistingName(), otherRequest.getExistingName()); - assertEquals(request.getUpdatingName(), otherRequest.getUpdatingName()); + assertEquals(request.getName(), otherRequest.getName()); assertEquals(request.getResourceLimits().size(), otherRequest.getResourceLimits().size()); compareResourceLimits(request.getResourceLimits(), otherRequest.getResourceLimits()); assertEquals(request.getEnforcement(), otherRequest.getEnforcement()); + assertEquals(request.getUpdatedAt(), otherRequest.getUpdatedAt()); } } diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponseTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponseTests.java index 95e580ea184da..beb7a8502da33 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponseTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponseTests.java @@ -9,7 +9,6 @@ package org.opensearch.plugin.resource_limit_group; import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.test.OpenSearchTestCase; @@ -17,15 +16,13 @@ import java.io.IOException; import java.util.List; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_ONE; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.MONITOR; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimits; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimitGroups; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupOne; public class UpdateResourceLimitGroupResponseTests extends OpenSearchTestCase { public void testSerialization() throws IOException { - ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(NAME_ONE, List.of(new ResourceLimit("jvm", 0.4)), MONITOR); - UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(resourceLimitGroup); + UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(resourceLimitGroupOne); BytesStreamOutput out = new BytesStreamOutput(); response.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); @@ -33,9 +30,6 @@ public void testSerialization() throws IOException { assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); ResourceLimitGroup responseGroup = response.getResourceLimitGroup(); ResourceLimitGroup otherResponseGroup = otherResponse.getResourceLimitGroup(); - assertEquals(responseGroup.getName(), otherResponseGroup.getName()); - assertEquals(responseGroup.getResourceLimits().size(), otherResponseGroup.getResourceLimits().size()); - compareResourceLimits(responseGroup.getResourceLimits(), otherResponseGroup.getResourceLimits()); - assertEquals(responseGroup.getEnforcement(), otherResponseGroup.getEnforcement()); + compareResourceLimitGroups(List.of(responseGroup), List.of(otherResponseGroup)); } } diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceServiceTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceServiceTests.java index 30741b2796b10..53a947db493ad 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceServiceTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceServiceTests.java @@ -24,7 +24,20 @@ import java.util.Set; import java.util.stream.Collectors; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.*; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.MONITOR; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_NONE_EXISTED; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_ONE; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_TWO; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.SANDBOX_MAX_SETTING_NAME; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.TIMESTAMP_ONE; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.clusterState; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimitGroups; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.prepareSandboxPersistenceService; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupList; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupMap; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupOne; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupPersistenceService; +import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupTwo; import static org.mockito.Mockito.mock; public class ResourceLimitGroupPersistenceServiceTests extends OpenSearchTestCase { @@ -33,9 +46,7 @@ public void testGetSingleResourceLimitGroup() { List groups = resourceLimitGroupPersistenceService.getFromClusterStateMetadata(NAME_ONE, clusterState); assertEquals(1, groups.size()); ResourceLimitGroup resourceLimitGroup = groups.get(0); - assertEquals(NAME_ONE, resourceLimitGroup.getName()); - assertEquals(MONITOR, resourceLimitGroup.getEnforcement()); - compareResourceLimits(resourceLimitGroupOne.getResourceLimits(), resourceLimitGroup.getResourceLimits()); + compareResourceLimitGroups(List.of(resourceLimitGroupOne), List.of(resourceLimitGroup)); } public void testGetAllResourceLimitGroups() { @@ -50,7 +61,11 @@ public void testGetAllResourceLimitGroups() { public void testGetZeroResourceLimitGroups() { Settings settings = Settings.builder().build(); ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - ResourceLimitGroupPersistenceService sandboxPersistenceService = new ResourceLimitGroupPersistenceService(mock(ClusterService.class), settings, clusterSettings); + ResourceLimitGroupPersistenceService sandboxPersistenceService = new ResourceLimitGroupPersistenceService( + mock(ClusterService.class), + settings, + clusterSettings + ); List res = sandboxPersistenceService.getFromClusterStateMetadata(NAME_NONE_EXISTED, clusterState); assertEquals(0, res.size()); } @@ -79,29 +94,47 @@ public void testDeleteNonExistedResourceLimitGroup() { public void testUpdateResourceLimitGroupAllFields() { ResourceLimitGroup current = resourceLimitGroupOne; ResourceLimitGroup updated = resourceLimitGroupTwo; - ClusterState newClusterState = resourceLimitGroupPersistenceService.updateResourceLimitGroupInClusterState(current, updated, clusterState); + ClusterState newClusterState = resourceLimitGroupPersistenceService.updateResourceLimitGroupInClusterState( + current, + updated, + clusterState + ); List updatedSandboxes = new ArrayList<>(newClusterState.getMetadata().resourceLimitGroups().values()); assertEquals(1, updatedSandboxes.size()); compareResourceLimitGroups(List.of(updated), updatedSandboxes); } - public void testUpdateResourceLimitGroupNameOnly() { + public void testUpdateResourceLimitGroupResourceLimitOnly() { ResourceLimitGroup current = resourceLimitGroupOne; - String updatedName = NAME_ONE + "_updated"; - ResourceLimitGroup updated = new ResourceLimitGroup(updatedName, List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.3)), MONITOR); - ClusterState newClusterState = resourceLimitGroupPersistenceService.updateResourceLimitGroupInClusterState(current, updated, clusterState); + String updatedTime = "2024-04-28 23:02:21"; + ResourceLimitGroup updated = new ResourceLimitGroup( + NAME_ONE, + resourceLimitGroupOne.getUUID(), + List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.1)), + MONITOR, + TIMESTAMP_ONE, + updatedTime + ); + ClusterState newClusterState = resourceLimitGroupPersistenceService.updateResourceLimitGroupInClusterState( + current, + updated, + clusterState + ); Map updatedSandboxesMap = newClusterState.getMetadata().resourceLimitGroups(); assertEquals(2, updatedSandboxesMap.size()); - assertTrue(updatedSandboxesMap.containsKey(updatedName)); - assertFalse(updatedSandboxesMap.containsKey(NAME_ONE)); - compareResourceLimitGroups(List.of(updated), List.of(updatedSandboxesMap.get(updatedName))); + assertTrue(updatedSandboxesMap.containsKey(NAME_ONE)); + assertTrue(updatedSandboxesMap.containsKey(NAME_TWO)); + compareResourceLimitGroups(List.of(updated), List.of(updatedSandboxesMap.get(NAME_ONE))); } public void testCreateResourceLimitGroup() { List setup = prepareSandboxPersistenceService(new ArrayList<>()); ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService1 = (ResourceLimitGroupPersistenceService) setup.get(0); ClusterState clusterState = (ClusterState) setup.get(1); - ClusterState newClusterState = resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState(resourceLimitGroupOne, clusterState); + ClusterState newClusterState = resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState( + resourceLimitGroupOne, + clusterState + ); Map updatedGroupsMap = newClusterState.getMetadata().resourceLimitGroups(); assertEquals(1, updatedGroupsMap.size()); assertTrue(updatedGroupsMap.containsKey(NAME_ONE)); @@ -112,7 +145,10 @@ public void testCreateAnotherResourceLimitGroup() { List setup = prepareSandboxPersistenceService(List.of(resourceLimitGroupOne)); ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService1 = (ResourceLimitGroupPersistenceService) setup.get(0); ClusterState clusterState = (ClusterState) setup.get(1); - ClusterState newClusterState = resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState(resourceLimitGroupTwo, clusterState); + ClusterState newClusterState = resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState( + resourceLimitGroupTwo, + clusterState + ); Map updatedGroupsMap = newClusterState.getMetadata().resourceLimitGroups(); assertEquals(2, updatedGroupsMap.size()); compareResourceLimitGroups(resourceLimitGroupList, new ArrayList<>(updatedGroupsMap.values())); @@ -122,26 +158,60 @@ public void testCreateResourceLimitGroupDuplicateName() { List setup = prepareSandboxPersistenceService(List.of(resourceLimitGroupOne)); ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService1 = (ResourceLimitGroupPersistenceService) setup.get(0); ClusterState clusterState = (ClusterState) setup.get(1); - ResourceLimitGroup toCreate = new ResourceLimitGroup(NAME_ONE, List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.3)), MONITOR); - assertThrows(RuntimeException.class, () -> resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState(toCreate, clusterState)); + ResourceLimitGroup toCreate = new ResourceLimitGroup( + NAME_ONE, + "W5iIqHyhgi4K1qIAAAAIHw==", + List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.3)), + MONITOR, + null, + null + ); + assertThrows( + RuntimeException.class, + () -> resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState(toCreate, clusterState) + ); } public void testCreateResourceLimitGroupOverflowAllocation() { List setup = prepareSandboxPersistenceService(List.of(resourceLimitGroupTwo)); - ResourceLimitGroup toCreate = new ResourceLimitGroup(NAME_TWO, List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.5)), MONITOR); + ResourceLimitGroup toCreate = new ResourceLimitGroup( + NAME_TWO, + null, + List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.5)), + MONITOR, + null, + null + ); ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService1 = (ResourceLimitGroupPersistenceService) setup.get(0); ClusterState clusterState = (ClusterState) setup.get(1); - assertThrows(RuntimeException.class, () -> resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState(toCreate, clusterState)); + assertThrows( + RuntimeException.class, + () -> resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState(toCreate, clusterState) + ); } public void testCreateResourceLimitGroupOverflowCount() { - ResourceLimitGroup toCreate = new ResourceLimitGroup(NAME_NONE_EXISTED, List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.5)), MONITOR); + ResourceLimitGroup toCreate = new ResourceLimitGroup( + NAME_NONE_EXISTED, + null, + List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.5)), + MONITOR, + null, + null + ); Metadata metadata = Metadata.builder().resourceLimitGroups(resourceLimitGroupMap).build(); Settings settings = Settings.builder().put(SANDBOX_MAX_SETTING_NAME, 2).build(); ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); ClusterService clusterService = new ClusterService(settings, clusterSettings, mock(ThreadPool.class)); ClusterState clusterState = ClusterState.builder(new ClusterName("_name")).metadata(metadata).build(); - ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService1 = new ResourceLimitGroupPersistenceService(clusterService, settings, clusterSettings); - assertThrows(RuntimeException.class, () -> resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState(toCreate, clusterState)); + ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService1 = new ResourceLimitGroupPersistenceService( + clusterService, + settings, + clusterSettings + ); + assertThrows( + RuntimeException.class, + () -> resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState(toCreate, clusterState) + ); } } diff --git a/server/src/main/java/org/opensearch/action/search/AbstractSearchAsyncAction.java b/server/src/main/java/org/opensearch/action/search/AbstractSearchAsyncAction.java index c706189f993a2..0520a4a7aecec 100644 --- a/server/src/main/java/org/opensearch/action/search/AbstractSearchAsyncAction.java +++ b/server/src/main/java/org/opensearch/action/search/AbstractSearchAsyncAction.java @@ -839,9 +839,6 @@ public final ShardSearchRequest buildShardSearchRequest(SearchShardIterator shar // than creating an empty response in the search thread pool. // Note that, we have to disable this shortcut for queries that create a context (scroll and search context). shardRequest.canReturnNullResponseIfMatchNoDocs(hasShardResponse.get() && shardRequest.scroll() == null); - - // Propagate the resource limit group from co-ordinator to data nodes - shardRequest.setResourceLimitGroupId(getTask().getResourceLimitGroupId()); return shardRequest; } diff --git a/server/src/main/java/org/opensearch/action/search/SearchRequest.java b/server/src/main/java/org/opensearch/action/search/SearchRequest.java index 24a349c3964a9..3b8a6937815aa 100644 --- a/server/src/main/java/org/opensearch/action/search/SearchRequest.java +++ b/server/src/main/java/org/opensearch/action/search/SearchRequest.java @@ -122,8 +122,6 @@ public class SearchRequest extends ActionRequest implements IndicesRequest.Repla private Boolean phaseTook = null; - private String resourceLimitGroupId; - public SearchRequest() { this.localClusterAlias = null; this.absoluteStartMillis = DEFAULT_ABSOLUTE_START_MILLIS; @@ -264,10 +262,6 @@ public SearchRequest(StreamInput in) throws IOException { if (in.getVersion().onOrAfter(Version.V_2_12_0)) { phaseTook = in.readOptionalBoolean(); } - - if (in.getVersion().onOrAfter(Version.V_3_0_0)) { - resourceLimitGroupId = in.readOptionalString(); - } } @Override @@ -302,9 +296,6 @@ public void writeTo(StreamOutput out) throws IOException { if (out.getVersion().onOrAfter(Version.V_2_12_0)) { out.writeOptionalBoolean(phaseTook); } - if (out.getVersion().onOrAfter(Version.V_3_0_0)) { - out.writeOptionalString(resourceLimitGroupId); - } } @Override @@ -707,15 +698,6 @@ public String pipeline() { return pipeline; } - public SearchRequest resourceLimitGroupId(String resourceLimitGroupId) { - this.resourceLimitGroupId = resourceLimitGroupId; - return this; - } - - public String resourceLimitGroupId() { - return resourceLimitGroupId; - } - @Override public SearchTask createTask(long id, String type, String action, TaskId parentTaskId, Map headers) { return new SearchTask(id, type, action, this::buildDescription, parentTaskId, headers, cancelAfterTimeInterval); @@ -770,8 +752,7 @@ public boolean equals(Object o) { && ccsMinimizeRoundtrips == that.ccsMinimizeRoundtrips && Objects.equals(cancelAfterTimeInterval, that.cancelAfterTimeInterval) && Objects.equals(pipeline, that.pipeline) - && Objects.equals(phaseTook, that.phaseTook) - && Objects.equals(resourceLimitGroupId, that.resourceLimitGroupId); + && Objects.equals(phaseTook, that.phaseTook); } @Override @@ -793,8 +774,7 @@ public int hashCode() { absoluteStartMillis, ccsMinimizeRoundtrips, cancelAfterTimeInterval, - phaseTook, - resourceLimitGroupId + phaseTook ); } @@ -839,8 +819,6 @@ public String toString() { + pipeline + ", phaseTook=" + phaseTook - + ", resourceLimitGroupId=" - + resourceLimitGroupId + "}"; } } diff --git a/server/src/main/java/org/opensearch/action/search/SearchShardTask.java b/server/src/main/java/org/opensearch/action/search/SearchShardTask.java index 9e78a06aa7da5..dfecf4f462c4d 100644 --- a/server/src/main/java/org/opensearch/action/search/SearchShardTask.java +++ b/server/src/main/java/org/opensearch/action/search/SearchShardTask.java @@ -53,7 +53,6 @@ public class SearchShardTask extends CancellableTask implements SearchBackpressureTask { // generating metadata in a lazy way since source can be quite big private final MemoizedSupplier metadataSupplier; - private String resourceLimitGroupId; public SearchShardTask(long id, String type, String action, String description, TaskId parentTaskId, Map headers) { this(id, type, action, description, parentTaskId, headers, () -> ""); @@ -85,12 +84,4 @@ public boolean supportsResourceTracking() { public boolean shouldCancelChildrenOnCancellation() { return false; } - - public String getResourceLimitGroupId() { - return resourceLimitGroupId; - } - - public void setResourceLimitGroupId(String resourceLimitGroupId) { - this.resourceLimitGroupId = resourceLimitGroupId; - } } diff --git a/server/src/main/java/org/opensearch/action/search/SearchTask.java b/server/src/main/java/org/opensearch/action/search/SearchTask.java index 363f3fde65338..d3c1043c50cce 100644 --- a/server/src/main/java/org/opensearch/action/search/SearchTask.java +++ b/server/src/main/java/org/opensearch/action/search/SearchTask.java @@ -53,7 +53,6 @@ public class SearchTask extends CancellableTask implements SearchBackpressureTas // generating description in a lazy way since source can be quite big private final Supplier descriptionSupplier; private SearchProgressListener progressListener = SearchProgressListener.NOOP; - private String resourceLimitGroupId; public SearchTask( long id, @@ -107,12 +106,4 @@ public final SearchProgressListener getProgressListener() { public boolean shouldCancelChildrenOnCancellation() { return true; } - - public String getResourceLimitGroupId() { - return resourceLimitGroupId; - } - - public void setResourceLimitGroupId(String resourceLimitGroupId) { - this.resourceLimitGroupId = resourceLimitGroupId; - } } diff --git a/server/src/main/java/org/opensearch/action/search/TransportSearchAction.java b/server/src/main/java/org/opensearch/action/search/TransportSearchAction.java index 7ee7292176473..65cfd35489033 100644 --- a/server/src/main/java/org/opensearch/action/search/TransportSearchAction.java +++ b/server/src/main/java/org/opensearch/action/search/TransportSearchAction.java @@ -1104,9 +1104,6 @@ private void executeSearch( concreteLocalIndices, localShardIterators.size() + remoteShardIterators.size() ); - - task.setResourceLimitGroupId(searchRequest.resourceLimitGroupId()); - searchAsyncActionProvider.asyncSearchAction( task, searchRequest, diff --git a/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java b/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java index f3391a684efab..c750ec54316f3 100644 --- a/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java +++ b/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java @@ -10,6 +10,7 @@ import org.opensearch.cluster.AbstractDiffable; import org.opensearch.cluster.Diff; +import org.opensearch.common.UUIDs; import org.opensearch.common.annotation.ExperimentalApi; import org.opensearch.core.ParseField; import org.opensearch.core.common.io.stream.StreamInput; @@ -21,6 +22,9 @@ import org.opensearch.core.xcontent.XContentParser; import java.io.IOException; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Locale; import java.util.Objects; @@ -28,6 +32,7 @@ /** * Class to define the ResourceLimitGroup schema * { + * "uuid": "" * "name": "analytics", * "resourceLimits": [ * { @@ -42,8 +47,11 @@ public class ResourceLimitGroup extends AbstractDiffable implements ToXContentObject { private final String name; + private final String uuid; private final List resourceLimits; private final String enforcement; + private final String createdAt; + private final String updatedAt; private static final List ALLOWED_RESOURCES = List.of("jvm"); private static final List ALLOWED_ENFORCEMENTS = List.of("monitor"); @@ -51,11 +59,25 @@ public class ResourceLimitGroup extends AbstractDiffable imp public static final ParseField NAME_FIELD = new ParseField("name"); public static final ParseField RESOURCE_LIMITS_FIELD = new ParseField("resourceLimits"); public static final ParseField ENFORCEMENT_FIELD = new ParseField("enforcement"); + public static final ParseField UPDATED_TIMESTAMP_FIELD = new ParseField("updatedAt"); @SuppressWarnings("unchecked") private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( "ResourceLimitGroupParser", - args -> new ResourceLimitGroup((String) args[0], (List) args[1], (String) args[2]) + args -> { + Instant currentTimestamp = Instant.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd' 'HH:mm:ss", Locale.getDefault()) + .withZone(ZoneId.of("UTC")); + String formattedTimestamp = formatter.format(currentTimestamp); + return new ResourceLimitGroup( + (String) args[0], + UUIDs.randomBase64UUID(), + (List) args[1], + (String) args[2], + formattedTimestamp, + formattedTimestamp + ); + } ); static { @@ -70,11 +92,16 @@ public class ResourceLimitGroup extends AbstractDiffable imp private static final ConstructingObjectParser PARSER_OPTIONAL_FIELDS = new ConstructingObjectParser<>( "ResourceLimitGroupParser", - args -> new ResourceLimitGroup((String) args[0], (List) args[1], (String) args[2]) + args -> { + Instant currentTimestamp = Instant.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd' 'HH:mm:ss", Locale.getDefault()) + .withZone(ZoneId.of("UTC")); + String formattedTimestamp = formatter.format(currentTimestamp); + return new ResourceLimitGroup(null, null, (List) args[0], (String) args[1], null, formattedTimestamp); + } ); static { - PARSER_OPTIONAL_FIELDS.declareString(ConstructingObjectParser.optionalConstructorArg(), NAME_FIELD); PARSER_OPTIONAL_FIELDS.declareObjectArray( ConstructingObjectParser.optionalConstructorArg(), (p, c) -> ResourceLimit.fromXContent(p), @@ -83,18 +110,28 @@ public class ResourceLimitGroup extends AbstractDiffable imp PARSER_OPTIONAL_FIELDS.declareString(ConstructingObjectParser.optionalConstructorArg(), ENFORCEMENT_FIELD); } - public ResourceLimitGroup(String name, List resourceLimits, String enforcement) { - isValidResourceLimitGroup(name, enforcement); + public ResourceLimitGroup( + String name, + String uuid, + List resourceLimits, + String enforcement, + String createdAt, + String updatedAt + ) { + isValidResourceLimitGroup(name, resourceLimits, enforcement); this.name = name; + this.uuid = uuid; this.resourceLimits = resourceLimits; this.enforcement = enforcement; + this.createdAt = createdAt; + this.updatedAt = updatedAt; } public ResourceLimitGroup(StreamInput in) throws IOException { - this(in.readString(), in.readList(ResourceLimit::new), in.readString()); + this(in.readString(), in.readString(), in.readList(ResourceLimit::new), in.readString(), in.readString(), in.readString()); } - private void isValidResourceLimitGroup(String name, String enforcement) { + private void isValidResourceLimitGroup(String name, List resourceLimits, String enforcement) { if (name != null) { if (name.isEmpty()) { throw new IllegalArgumentException("Resource Limit Group name cannot be empty"); @@ -111,6 +148,9 @@ private void isValidResourceLimitGroup(String name, String enforcement) { ); } } + if (resourceLimits != null && resourceLimits.isEmpty()) { + throw new IllegalArgumentException("Resource limit cannot be empty."); + } if (enforcement != null) { if (!ALLOWED_ENFORCEMENTS.contains(enforcement)) { throw new IllegalArgumentException( @@ -234,14 +274,24 @@ public int hashCode() { */ @Override public void writeTo(StreamOutput out) throws IOException { - writeToOutputStream(out, name, resourceLimits, enforcement); + writeToOutputStream(out, name, uuid, resourceLimits, enforcement, createdAt, updatedAt); } - public static void writeToOutputStream(StreamOutput out, String name, List resourceLimits, String enforcement) - throws IOException { + public static void writeToOutputStream( + StreamOutput out, + String name, + String uuid, + List resourceLimits, + String enforcement, + String createdAt, + String updatedAt + ) throws IOException { out.writeString(name); + out.writeString(uuid); out.writeList(resourceLimits); out.writeString(enforcement); + out.writeString(createdAt); + out.writeString(updatedAt); } /** @@ -256,6 +306,7 @@ public XContentBuilder toXContent(final XContentBuilder builder, final Params pa builder.field(NAME_FIELD.getPreferredName(), name); builder.field(RESOURCE_LIMITS_FIELD.getPreferredName(), resourceLimits); builder.field(ENFORCEMENT_FIELD.getPreferredName(), enforcement); + builder.field(UPDATED_TIMESTAMP_FIELD.getPreferredName(), updatedAt); builder.endObject(); return builder; } @@ -298,4 +349,16 @@ public List getResourceLimits() { public String getEnforcement() { return enforcement; } + + public String getUUID() { + return uuid; + } + + public String getCreatedAt() { + return createdAt; + } + + public String getUpdatedAt() { + return updatedAt; + } } diff --git a/server/src/main/java/org/opensearch/rest/action/search/RestSearchAction.java b/server/src/main/java/org/opensearch/rest/action/search/RestSearchAction.java index 7fa1b38ba95bf..80dc34c4d5d68 100644 --- a/server/src/main/java/org/opensearch/rest/action/search/RestSearchAction.java +++ b/server/src/main/java/org/opensearch/rest/action/search/RestSearchAction.java @@ -222,11 +222,6 @@ public static void parseSearchRequest( ); } - // As part of first phase in enforcing the resource limits on the groups of queries - if (request.hasParam("resource_limit_group_id")) { - searchRequest.resourceLimitGroupId(request.param("resource_limit_group_id")); - } - searchRequest.setCancelAfterTimeInterval(request.paramAsTime("cancel_after_time_interval", null)); } diff --git a/server/src/main/java/org/opensearch/search/SearchService.java b/server/src/main/java/org/opensearch/search/SearchService.java index 1167dd43784aa..6b3620e65a271 100644 --- a/server/src/main/java/org/opensearch/search/SearchService.java +++ b/server/src/main/java/org/opensearch/search/SearchService.java @@ -568,7 +568,6 @@ public void executeQueryPhase( assert request.canReturnNullResponseIfMatchNoDocs() == false || request.numberOfShards() > 1 : "empty responses require more than one shard"; final IndexShard shard = getShard(request); - task.setResourceLimitGroupId(request.resourceLimitGroupId()); rewriteAndFetchShardRequest(shard, request, new ActionListener() { @Override public void onResponse(ShardSearchRequest orig) { @@ -677,7 +676,6 @@ public void executeQueryPhase( } runAsync(getExecutor(readerContext.indexShard()), () -> { final ShardSearchRequest shardSearchRequest = readerContext.getShardSearchRequest(null); - task.setResourceLimitGroupId(shardSearchRequest.resourceLimitGroupId()); try ( SearchContext searchContext = createContext(readerContext, shardSearchRequest, task, false); SearchOperationListenerExecutor executor = new SearchOperationListenerExecutor(searchContext) @@ -780,7 +778,6 @@ public void executeFetchPhase( public void executeFetchPhase(ShardFetchRequest request, SearchShardTask task, ActionListener listener) { final ReaderContext readerContext = findReaderContext(request.contextId(), request); final ShardSearchRequest shardSearchRequest = readerContext.getShardSearchRequest(request.getShardSearchRequest()); - task.setResourceLimitGroupId(shardSearchRequest.resourceLimitGroupId()); final Releasable markAsUsed = readerContext.markAsUsed(getKeepAlive(shardSearchRequest)); runAsync(getExecutor(readerContext.indexShard()), () -> { try (SearchContext searchContext = createContext(readerContext, shardSearchRequest, task, false)) { diff --git a/server/src/main/java/org/opensearch/search/internal/ShardSearchRequest.java b/server/src/main/java/org/opensearch/search/internal/ShardSearchRequest.java index cf661c7243bb8..de1d5fb8b4098 100644 --- a/server/src/main/java/org/opensearch/search/internal/ShardSearchRequest.java +++ b/server/src/main/java/org/opensearch/search/internal/ShardSearchRequest.java @@ -112,7 +112,6 @@ public class ShardSearchRequest extends TransportRequest implements IndicesReque private SearchSourceBuilder source; private final ShardSearchContextId readerId; private final TimeValue keepAlive; - private String resourceLimitGroupId; public ShardSearchRequest( OriginalIndices originalIndices, @@ -267,9 +266,6 @@ public ShardSearchRequest(StreamInput in) throws IOException { readerId = in.readOptionalWriteable(ShardSearchContextId::new); keepAlive = in.readOptionalTimeValue(); originalIndices = OriginalIndices.readOriginalIndices(in); - if (in.getVersion().onOrAfter(Version.V_3_0_0)) { - resourceLimitGroupId = in.readOptionalString(); - } assert keepAlive == null || readerId != null : "readerId: " + readerId + " keepAlive: " + keepAlive; } @@ -294,7 +290,6 @@ public ShardSearchRequest(ShardSearchRequest clone) { this.originalIndices = clone.originalIndices; this.readerId = clone.readerId; this.keepAlive = clone.keepAlive; - this.resourceLimitGroupId = clone.resourceLimitGroupId; } @Override @@ -302,9 +297,6 @@ public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); innerWriteTo(out, false); OriginalIndices.writeOriginalIndices(originalIndices, out); - if (out.getVersion().onOrAfter(Version.V_3_0_0)) { - out.writeOptionalString(resourceLimitGroupId); - } } protected final void innerWriteTo(StreamOutput out, boolean asKey) throws IOException { @@ -433,14 +425,6 @@ public String preference() { return preference; } - public String resourceLimitGroupId() { - return resourceLimitGroupId; - } - - public void setResourceLimitGroupId(String resourceLimitGroupId) { - this.resourceLimitGroupId = resourceLimitGroupId; - } - /** * Sets the bottom sort values that can be used by the searcher to filter documents * that are after it. This value is computed by coordinating nodes that throttles the diff --git a/server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupTests.java b/server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupTests.java index 6b1e58acffab3..78f95aa35d145 100644 --- a/server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupTests.java +++ b/server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupTests.java @@ -15,6 +15,7 @@ import org.opensearch.test.OpenSearchTestCase; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -23,11 +24,16 @@ public class ResourceLimitGroupTests extends OpenSearchTestCase { public static final String JVM = "jvm"; public static final String NAME_ONE = "resource_limit_group_one"; + public static final String UUID_ONE = "AgfUO5Ja9yfsYlONlYi3TQ=="; + public static final String TIMESTAMP_ONE = "2024-04-26 23:02:21"; public static final String MONITOR = "monitor"; public static final ResourceLimitGroup resourceLimitGroupOne = new ResourceLimitGroup( NAME_ONE, - List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), - MONITOR + UUID_ONE, + List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.3)), + MONITOR, + TIMESTAMP_ONE, + TIMESTAMP_ONE ); public static void compareResourceLimits( @@ -71,38 +77,53 @@ public void testSerializationResourceLimitGroup() throws IOException { public void testInvalidName() { assertThrows( IllegalArgumentException.class, - () -> new ResourceLimitGroup("", List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR) + () -> new ResourceLimitGroup("", null, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR, null, null) ); assertThrows( IllegalArgumentException.class, - () -> new ResourceLimitGroup("-test", List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR) + () -> new ResourceLimitGroup("-test", null, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR, null, null) ); assertThrows( IllegalArgumentException.class, - () -> new ResourceLimitGroup("_test", List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR) + () -> new ResourceLimitGroup("_test", null, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR, null, null) ); assertThrows( IllegalArgumentException.class, - () -> new ResourceLimitGroup(":test", List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR) + () -> new ResourceLimitGroup(":test", null, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR, null, null) ); assertThrows( IllegalArgumentException.class, - () -> new ResourceLimitGroup("te*st", List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR) + () -> new ResourceLimitGroup("te*st", null, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR, null, null) ); assertThrows( IllegalArgumentException.class, - () -> new ResourceLimitGroup("test?", List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR) + () -> new ResourceLimitGroup("test?", null, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR, null, null) ); assertThrows( IllegalArgumentException.class, - () -> new ResourceLimitGroup("Test", List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR) + () -> new ResourceLimitGroup("Test", null, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR, null, null) + ); + } + + public void testInvalidResourceLimitList() { + assertThrows(IllegalArgumentException.class, () -> new ResourceLimitGroup("Test", null, new ArrayList<>(), MONITOR, null, null)); + assertThrows( + IllegalArgumentException.class, + () -> new ResourceLimitGroup( + "Test", + null, + List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3), new ResourceLimitGroup.ResourceLimit(JVM, 0.4)), + MONITOR, + null, + null + ) ); } public void testInvalidEnforcement() { assertThrows( IllegalArgumentException.class, - () -> new ResourceLimitGroup(NAME_ONE, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), "random") + () -> new ResourceLimitGroup(NAME_ONE, null, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), "random", null, null) ); } From 5d57745e39487fb07fe42cdf08b8c2a174a28da0 Mon Sep 17 00:00:00 2001 From: Ruirui Zhang Date: Mon, 29 Apr 2024 14:30:24 -0700 Subject: [PATCH 09/15] fix ClusterSettings format Signed-off-by: Ruirui Zhang --- .../java/org/opensearch/common/settings/ClusterSettings.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java b/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java index 43c8c1f9cb9fa..e297f3e3c5d2f 100644 --- a/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java +++ b/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java @@ -751,8 +751,7 @@ public void apply(Settings value, Settings current, Settings previous) { ) ); - public static List> BUILT_IN_SETTING_UPGRADERS = Collections.emptyList(); /** * Map of feature flag name to feature-flagged cluster settings. Once each feature From 70505969e259105a3745bfc960dd1cc9a3d616d4 Mon Sep 17 00:00:00 2001 From: Ruirui Zhang Date: Mon, 20 May 2024 17:22:48 -0700 Subject: [PATCH 10/15] address PR comments Signed-off-by: Ruirui Zhang --- .../query-resource-limit-group/build.gradle | 2 +- .../CreateResourceLimitGroupAction.java | 2 +- .../CreateResourceLimitGroupRequest.java | 2 +- .../CreateResourceLimitGroupResponse.java | 2 +- .../DeleteResourceLimitGroupAction.java | 2 +- .../DeleteResourceLimitGroupRequest.java | 2 +- .../DeleteResourceLimitGroupResponse.java | 2 +- .../GetResourceLimitGroupAction.java | 2 +- .../GetResourceLimitGroupRequest.java | 2 +- .../GetResourceLimitGroupResponse.java | 2 +- .../ResourceLimitGroupPlugin.java | 10 ++--- .../ResourceLimitGroupPluginModule.java | 6 +-- ...ansportCreateResourceLimitGroupAction.java | 4 +- ...ansportDeleteResourceLimitGroupAction.java | 4 +- .../TransportGetResourceLimitGroupAction.java | 4 +- ...ansportUpdateResourceLimitGroupAction.java | 4 +- .../UpdateResourceLimitGroupAction.java | 2 +- .../UpdateResourceLimitGroupRequest.java | 2 +- .../UpdateResourceLimitGroupResponse.java | 2 +- .../package-info.java | 2 +- .../RestCreateResourceLimitGroupAction.java | 8 ++-- .../RestDeleteResourceLimitGroupAction.java | 8 ++-- .../rest/RestGetResourceLimitGroupAction.java | 8 ++-- .../RestUpdateResourceLimitGroupAction.java | 8 ++-- .../rest/package-info.java | 2 +- .../service/Persistable.java | 10 ++--- .../ResourceLimitGroupPersistenceService.java | 40 +++++++++---------- .../service/package-info.java | 2 +- .../CreateResourceLimitGroupRequestTests.java | 6 +-- ...CreateResourceLimitGroupResponseTests.java | 6 +-- .../DeleteResourceLimitGroupRequestTests.java | 4 +- ...DeleteResourceLimitGroupResponseTests.java | 8 ++-- .../GetResourceLimitGroupRequestTests.java | 4 +- .../GetResourceLimitGroupResponseTests.java | 8 ++-- .../ResourceLimitGroupTestUtils.java | 4 +- .../UpdateResourceLimitGroupRequestTests.java | 10 ++--- ...UpdateResourceLimitGroupResponseTests.java | 6 +-- ...urceLimitGroupPersistenceServiceTests.java | 30 +++++++------- 38 files changed, 116 insertions(+), 116 deletions(-) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/CreateResourceLimitGroupAction.java (94%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/CreateResourceLimitGroupRequest.java (98%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/CreateResourceLimitGroupResponse.java (97%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/DeleteResourceLimitGroupAction.java (94%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/DeleteResourceLimitGroupRequest.java (98%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/DeleteResourceLimitGroupResponse.java (98%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/GetResourceLimitGroupAction.java (94%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/GetResourceLimitGroupRequest.java (98%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/GetResourceLimitGroupResponse.java (98%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/ResourceLimitGroupPlugin.java (86%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/ResourceLimitGroupPluginModule.java (80%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/TransportCreateResourceLimitGroupAction.java (95%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/TransportDeleteResourceLimitGroupAction.java (94%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/TransportGetResourceLimitGroupAction.java (94%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/TransportUpdateResourceLimitGroupAction.java (95%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/UpdateResourceLimitGroupAction.java (94%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/UpdateResourceLimitGroupRequest.java (98%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/UpdateResourceLimitGroupResponse.java (97%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/package-info.java (83%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/rest/RestCreateResourceLimitGroupAction.java (91%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/rest/RestDeleteResourceLimitGroupAction.java (88%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/rest/RestGetResourceLimitGroupAction.java (88%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/rest/RestUpdateResourceLimitGroupAction.java (90%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/rest/package-info.java (83%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/service/Persistable.java (77%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/service/ResourceLimitGroupPersistenceService.java (95%) rename plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/{resource_limit_group => rlg}/service/package-info.java (86%) rename plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/{resource_limit_group => rlg}/CreateResourceLimitGroupRequestTests.java (83%) rename plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/{resource_limit_group => rlg}/CreateResourceLimitGroupResponseTests.java (82%) rename plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/{resource_limit_group => rlg}/DeleteResourceLimitGroupRequestTests.java (91%) rename plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/{resource_limit_group => rlg}/DeleteResourceLimitGroupResponseTests.java (88%) rename plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/{resource_limit_group => rlg}/GetResourceLimitGroupRequestTests.java (91%) rename plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/{resource_limit_group => rlg}/GetResourceLimitGroupResponseTests.java (88%) rename plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/{resource_limit_group => rlg}/ResourceLimitGroupTestUtils.java (97%) rename plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/{resource_limit_group => rlg}/UpdateResourceLimitGroupRequestTests.java (88%) rename plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/{resource_limit_group => rlg}/UpdateResourceLimitGroupResponseTests.java (82%) rename plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/{resource_limit_group => rlg}/service/ResourceLimitGroupPersistenceServiceTests.java (86%) diff --git a/plugins/query-resource-limit-group/build.gradle b/plugins/query-resource-limit-group/build.gradle index cca4402f60e42..d4d05c5b3c6a8 100644 --- a/plugins/query-resource-limit-group/build.gradle +++ b/plugins/query-resource-limit-group/build.gradle @@ -11,7 +11,7 @@ opensearchplugin { description 'OpenSearch ResourceLimitGroup Plugin.' - classname 'org.opensearch.plugin.resource_limit_group.ResourceLimitGroupPlugin' + classname 'org.opensearch.plugin.rlg.ResourceLimitGroupPlugin' } dependencies { diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupAction.java similarity index 94% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupAction.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupAction.java index 4b002d85f7f0e..b3ec61f55e9b3 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.action.ActionType; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupRequest.java similarity index 98% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequest.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupRequest.java index c897957a66438..d7a8c6ac196f3 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequest.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupRequest.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.action.ActionRequest; import org.opensearch.action.ActionRequestValidationException; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponse.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupResponse.java similarity index 97% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponse.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupResponse.java index 290de02fc4d20..530500b22a507 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponse.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupResponse.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.cluster.metadata.ResourceLimitGroup; import org.opensearch.core.action.ActionResponse; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupAction.java similarity index 94% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupAction.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupAction.java index 184ffdbc5ca51..44a2c87ac31fd 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.action.ActionType; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupRequest.java similarity index 98% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupRequest.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupRequest.java index 10a66828ca58d..690df6cbaa306 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupRequest.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupRequest.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.action.ActionRequest; import org.opensearch.action.ActionRequestValidationException; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponse.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupResponse.java similarity index 98% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponse.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupResponse.java index 5b579a56bfe37..995863439b596 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponse.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupResponse.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.cluster.metadata.ResourceLimitGroup; import org.opensearch.core.action.ActionResponse; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupAction.java similarity index 94% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupAction.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupAction.java index 97285d75b65ed..e2f193bd7e592 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.action.ActionType; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupRequest.java similarity index 98% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequest.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupRequest.java index efba50ab1beb8..50cb467bec09c 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequest.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupRequest.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.action.ActionRequest; import org.opensearch.action.ActionRequestValidationException; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponse.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupResponse.java similarity index 98% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponse.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupResponse.java index f9b299af3a807..99bc92f6f5cd3 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponse.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupResponse.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.cluster.metadata.ResourceLimitGroup; import org.opensearch.core.action.ActionResponse; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/ResourceLimitGroupPlugin.java similarity index 86% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/ResourceLimitGroupPlugin.java index af66821f7a68d..3a41762b4e7b5 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPlugin.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/ResourceLimitGroupPlugin.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.action.ActionRequest; import org.opensearch.cluster.metadata.IndexNameExpressionResolver; @@ -17,10 +17,10 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.settings.SettingsFilter; import org.opensearch.core.action.ActionResponse; -import org.opensearch.plugin.resource_limit_group.rest.RestCreateResourceLimitGroupAction; -import org.opensearch.plugin.resource_limit_group.rest.RestDeleteResourceLimitGroupAction; -import org.opensearch.plugin.resource_limit_group.rest.RestGetResourceLimitGroupAction; -import org.opensearch.plugin.resource_limit_group.rest.RestUpdateResourceLimitGroupAction; +import org.opensearch.plugin.rlg.rest.RestCreateResourceLimitGroupAction; +import org.opensearch.plugin.rlg.rest.RestDeleteResourceLimitGroupAction; +import org.opensearch.plugin.rlg.rest.RestGetResourceLimitGroupAction; +import org.opensearch.plugin.rlg.rest.RestUpdateResourceLimitGroupAction; import org.opensearch.plugins.ActionPlugin; import org.opensearch.plugins.Plugin; import org.opensearch.rest.RestController; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPluginModule.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/ResourceLimitGroupPluginModule.java similarity index 80% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPluginModule.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/ResourceLimitGroupPluginModule.java index bebf3f24b32f0..07bcc7eb2bde3 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupPluginModule.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/ResourceLimitGroupPluginModule.java @@ -6,13 +6,13 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.cluster.metadata.ResourceLimitGroup; import org.opensearch.common.inject.AbstractModule; import org.opensearch.common.inject.TypeLiteral; -import org.opensearch.plugin.resource_limit_group.service.Persistable; -import org.opensearch.plugin.resource_limit_group.service.ResourceLimitGroupPersistenceService; +import org.opensearch.plugin.rlg.service.Persistable; +import org.opensearch.plugin.rlg.service.ResourceLimitGroupPersistenceService; /** * Guice Module to manage ResourceLimitGroup related objects diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportCreateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportCreateResourceLimitGroupAction.java similarity index 95% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportCreateResourceLimitGroupAction.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportCreateResourceLimitGroupAction.java index 05b9c34a01907..fc3bd773c0b1d 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportCreateResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportCreateResourceLimitGroupAction.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; import org.opensearch.cluster.metadata.ResourceLimitGroup; import org.opensearch.common.inject.Inject; import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.resource_limit_group.service.Persistable; +import org.opensearch.plugin.rlg.service.Persistable; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportService; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportDeleteResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportDeleteResourceLimitGroupAction.java similarity index 94% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportDeleteResourceLimitGroupAction.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportDeleteResourceLimitGroupAction.java index be0107b0d9d77..ee4ff508f9966 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportDeleteResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportDeleteResourceLimitGroupAction.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; import org.opensearch.cluster.metadata.ResourceLimitGroup; import org.opensearch.common.inject.Inject; import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.resource_limit_group.service.Persistable; +import org.opensearch.plugin.rlg.service.Persistable; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportService; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportGetResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportGetResourceLimitGroupAction.java similarity index 94% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportGetResourceLimitGroupAction.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportGetResourceLimitGroupAction.java index 8f2b1cf4c2c86..ba2ff776770fe 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportGetResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportGetResourceLimitGroupAction.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; import org.opensearch.cluster.metadata.ResourceLimitGroup; import org.opensearch.common.inject.Inject; import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.resource_limit_group.service.Persistable; +import org.opensearch.plugin.rlg.service.Persistable; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportService; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportUpdateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportUpdateResourceLimitGroupAction.java similarity index 95% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportUpdateResourceLimitGroupAction.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportUpdateResourceLimitGroupAction.java index a77cc3c5a6505..90a208d48053a 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/TransportUpdateResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportUpdateResourceLimitGroupAction.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; import org.opensearch.cluster.metadata.ResourceLimitGroup; import org.opensearch.common.inject.Inject; import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.resource_limit_group.service.Persistable; +import org.opensearch.plugin.rlg.service.Persistable; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportService; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupAction.java similarity index 94% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupAction.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupAction.java index 54a41fccc258e..afa5be86b05a6 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.action.ActionType; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupRequest.java similarity index 98% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequest.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupRequest.java index c75c1d6c57dab..ab9aafce4dd62 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequest.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupRequest.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.action.ActionRequest; import org.opensearch.action.ActionRequestValidationException; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponse.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupResponse.java similarity index 97% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponse.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupResponse.java index ffe1dabf8875c..3f8a5e3c9c683 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponse.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupResponse.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.cluster.metadata.ResourceLimitGroup; import org.opensearch.core.action.ActionResponse; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/package-info.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/package-info.java similarity index 83% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/package-info.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/package-info.java index 4b54c3e635cdc..8db7a9c279a5b 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/package-info.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/package-info.java @@ -9,4 +9,4 @@ /** * Base Package of CRUD API of resource limit group */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestCreateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestCreateResourceLimitGroupAction.java similarity index 91% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestCreateResourceLimitGroupAction.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestCreateResourceLimitGroupAction.java index 17ebb48ca9dc8..9002d7ba48acb 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestCreateResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestCreateResourceLimitGroupAction.java @@ -6,15 +6,15 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group.rest; +package org.opensearch.plugin.rlg.rest; import org.opensearch.client.node.NodeClient; import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; import org.opensearch.core.xcontent.XContentParser; -import org.opensearch.plugin.resource_limit_group.CreateResourceLimitGroupAction; -import org.opensearch.plugin.resource_limit_group.CreateResourceLimitGroupRequest; -import org.opensearch.plugin.resource_limit_group.CreateResourceLimitGroupResponse; +import org.opensearch.plugin.rlg.CreateResourceLimitGroupAction; +import org.opensearch.plugin.rlg.CreateResourceLimitGroupRequest; +import org.opensearch.plugin.rlg.CreateResourceLimitGroupResponse; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.RestChannel; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestDeleteResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestDeleteResourceLimitGroupAction.java similarity index 88% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestDeleteResourceLimitGroupAction.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestDeleteResourceLimitGroupAction.java index 558e4fa796ecd..a0c213bbb7860 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestDeleteResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestDeleteResourceLimitGroupAction.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group.rest; +package org.opensearch.plugin.rlg.rest; import org.opensearch.client.node.NodeClient; import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.plugin.resource_limit_group.DeleteResourceLimitGroupAction; -import org.opensearch.plugin.resource_limit_group.DeleteResourceLimitGroupRequest; -import org.opensearch.plugin.resource_limit_group.DeleteResourceLimitGroupResponse; +import org.opensearch.plugin.rlg.DeleteResourceLimitGroupAction; +import org.opensearch.plugin.rlg.DeleteResourceLimitGroupRequest; +import org.opensearch.plugin.rlg.DeleteResourceLimitGroupResponse; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.RestChannel; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestGetResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestGetResourceLimitGroupAction.java similarity index 88% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestGetResourceLimitGroupAction.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestGetResourceLimitGroupAction.java index 5d53e970970ae..d2dcf9e7d366c 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestGetResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestGetResourceLimitGroupAction.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group.rest; +package org.opensearch.plugin.rlg.rest; import org.opensearch.client.node.NodeClient; import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.plugin.resource_limit_group.GetResourceLimitGroupAction; -import org.opensearch.plugin.resource_limit_group.GetResourceLimitGroupRequest; -import org.opensearch.plugin.resource_limit_group.GetResourceLimitGroupResponse; +import org.opensearch.plugin.rlg.GetResourceLimitGroupAction; +import org.opensearch.plugin.rlg.GetResourceLimitGroupRequest; +import org.opensearch.plugin.rlg.GetResourceLimitGroupResponse; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.RestChannel; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestUpdateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestUpdateResourceLimitGroupAction.java similarity index 90% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestUpdateResourceLimitGroupAction.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestUpdateResourceLimitGroupAction.java index d4de15043a8b1..f6a769d7e0104 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/RestUpdateResourceLimitGroupAction.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestUpdateResourceLimitGroupAction.java @@ -6,15 +6,15 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group.rest; +package org.opensearch.plugin.rlg.rest; import org.opensearch.client.node.NodeClient; import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; import org.opensearch.core.xcontent.XContentParser; -import org.opensearch.plugin.resource_limit_group.UpdateResourceLimitGroupAction; -import org.opensearch.plugin.resource_limit_group.UpdateResourceLimitGroupRequest; -import org.opensearch.plugin.resource_limit_group.UpdateResourceLimitGroupResponse; +import org.opensearch.plugin.rlg.UpdateResourceLimitGroupAction; +import org.opensearch.plugin.rlg.UpdateResourceLimitGroupRequest; +import org.opensearch.plugin.rlg.UpdateResourceLimitGroupResponse; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.RestChannel; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/package-info.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/package-info.java similarity index 83% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/package-info.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/package-info.java index f139daedf9fb9..6f0597a33e76c 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/rest/package-info.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/package-info.java @@ -9,4 +9,4 @@ /** * Package for the rest classes for resource limit group CRUD operations */ -package org.opensearch.plugin.resource_limit_group.rest; +package org.opensearch.plugin.rlg.rest; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/Persistable.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/Persistable.java similarity index 77% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/Persistable.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/Persistable.java index b5758ba3ec627..70d221c73070f 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/Persistable.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/Persistable.java @@ -6,13 +6,13 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group.service; +package org.opensearch.plugin.rlg.service; import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.resource_limit_group.CreateResourceLimitGroupResponse; -import org.opensearch.plugin.resource_limit_group.DeleteResourceLimitGroupResponse; -import org.opensearch.plugin.resource_limit_group.GetResourceLimitGroupResponse; -import org.opensearch.plugin.resource_limit_group.UpdateResourceLimitGroupResponse; +import org.opensearch.plugin.rlg.CreateResourceLimitGroupResponse; +import org.opensearch.plugin.rlg.DeleteResourceLimitGroupResponse; +import org.opensearch.plugin.rlg.GetResourceLimitGroupResponse; +import org.opensearch.plugin.rlg.UpdateResourceLimitGroupResponse; /** * This interface defines the key APIs for implementing resource limit group persistence diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceService.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceService.java similarity index 95% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceService.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceService.java index 8eb3821a2cd5f..083437578e115 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceService.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceService.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group.service; +package org.opensearch.plugin.rlg.service; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -23,10 +23,10 @@ import org.opensearch.common.settings.Settings; import org.opensearch.core.action.ActionListener; import org.opensearch.core.rest.RestStatus; -import org.opensearch.plugin.resource_limit_group.CreateResourceLimitGroupResponse; -import org.opensearch.plugin.resource_limit_group.DeleteResourceLimitGroupResponse; -import org.opensearch.plugin.resource_limit_group.GetResourceLimitGroupResponse; -import org.opensearch.plugin.resource_limit_group.UpdateResourceLimitGroupResponse; +import org.opensearch.plugin.rlg.CreateResourceLimitGroupResponse; +import org.opensearch.plugin.rlg.DeleteResourceLimitGroupResponse; +import org.opensearch.plugin.rlg.GetResourceLimitGroupResponse; +import org.opensearch.plugin.rlg.UpdateResourceLimitGroupResponse; import java.util.ArrayList; import java.util.HashMap; @@ -50,7 +50,7 @@ public class ResourceLimitGroupPersistenceService implements Persistable inflightResourceLimitValues; + private final Map inflightResourceLimitValues; private volatile int maxResourceLimitGroupCount; final ThrottlingKey createResourceLimitGroupThrottlingKey; final ThrottlingKey updateResourceLimitGroupThrottlingKey; @@ -135,7 +135,6 @@ public void update(ResourceLimitGroup resourceLimitGroup, ActionListener maxResourceLimitGroupCount; + if (!resourceNameWithThresholdExceeded.isEmpty()) { logger.error("Total resource allocation for {} will go above the max limit of 1.0", resourceNameWithThresholdExceeded); throw new RuntimeException( "Total resource allocation for " + resourceNameWithThresholdExceeded + " will go above the max limit of 1.0" ); } - - // check if group count exceed max - boolean groupCountExceeded = inflightCreateResourceLimitGroupRequestCount.incrementAndGet() + previousGroups - .size() > maxResourceLimitGroupCount; - inflightCreateResourceLimitGroupRequestCount.decrementAndGet(); if (groupCountExceeded) { logger.error("{} value exceeded its assigned limit of {}", RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME, maxResourceLimitGroupCount); throw new RuntimeException("Can't create more than " + maxResourceLimitGroupCount + " Resource Limit Groups in the system"); @@ -296,6 +297,9 @@ ClusterState saveResourceLimitGroupInClusterState(final ResourceLimitGroup resou * @param resourceLimitGroup - the resource limit group we're currently creating */ void restoreInflightValues(ResourceLimitGroup resourceLimitGroup) { + if (resourceLimitGroup.getResourceLimits() == null || resourceLimitGroup.getResourceLimits().isEmpty()) { + return; + } for (ResourceLimit rl : resourceLimitGroup.getResourceLimits()) { String currResourceName = rl.getResourceName(); inflightResourceLimitValues.get(currResourceName).add(-getResourceLimitValue(currResourceName, resourceLimitGroup)); @@ -342,6 +346,7 @@ public ThrottlingKey getClusterManagerThrottlingKey() { @Override public void onFailure(String source, Exception e) { + restoreInflightValues(toUpdateGroup); logger.warn("Failed to update Resource Limit Group due to error: {}, for source: {}", e.getMessage(), source); UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(); response.setRestStatus(RestStatus.FAILED_DEPENDENCY); @@ -350,12 +355,7 @@ public void onFailure(String source, Exception e) { @Override public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { - if (toUpdateGroup.getResourceLimits() != null) { - for (ResourceLimit rl : toUpdateGroup.getResourceLimits()) { - String currResourceName = rl.getResourceName(); - inflightResourceLimitValues.get(currResourceName).add(-getResourceLimitValue(currResourceName, toUpdateGroup)); - } - } + restoreInflightValues(toUpdateGroup); UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(updatedGroup); response.setRestStatus(RestStatus.OK); listener.onResponse(response); diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/package-info.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/package-info.java similarity index 86% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/package-info.java rename to plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/package-info.java index 5e907f6ecbeec..3a953b1ee97d2 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/resource_limit_group/service/package-info.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/package-info.java @@ -13,4 +13,4 @@ /** * Package for the service classes for resource limit group CRUD operations */ -package org.opensearch.plugin.resource_limit_group.service; +package org.opensearch.plugin.rlg.service; diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequestTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupRequestTests.java similarity index 83% rename from plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequestTests.java rename to plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupRequestTests.java index c9f1c7bc3f5d5..9ef9133d5c888 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupRequestTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupRequestTests.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.core.common.io.stream.StreamInput; @@ -14,8 +14,8 @@ import java.io.IOException; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimits; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupOne; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.compareResourceLimits; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupOne; public class CreateResourceLimitGroupRequestTests extends OpenSearchTestCase { diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponseTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupResponseTests.java similarity index 82% rename from plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponseTests.java rename to plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupResponseTests.java index 8db619cb7e0a9..c89b3fd3e3299 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/CreateResourceLimitGroupResponseTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupResponseTests.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.cluster.metadata.ResourceLimitGroup; import org.opensearch.common.io.stream.BytesStreamOutput; @@ -16,8 +16,8 @@ import java.io.IOException; import java.util.List; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimitGroups; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupOne; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.compareResourceLimitGroups; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupOne; public class CreateResourceLimitGroupResponseTests extends OpenSearchTestCase { diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupRequestTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupRequestTests.java similarity index 91% rename from plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupRequestTests.java rename to plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupRequestTests.java index a77ddb6521736..29c4f00d4ac4e 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupRequestTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupRequestTests.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.core.common.io.stream.StreamInput; @@ -14,7 +14,7 @@ import java.io.IOException; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_ONE; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.NAME_ONE; public class DeleteResourceLimitGroupRequestTests extends OpenSearchTestCase { diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponseTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupResponseTests.java similarity index 88% rename from plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponseTests.java rename to plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupResponseTests.java index 81722501714b8..587f1c4754270 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/DeleteResourceLimitGroupResponseTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupResponseTests.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.cluster.metadata.ResourceLimitGroup; import org.opensearch.common.io.stream.BytesStreamOutput; @@ -17,9 +17,9 @@ import java.util.ArrayList; import java.util.List; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimitGroups; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupList; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupOne; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.compareResourceLimitGroups; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupList; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupOne; public class DeleteResourceLimitGroupResponseTests extends OpenSearchTestCase { diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequestTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/GetResourceLimitGroupRequestTests.java similarity index 91% rename from plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequestTests.java rename to plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/GetResourceLimitGroupRequestTests.java index ac933c5b2a5a2..bda42d7398957 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupRequestTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/GetResourceLimitGroupRequestTests.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.core.common.io.stream.StreamInput; @@ -14,7 +14,7 @@ import java.io.IOException; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_ONE; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.NAME_ONE; public class GetResourceLimitGroupRequestTests extends OpenSearchTestCase { diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponseTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/GetResourceLimitGroupResponseTests.java similarity index 88% rename from plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponseTests.java rename to plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/GetResourceLimitGroupResponseTests.java index e705e0e76c1d2..34616bcdaf89e 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/GetResourceLimitGroupResponseTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/GetResourceLimitGroupResponseTests.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.cluster.metadata.ResourceLimitGroup; import org.opensearch.common.io.stream.BytesStreamOutput; @@ -17,9 +17,9 @@ import java.util.ArrayList; import java.util.List; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimitGroups; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupList; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupOne; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.compareResourceLimitGroups; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupList; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupOne; public class GetResourceLimitGroupResponseTests extends OpenSearchTestCase { diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupTestUtils.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/ResourceLimitGroupTestUtils.java similarity index 97% rename from plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupTestUtils.java rename to plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/ResourceLimitGroupTestUtils.java index 574640ef5b16d..4eaff1a5d3c20 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/ResourceLimitGroupTestUtils.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/ResourceLimitGroupTestUtils.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.cluster.ClusterName; import org.opensearch.cluster.ClusterState; @@ -16,7 +16,7 @@ import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.settings.ClusterSettings; import org.opensearch.common.settings.Settings; -import org.opensearch.plugin.resource_limit_group.service.ResourceLimitGroupPersistenceService; +import org.opensearch.plugin.rlg.service.ResourceLimitGroupPersistenceService; import org.opensearch.threadpool.ThreadPool; import java.util.HashMap; diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequestTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupRequestTests.java similarity index 88% rename from plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequestTests.java rename to plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupRequestTests.java index 404069310dfe8..423a33ab5422d 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupRequestTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupRequestTests.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.cluster.metadata.ResourceLimitGroup; import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; @@ -17,10 +17,10 @@ import java.io.IOException; import java.util.List; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_ONE; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.TIMESTAMP_ONE; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimits; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupOne; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.NAME_ONE; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.TIMESTAMP_ONE; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.compareResourceLimits; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupOne; public class UpdateResourceLimitGroupRequestTests extends OpenSearchTestCase { diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponseTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupResponseTests.java similarity index 82% rename from plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponseTests.java rename to plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupResponseTests.java index beb7a8502da33..eefe7cbc60c6a 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/UpdateResourceLimitGroupResponseTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupResponseTests.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group; +package org.opensearch.plugin.rlg; import org.opensearch.cluster.metadata.ResourceLimitGroup; import org.opensearch.common.io.stream.BytesStreamOutput; @@ -16,8 +16,8 @@ import java.io.IOException; import java.util.List; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimitGroups; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupOne; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.compareResourceLimitGroups; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupOne; public class UpdateResourceLimitGroupResponseTests extends OpenSearchTestCase { diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceServiceTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceServiceTests.java similarity index 86% rename from plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceServiceTests.java rename to plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceServiceTests.java index 53a947db493ad..0e5149645501e 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/resource_limit_group/service/ResourceLimitGroupPersistenceServiceTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceServiceTests.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.resource_limit_group.service; +package org.opensearch.plugin.rlg.service; import org.opensearch.cluster.ClusterName; import org.opensearch.cluster.ClusterState; @@ -24,20 +24,20 @@ import java.util.Set; import java.util.stream.Collectors; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.MONITOR; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_NONE_EXISTED; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_ONE; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.NAME_TWO; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.SANDBOX_MAX_SETTING_NAME; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.TIMESTAMP_ONE; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.clusterState; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.compareResourceLimitGroups; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.prepareSandboxPersistenceService; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupList; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupMap; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupOne; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupPersistenceService; -import static org.opensearch.plugin.resource_limit_group.ResourceLimitGroupTestUtils.resourceLimitGroupTwo; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.MONITOR; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.NAME_NONE_EXISTED; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.NAME_ONE; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.NAME_TWO; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.SANDBOX_MAX_SETTING_NAME; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.TIMESTAMP_ONE; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.clusterState; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.compareResourceLimitGroups; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.prepareSandboxPersistenceService; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupList; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupMap; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupOne; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupPersistenceService; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupTwo; import static org.mockito.Mockito.mock; public class ResourceLimitGroupPersistenceServiceTests extends OpenSearchTestCase { From 4182e0754c8bff6c603f413495e536bf572643c6 Mon Sep 17 00:00:00 2001 From: Ruirui Zhang Date: Wed, 22 May 2024 12:36:33 -0700 Subject: [PATCH 11/15] modify crud api based on comments Signed-off-by: Ruirui Zhang --- .../ResourceLimitGroupPersistenceService.java | 160 +++++++++--------- .../rlg/ResourceLimitGroupTestUtils.java | 11 ++ ...urceLimitGroupPersistenceServiceTests.java | 44 ++--- 3 files changed, 115 insertions(+), 100 deletions(-) diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceService.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceService.java index 083437578e115..210b6224a4cb4 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceService.java +++ b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceService.java @@ -49,7 +49,7 @@ public class ResourceLimitGroupPersistenceService implements Persistable inflightResourceLimitValues; private volatile int maxResourceLimitGroupCount; final ThrottlingKey createResourceLimitGroupThrottlingKey; @@ -107,70 +107,7 @@ public void persist(ResourceLimitGroup resourceLimitGroup, ActionListener listener) { - ClusterState currentState = clusterService.state(); - Map currentGroupsMap = currentState.metadata().resourceLimitGroups(); - List currentGroupsList = new ArrayList<>(currentGroupsMap.values()); - String name = resourceLimitGroup.getName(); - - if (!currentGroupsMap.containsKey(name)) { - logger.warn("No Resource Limit Group exists with the provided name: {}", name); - Exception e = new RuntimeException("No Resource Limit Group exists with the provided name: " + name); - UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(); - response.setRestStatus(RestStatus.NOT_FOUND); - listener.onFailure(e); - return; - } - - // check if there's any resource allocation that exceed limit of 1.0 - if (resourceLimitGroup.getResourceLimits() != null) { - String resourceNameWithThresholdExceeded = ""; - for (ResourceLimit resourceLimit : resourceLimitGroup.getResourceLimits()) { - String resourceName = resourceLimit.getResourceName(); - double existingUsage = calculateExistingUsage(resourceName, currentGroupsList, name); - double newGroupUsage = getResourceLimitValue(resourceName, resourceLimitGroup); - inflightResourceLimitValues.computeIfAbsent(resourceName, k -> new DoubleAdder()).add(newGroupUsage); - double totalUsage = existingUsage + inflightResourceLimitValues.get(resourceName).doubleValue(); - if (totalUsage > 1) { - resourceNameWithThresholdExceeded = resourceName; - } - } - if (!resourceNameWithThresholdExceeded.isEmpty()) { - Exception e = new RuntimeException( - "Total resource allocation for " + resourceNameWithThresholdExceeded + " will go above the max limit of 1.0" - ); - UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(); - response.setRestStatus(RestStatus.CONFLICT); - listener.onFailure(e); - return; - } - } - - // build the resource limit group with updated fields - ResourceLimitGroup existingGroup = currentGroupsMap.get(name); - String uuid = existingGroup.getUUID(); - String createdAt = existingGroup.getCreatedAt(); - String updatedAt = resourceLimitGroup.getUpdatedAt(); - List resourceLimit; - if (resourceLimitGroup.getResourceLimits() == null || resourceLimitGroup.getResourceLimits().isEmpty()) { - resourceLimit = existingGroup.getResourceLimits(); - } else { - resourceLimit = new ArrayList<>(existingGroup.getResourceLimits()); - Map resourceLimitMap = resourceLimitGroup.getResourceLimits() - .stream() - .collect(Collectors.toMap(ResourceLimit::getResourceName, ResourceLimit::getValue)); - for (ResourceLimit rl : resourceLimit) { - String currResourceName = rl.getResourceName(); - if (resourceLimitMap.containsKey(currResourceName)) { - rl.setValue(resourceLimitMap.get(currResourceName)); - } - } - } - String enforcement = resourceLimitGroup.getEnforcement() == null - ? existingGroup.getEnforcement() - : resourceLimitGroup.getEnforcement(); - - ResourceLimitGroup updatedGroup = new ResourceLimitGroup(name, uuid, resourceLimit, enforcement, createdAt, updatedAt); - updateInClusterStateMetadata(existingGroup, resourceLimitGroup, updatedGroup, listener); + updateInClusterStateMetadata(resourceLimitGroup, listener); } @Override @@ -256,10 +193,6 @@ private double getResourceLimitValue(String resourceName, final ResourceLimitGro ClusterState saveResourceLimitGroupInClusterState(final ResourceLimitGroup resourceLimitGroup, final ClusterState currentClusterState) { final Metadata metadata = currentClusterState.metadata(); String groupName = resourceLimitGroup.getName(); - if (metadata.resourceLimitGroups().containsKey(groupName)) { - logger.warn("Resource Limit Group with name {} already exists. Not creating a new one.", groupName); - throw new RuntimeException("Resource Limit Group with name " + groupName + " already exists. Not creating a new one."); - } final List previousGroups = new ArrayList<>(metadata.resourceLimitGroups().values()); // check if there's any resource allocation that exceed limit of 1.0 @@ -278,6 +211,10 @@ ClusterState saveResourceLimitGroupInClusterState(final ResourceLimitGroup resou boolean groupCountExceeded = inflightCreateResourceLimitGroupRequestCount.incrementAndGet() + previousGroups .size() > maxResourceLimitGroupCount; + if (metadata.resourceLimitGroups().containsKey(groupName)) { + logger.warn("Resource Limit Group with name {} already exists. Not creating a new one.", groupName); + throw new RuntimeException("Resource Limit Group with name " + groupName + " already exists. Not creating a new one."); + } if (!resourceNameWithThresholdExceeded.isEmpty()) { logger.error("Total resource allocation for {} will go above the max limit of 1.0", resourceNameWithThresholdExceeded); throw new RuntimeException( @@ -324,19 +261,16 @@ private double calculateExistingUsage(String resourceName, List listener ) { clusterService.submitStateUpdateTask(SOURCE, new ClusterStateUpdateTask(Priority.URGENT) { @Override public ClusterState execute(ClusterState currentState) { - return updateResourceLimitGroupInClusterState(existingGroup, updatedGroup, currentState); + return updateResourceLimitGroupInClusterState(toUpdateGroup, currentState); } @Override @@ -356,6 +290,9 @@ public void onFailure(String source, Exception e) { @Override public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { restoreInflightValues(toUpdateGroup); + String name = toUpdateGroup.getName(); + assert newState.metadata().resourceLimitGroups().containsKey(name); + ResourceLimitGroup updatedGroup = newState.metadata().resourceLimitGroups().get(name); UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(updatedGroup); response.setRestStatus(RestStatus.OK); listener.onResponse(response); @@ -365,16 +302,69 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS /** * Modify cluster state to update the existing Resource Limit Group - * @param existingGroup {@link ResourceLimitGroup} - the existing resource limit group that we want to update - * @param updatedGroup {@link ResourceLimitGroup} - the resource limit group we're updating to + * @param resourceLimitGroup {@link ResourceLimitGroup} - the resource limit group that we want to update * @param currentState - current cluster state */ public ClusterState updateResourceLimitGroupInClusterState( - ResourceLimitGroup existingGroup, - ResourceLimitGroup updatedGroup, + ResourceLimitGroup resourceLimitGroup, ClusterState currentState ) { final Metadata metadata = currentState.metadata(); + Map currentGroupsMap = currentState.metadata().resourceLimitGroups(); + List currentGroupsList = new ArrayList<>(currentGroupsMap.values()); + String name = resourceLimitGroup.getName(); + String resourceNameWithThresholdExceeded = ""; + + // check if there's any resource allocation that exceed limit of 1.0 + if (resourceLimitGroup.getResourceLimits() != null) { + for (ResourceLimit resourceLimit : resourceLimitGroup.getResourceLimits()) { + String resourceName = resourceLimit.getResourceName(); + double existingUsage = calculateExistingUsage(resourceName, currentGroupsList, name); + double newGroupUsage = getResourceLimitValue(resourceName, resourceLimitGroup); + inflightResourceLimitValues.computeIfAbsent(resourceName, k -> new DoubleAdder()).add(newGroupUsage); + double totalUsage = existingUsage + inflightResourceLimitValues.get(resourceName).doubleValue(); + if (totalUsage > 1) { + resourceNameWithThresholdExceeded = resourceName; + } + } + } + + if (!currentGroupsMap.containsKey(name)) { + logger.warn("No Resource Limit Group exists with the provided name: {}", name); + throw new RuntimeException("No Resource Limit Group exists with the provided name: " + name); + } + if (!resourceNameWithThresholdExceeded.isEmpty()) { + logger.error("Total resource allocation for {} will go above the max limit of 1.0", resourceNameWithThresholdExceeded); + throw new RuntimeException( + "Total resource allocation for " + resourceNameWithThresholdExceeded + " will go above the max limit of 1.0" + ); + } + + // build the resource limit group with updated fields + ResourceLimitGroup existingGroup = currentGroupsMap.get(name); + String uuid = existingGroup.getUUID(); + String createdAt = existingGroup.getCreatedAt(); + String updatedAt = resourceLimitGroup.getUpdatedAt(); + List resourceLimit; + if (resourceLimitGroup.getResourceLimits() == null || resourceLimitGroup.getResourceLimits().isEmpty()) { + resourceLimit = existingGroup.getResourceLimits(); + } else { + resourceLimit = new ArrayList<>(existingGroup.getResourceLimits()); + Map resourceLimitMap = resourceLimitGroup.getResourceLimits() + .stream() + .collect(Collectors.toMap(ResourceLimit::getResourceName, ResourceLimit::getValue)); + for (ResourceLimit rl : resourceLimit) { + String currResourceName = rl.getResourceName(); + if (resourceLimitMap.containsKey(currResourceName)) { + rl.setValue(resourceLimitMap.get(currResourceName)); + } + } + } + String enforcement = resourceLimitGroup.getEnforcement() == null + ? existingGroup.getEnforcement() + : resourceLimitGroup.getEnforcement(); + + ResourceLimitGroup updatedGroup = new ResourceLimitGroup(name, uuid, resourceLimit, enforcement, createdAt, updatedAt); return ClusterState.builder(currentState) .metadata(Metadata.builder(metadata).removeResourceLimitGroup(existingGroup.getName()).put(updatedGroup).build()) .build(); @@ -457,4 +447,18 @@ List getFromClusterStateMetadata(String name, ClusterState c } return resultGroups; } + + /** + * inflightCreateResourceLimitGroupRequestCount getter + */ + public AtomicInteger getInflightCreateResourceLimitGroupRequestCount() { + return inflightCreateResourceLimitGroupRequestCount; + } + + /** + * inflightResourceLimitValues getter + */ + public Map getInflightResourceLimitValues() { + return inflightResourceLimitValues; + } } diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/ResourceLimitGroupTestUtils.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/ResourceLimitGroupTestUtils.java index 4eaff1a5d3c20..ebacff9270e77 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/ResourceLimitGroupTestUtils.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/ResourceLimitGroupTestUtils.java @@ -22,6 +22,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.DoubleAdder; import java.util.stream.Collectors; import static org.junit.Assert.assertEquals; @@ -117,4 +118,14 @@ public static void compareResourceLimitGroups(List listOne, assertEquals(groupOne.getUpdatedAt(), groupTwo.getUpdatedAt()); } } + + public static void assertInflightValuesAreZero(ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService) { + assertEquals(0, resourceLimitGroupPersistenceService.getInflightCreateResourceLimitGroupRequestCount().get()); + Map inflightResourceMap = resourceLimitGroupPersistenceService.getInflightResourceLimitValues(); + if (inflightResourceMap != null) { + for (String resourceName: inflightResourceMap.keySet()) { + assertEquals(0, inflightResourceMap.get(resourceName).intValue()); + } + } + } } diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceServiceTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceServiceTests.java index 0e5149645501e..b8a09060cd3c1 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceServiceTests.java +++ b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceServiceTests.java @@ -24,21 +24,8 @@ import java.util.Set; import java.util.stream.Collectors; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.MONITOR; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.NAME_NONE_EXISTED; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.NAME_ONE; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.NAME_TWO; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.SANDBOX_MAX_SETTING_NAME; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.TIMESTAMP_ONE; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.clusterState; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.compareResourceLimitGroups; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.prepareSandboxPersistenceService; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupList; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupMap; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupOne; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupPersistenceService; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupTwo; import static org.mockito.Mockito.mock; +import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.*; public class ResourceLimitGroupPersistenceServiceTests extends OpenSearchTestCase { @@ -47,6 +34,7 @@ public void testGetSingleResourceLimitGroup() { assertEquals(1, groups.size()); ResourceLimitGroup resourceLimitGroup = groups.get(0); compareResourceLimitGroups(List.of(resourceLimitGroupOne), List.of(resourceLimitGroup)); + assertInflightValuesAreZero(resourceLimitGroupPersistenceService); } public void testGetAllResourceLimitGroups() { @@ -56,6 +44,7 @@ public void testGetAllResourceLimitGroups() { assertTrue(currentNAME.contains(NAME_ONE)); assertTrue(currentNAME.contains(NAME_TWO)); compareResourceLimitGroups(resourceLimitGroupList, res); + assertInflightValuesAreZero(resourceLimitGroupPersistenceService); } public void testGetZeroResourceLimitGroups() { @@ -68,6 +57,7 @@ public void testGetZeroResourceLimitGroups() { ); List res = sandboxPersistenceService.getFromClusterStateMetadata(NAME_NONE_EXISTED, clusterState); assertEquals(0, res.size()); + assertInflightValuesAreZero(resourceLimitGroupPersistenceService); } public void testDeleteSingleResourceLimitGroup() { @@ -76,12 +66,14 @@ public void testDeleteSingleResourceLimitGroup() { assertEquals(1, afterDeletionGroups.size()); List oldSandbox = List.of(resourceLimitGroupMap.get(NAME_ONE)); compareResourceLimitGroups(new ArrayList<>(afterDeletionGroups.values()), oldSandbox); + assertInflightValuesAreZero(resourceLimitGroupPersistenceService); } public void testDeleteAllResourceLimitGroups() { ClusterState newClusterState = resourceLimitGroupPersistenceService.deleteResourceLimitGroupInClusterState(null, clusterState); Map sandboxes = newClusterState.getMetadata().resourceLimitGroups(); assertEquals(0, sandboxes.size()); + assertInflightValuesAreZero(resourceLimitGroupPersistenceService); } public void testDeleteNonExistedResourceLimitGroup() { @@ -92,31 +84,36 @@ public void testDeleteNonExistedResourceLimitGroup() { } public void testUpdateResourceLimitGroupAllFields() { - ResourceLimitGroup current = resourceLimitGroupOne; - ResourceLimitGroup updated = resourceLimitGroupTwo; + String updatedTime = "2024-04-28 23:02:22"; + ResourceLimitGroup updated = new ResourceLimitGroup( + NAME_ONE, + UUID_ONE, + List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.15)), + MONITOR, + TIMESTAMP_ONE, + updatedTime + ); ClusterState newClusterState = resourceLimitGroupPersistenceService.updateResourceLimitGroupInClusterState( - current, updated, clusterState ); List updatedSandboxes = new ArrayList<>(newClusterState.getMetadata().resourceLimitGroups().values()); - assertEquals(1, updatedSandboxes.size()); - compareResourceLimitGroups(List.of(updated), updatedSandboxes); + assertEquals(2, updatedSandboxes.size()); + compareResourceLimitGroups(List.of(resourceLimitGroupTwo, updated), updatedSandboxes); + assertInflightValuesAreZero(resourceLimitGroupPersistenceService); } public void testUpdateResourceLimitGroupResourceLimitOnly() { - ResourceLimitGroup current = resourceLimitGroupOne; String updatedTime = "2024-04-28 23:02:21"; ResourceLimitGroup updated = new ResourceLimitGroup( NAME_ONE, resourceLimitGroupOne.getUUID(), - List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.1)), + List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.13)), MONITOR, TIMESTAMP_ONE, updatedTime ); ClusterState newClusterState = resourceLimitGroupPersistenceService.updateResourceLimitGroupInClusterState( - current, updated, clusterState ); @@ -125,6 +122,7 @@ public void testUpdateResourceLimitGroupResourceLimitOnly() { assertTrue(updatedSandboxesMap.containsKey(NAME_ONE)); assertTrue(updatedSandboxesMap.containsKey(NAME_TWO)); compareResourceLimitGroups(List.of(updated), List.of(updatedSandboxesMap.get(NAME_ONE))); + assertInflightValuesAreZero(resourceLimitGroupPersistenceService); } public void testCreateResourceLimitGroup() { @@ -139,6 +137,7 @@ public void testCreateResourceLimitGroup() { assertEquals(1, updatedGroupsMap.size()); assertTrue(updatedGroupsMap.containsKey(NAME_ONE)); compareResourceLimitGroups(List.of(resourceLimitGroupOne), List.of(updatedGroupsMap.get(NAME_ONE))); + assertInflightValuesAreZero(resourceLimitGroupPersistenceService); } public void testCreateAnotherResourceLimitGroup() { @@ -152,6 +151,7 @@ public void testCreateAnotherResourceLimitGroup() { Map updatedGroupsMap = newClusterState.getMetadata().resourceLimitGroups(); assertEquals(2, updatedGroupsMap.size()); compareResourceLimitGroups(resourceLimitGroupList, new ArrayList<>(updatedGroupsMap.values())); + assertInflightValuesAreZero(resourceLimitGroupPersistenceService); } public void testCreateResourceLimitGroupDuplicateName() { From 43dec36ae2c699d36d947dc51861401d7440e405 Mon Sep 17 00:00:00 2001 From: Ruirui Zhang Date: Fri, 14 Jun 2024 14:36:20 -0700 Subject: [PATCH 12/15] modify CRUD API to fit the new schema and change name to QueryGroup Signed-off-by: Ruirui Zhang --- .../build.gradle | 4 +- .../plugin/qg/CreateQueryGroupAction.java | 36 ++ .../plugin/qg/CreateQueryGroupRequest.java | 321 ++++++++++++ .../plugin/qg/CreateQueryGroupResponse.java} | 45 +- .../plugin/qg/DeleteQueryGroupAction.java | 37 ++ .../plugin/qg/DeleteQueryGroupRequest.java | 74 +++ .../plugin/qg/DeleteQueryGroupResponse.java} | 47 +- .../plugin/qg/GetQueryGroupAction.java | 37 ++ .../plugin/qg/GetQueryGroupRequest.java | 74 +++ .../plugin/qg/GetQueryGroupResponse.java} | 49 +- .../plugin/qg/QueryGroupPlugin.java} | 34 +- .../plugin/qg/QueryGroupPluginModule.java | 32 ++ .../qg/TransportCreateQueryGroupAction.java | 65 +++ .../qg/TransportDeleteQueryGroupAction.java} | 32 +- .../qg/TransportGetQueryGroupAction.java | 58 +++ .../qg/TransportUpdateQueryGroupAction.java | 57 +++ .../plugin/qg/UpdateQueryGroupAction.java | 36 ++ .../plugin/qg/UpdateQueryGroupRequest.java | 261 ++++++++++ .../plugin/qg/UpdateQueryGroupResponse.java} | 45 +- .../opensearch/plugin/qg}/package-info.java | 4 +- .../qg/rest/RestCreateQueryGroupAction.java | 80 +++ .../qg/rest/RestDeleteQueryGroupAction.java} | 32 +- .../qg/rest/RestGetQueryGroupAction.java} | 32 +- .../qg/rest/RestUpdateQueryGroupAction.java | 80 +++ .../plugin/qg/rest/package-info.java | 12 + .../plugin/qg/service/Persistable.java | 50 ++ .../service/QueryGroupPersistenceService.java | 438 +++++++++++++++++ .../plugin/qg/service/package-info.java | 12 + .../qg/CreateQueryGroupRequestTests.java | 96 ++++ .../qg/CreateQueryGroupResponseTests.java | 32 ++ .../qg/DeleteQueryGroupRequestTests.java} | 16 +- .../qg/DeleteQueryGroupResponseTests.java | 67 +++ .../plugin/qg/GetQueryGroupRequestTests.java} | 16 +- .../plugin/qg/GetQueryGroupResponseTests.java | 64 +++ .../plugin/qg/QueryGroupTestUtils.java | 125 +++++ .../qg/UpdateQueryGroupRequestTests.java | 119 +++++ .../qg/UpdateQueryGroupResponseTests.java | 32 ++ .../QueryGroupPersistenceServiceTests.java | 237 +++++++++ .../rlg/CreateResourceLimitGroupAction.java | 36 -- .../rlg/CreateResourceLimitGroupRequest.java | 182 ------- .../rlg/DeleteResourceLimitGroupAction.java | 37 -- .../rlg/DeleteResourceLimitGroupRequest.java | 93 ---- .../rlg/GetResourceLimitGroupAction.java | 37 -- .../rlg/GetResourceLimitGroupRequest.java | 93 ---- .../rlg/ResourceLimitGroupPluginModule.java | 33 -- ...ansportCreateResourceLimitGroupAction.java | 72 --- ...ansportDeleteResourceLimitGroupAction.java | 64 --- ...ansportUpdateResourceLimitGroupAction.java | 72 --- .../rlg/UpdateResourceLimitGroupAction.java | 36 -- .../rlg/UpdateResourceLimitGroupRequest.java | 159 ------ .../RestCreateResourceLimitGroupAction.java | 85 ---- .../RestUpdateResourceLimitGroupAction.java | 83 ---- .../plugin/rlg/rest/package-info.java | 12 - .../plugin/rlg/service/Persistable.java | 51 -- .../ResourceLimitGroupPersistenceService.java | 464 ------------------ .../plugin/rlg/service/package-info.java | 16 - .../CreateResourceLimitGroupRequestTests.java | 35 -- ...CreateResourceLimitGroupResponseTests.java | 35 -- ...DeleteResourceLimitGroupResponseTests.java | 67 --- .../GetResourceLimitGroupResponseTests.java | 68 --- .../rlg/ResourceLimitGroupTestUtils.java | 131 ----- .../UpdateResourceLimitGroupRequestTests.java | 73 --- ...UpdateResourceLimitGroupResponseTests.java | 35 -- ...urceLimitGroupPersistenceServiceTests.java | 217 -------- .../org/opensearch/cluster/ClusterModule.java | 10 +- .../opensearch/cluster/metadata/Metadata.java | 52 +- .../cluster/metadata/QueryGroup.java | 315 ++++++++++++ ...pMetadata.java => QueryGroupMetadata.java} | 140 +++--- .../cluster/metadata/ResourceLimitGroup.java | 364 -------------- .../common/settings/ClusterSettings.java | 10 +- .../QueryGroupPruner.java} | 10 +- .../QueryGroupService.java} | 44 +- .../QueryGroupServiceSettings.java} | 64 +-- .../QueryGroupRequestCanceller.java} | 8 +- .../cancellation/package-info.java | 2 +- .../query_group/module/QueryGroupModule.java | 33 ++ .../module/package-info.java | 2 +- .../package-info.java | 2 +- .../QueryGroupResourceUsageTracker.java | 19 + ...ueryGroupResourceUsageTrackerService.java} | 42 +- .../tracker/package-info.java | 2 +- .../module/ResourceLimitGroupModule.java | 33 -- ...esourceLimitGroupResourceUsageTracker.java | 19 - .../metadata/QueryGroupMetadataTests.java | 43 ++ .../cluster/metadata/QueryGroupTests.java | 144 ++++++ ...esourceLimitGroupServiceSettingsTests.java | 126 ----- .../ResourceLimitGroupTests.java | 136 ----- 87 files changed, 3461 insertions(+), 3333 deletions(-) rename plugins/{query-resource-limit-group => query-group}/build.gradle (73%) create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupAction.java create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupRequest.java rename plugins/{query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupResponse.java => query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupResponse.java} (52%) create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupAction.java create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupRequest.java rename plugins/{query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupResponse.java => query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupResponse.java} (53%) create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupAction.java create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupRequest.java rename plugins/{query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupResponse.java => query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupResponse.java} (52%) rename plugins/{query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/ResourceLimitGroupPlugin.java => query-group/src/main/java/org/opensearch/plugin/qg/QueryGroupPlugin.java} (55%) create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/QueryGroupPluginModule.java create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportCreateQueryGroupAction.java rename plugins/{query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportGetResourceLimitGroupAction.java => query-group/src/main/java/org/opensearch/plugin/qg/TransportDeleteQueryGroupAction.java} (50%) create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportGetQueryGroupAction.java create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportUpdateQueryGroupAction.java create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupAction.java create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupRequest.java rename plugins/{query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupResponse.java => query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupResponse.java} (52%) rename plugins/{query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg => query-group/src/main/java/org/opensearch/plugin/qg}/package-info.java (71%) create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestCreateQueryGroupAction.java rename plugins/{query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestDeleteResourceLimitGroupAction.java => query-group/src/main/java/org/opensearch/plugin/qg/rest/RestDeleteQueryGroupAction.java} (53%) rename plugins/{query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestGetResourceLimitGroupAction.java => query-group/src/main/java/org/opensearch/plugin/qg/rest/RestGetQueryGroupAction.java} (54%) create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestUpdateQueryGroupAction.java create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/package-info.java create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/Persistable.java create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/QueryGroupPersistenceService.java create mode 100644 plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/package-info.java create mode 100644 plugins/query-group/src/test/java/org/opensearch/plugin/qg/CreateQueryGroupRequestTests.java create mode 100644 plugins/query-group/src/test/java/org/opensearch/plugin/qg/CreateQueryGroupResponseTests.java rename plugins/{query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/GetResourceLimitGroupRequestTests.java => query-group/src/test/java/org/opensearch/plugin/qg/DeleteQueryGroupRequestTests.java} (61%) create mode 100644 plugins/query-group/src/test/java/org/opensearch/plugin/qg/DeleteQueryGroupResponseTests.java rename plugins/{query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupRequestTests.java => query-group/src/test/java/org/opensearch/plugin/qg/GetQueryGroupRequestTests.java} (60%) create mode 100644 plugins/query-group/src/test/java/org/opensearch/plugin/qg/GetQueryGroupResponseTests.java create mode 100644 plugins/query-group/src/test/java/org/opensearch/plugin/qg/QueryGroupTestUtils.java create mode 100644 plugins/query-group/src/test/java/org/opensearch/plugin/qg/UpdateQueryGroupRequestTests.java create mode 100644 plugins/query-group/src/test/java/org/opensearch/plugin/qg/UpdateQueryGroupResponseTests.java create mode 100644 plugins/query-group/src/test/java/org/opensearch/plugin/qg/service/QueryGroupPersistenceServiceTests.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupAction.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupRequest.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupAction.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupRequest.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupAction.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupRequest.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/ResourceLimitGroupPluginModule.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportCreateResourceLimitGroupAction.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportDeleteResourceLimitGroupAction.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportUpdateResourceLimitGroupAction.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupAction.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupRequest.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestCreateResourceLimitGroupAction.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestUpdateResourceLimitGroupAction.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/package-info.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/Persistable.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceService.java delete mode 100644 plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/package-info.java delete mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupRequestTests.java delete mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupResponseTests.java delete mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupResponseTests.java delete mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/GetResourceLimitGroupResponseTests.java delete mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/ResourceLimitGroupTestUtils.java delete mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupRequestTests.java delete mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupResponseTests.java delete mode 100644 plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceServiceTests.java create mode 100644 server/src/main/java/org/opensearch/cluster/metadata/QueryGroup.java rename server/src/main/java/org/opensearch/cluster/metadata/{ResourceLimitGroupMetadata.java => QueryGroupMetadata.java} (52%) delete mode 100644 server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java rename server/src/main/java/org/opensearch/search/{resource_limit_group/ResourceLimitGroupPruner.java => query_group/QueryGroupPruner.java} (53%) rename server/src/main/java/org/opensearch/search/{resource_limit_group/ResourceLimitGroupService.java => query_group/QueryGroupService.java} (53%) rename server/src/main/java/org/opensearch/search/{resource_limit_group/ResourceLimitGroupServiceSettings.java => query_group/QueryGroupServiceSettings.java} (72%) rename server/src/main/java/org/opensearch/search/{resource_limit_group/cancellation/ResourceLimitGroupRequestCanceller.java => query_group/cancellation/QueryGroupRequestCanceller.java} (61%) rename server/src/main/java/org/opensearch/search/{resource_limit_group => query_group}/cancellation/package-info.java (79%) create mode 100644 server/src/main/java/org/opensearch/search/query_group/module/QueryGroupModule.java rename server/src/main/java/org/opensearch/search/{resource_limit_group => query_group}/module/package-info.java (79%) rename server/src/main/java/org/opensearch/search/{resource_limit_group => query_group}/package-info.java (82%) create mode 100644 server/src/main/java/org/opensearch/search/query_group/tracker/QueryGroupResourceUsageTracker.java rename server/src/main/java/org/opensearch/search/{resource_limit_group/tracker/ResourceLimitsGroupResourceUsageTrackerService.java => query_group/tracker/QueryGroupResourceUsageTrackerService.java} (79%) rename server/src/main/java/org/opensearch/search/{resource_limit_group => query_group}/tracker/package-info.java (81%) delete mode 100644 server/src/main/java/org/opensearch/search/resource_limit_group/module/ResourceLimitGroupModule.java delete mode 100644 server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitGroupResourceUsageTracker.java create mode 100644 server/src/test/java/org/opensearch/cluster/metadata/QueryGroupMetadataTests.java create mode 100644 server/src/test/java/org/opensearch/cluster/metadata/QueryGroupTests.java delete mode 100644 server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettingsTests.java delete mode 100644 server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupTests.java diff --git a/plugins/query-resource-limit-group/build.gradle b/plugins/query-group/build.gradle similarity index 73% rename from plugins/query-resource-limit-group/build.gradle rename to plugins/query-group/build.gradle index d4d05c5b3c6a8..a90f895966786 100644 --- a/plugins/query-resource-limit-group/build.gradle +++ b/plugins/query-group/build.gradle @@ -10,8 +10,8 @@ */ opensearchplugin { - description 'OpenSearch ResourceLimitGroup Plugin.' - classname 'org.opensearch.plugin.rlg.ResourceLimitGroupPlugin' + description 'OpenSearch QueryGroup Plugin.' + classname 'org.opensearch.plugin.qg.QueryGroupPlugin' } dependencies { diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupAction.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupAction.java new file mode 100644 index 0000000000000..fc0c143a8f218 --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupAction.java @@ -0,0 +1,36 @@ +/* + * 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.qg; + +import org.opensearch.action.ActionType; + +/** + * Rest action to create QueryGroup + * + * @opensearch.api + */ +public class CreateQueryGroupAction extends ActionType { + + /** + * An instance of CreateQueryGroupAction + */ + public static final CreateQueryGroupAction INSTANCE = new CreateQueryGroupAction(); + + /** + * Name for CreateQueryGroupAction + */ + public static final String NAME = "cluster:admin/opensearch/query_group/_create"; + + /** + * Default constructor + */ + private CreateQueryGroupAction() { + super(NAME, CreateQueryGroupResponse::new); + } +} diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupRequest.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupRequest.java new file mode 100644 index 0000000000000..33a17593cf625 --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupRequest.java @@ -0,0 +1,321 @@ +/* + * 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.qg; + +import org.opensearch.action.ActionRequest; +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.cluster.metadata.QueryGroup; +import org.opensearch.cluster.metadata.QueryGroup.QueryGroupMode; +import org.opensearch.common.UUIDs; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.common.io.stream.Writeable; +import org.opensearch.core.xcontent.XContentParser; +import org.joda.time.Instant; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; + +import static org.opensearch.cluster.metadata.QueryGroup.ALLOWED_RESOURCES; +import static org.opensearch.cluster.metadata.QueryGroup.MAX_CHARS_ALLOWED_IN_NAME; + +/** + * A request for create QueryGroup + * User input schema: + * { + * "jvm": 0.4, + * "mode": "enforced", + * "name": "analytics" + * } + * + * @opensearch.internal + */ +public class CreateQueryGroupRequest extends ActionRequest implements Writeable.Reader { + private String name; + private String _id; + private QueryGroupMode mode; + private Map resourceLimits; + private long updatedAtInMillis; + + /** + * Default constructor for CreateQueryGroupRequest + */ + public CreateQueryGroupRequest() {} + + /** + * Constructor for CreateQueryGroupRequest + * @param queryGroup - A {@link QueryGroup} object + */ + public CreateQueryGroupRequest(QueryGroup queryGroup) { + this.name = queryGroup.getName(); + this._id = queryGroup.get_id(); + this.resourceLimits = queryGroup.getResourceLimits(); + this.mode = queryGroup.getMode(); + this.updatedAtInMillis = queryGroup.getUpdatedAtInMillis(); + verifyCreateQueryGroupRequest(name, _id, mode, resourceLimits, updatedAtInMillis); + } + + /** + * Constructor for CreateQueryGroupRequest + * @param name - QueryGroup name for CreateQueryGroupRequest + * @param _id - QueryGroup _id for CreateQueryGroupRequest + * @param mode - QueryGroup mode for CreateQueryGroupRequest + * @param resourceLimits - QueryGroup resourceLimits for CreateQueryGroupRequest + * @param updatedAtInMillis - QueryGroup updated time in millis for CreateQueryGroupRequest + */ + public CreateQueryGroupRequest( + String name, + String _id, + QueryGroupMode mode, + Map resourceLimits, + long updatedAtInMillis + ) { + this.name = name; + this._id = _id; + this.resourceLimits = resourceLimits; + this.mode = mode; + this.updatedAtInMillis = updatedAtInMillis; + verifyCreateQueryGroupRequest(name, _id, mode, resourceLimits, updatedAtInMillis); + } + + /** + * Constructor for CreateQueryGroupRequest + * @param in - A {@link StreamInput} object + */ + public CreateQueryGroupRequest(StreamInput in) throws IOException { + super(in); + name = in.readString(); + _id = in.readString(); + mode = QueryGroupMode.fromName(in.readString()); + resourceLimits = in.readMap(); + updatedAtInMillis = in.readLong(); + verifyCreateQueryGroupRequest(name, _id, mode, resourceLimits, updatedAtInMillis); + } + + /** + * Verification for CreateQueryGroupRequest + * @param name - QueryGroup name for CreateQueryGroupRequest + * @param _id - QueryGroup _id for CreateQueryGroupRequest + * @param mode - QueryGroup mode for CreateQueryGroupRequest + * @param resourceLimits - QueryGroup resourceLimits for CreateQueryGroupRequest + * @param updatedAtInMillis - QueryGroup updated time in millis for CreateQueryGroupRequest + */ + private void verifyCreateQueryGroupRequest( + String name, + String _id, + QueryGroupMode mode, + Map resourceLimits, + long updatedAtInMillis + ) { + Objects.requireNonNull(_id, "QueryGroup._id can't be null"); + Objects.requireNonNull(name, "QueryGroup.name can't be null"); + Objects.requireNonNull(resourceLimits, "QueryGroup.resourceLimits can't be null"); + Objects.requireNonNull(mode, "QueryGroup.mode can't be null"); + Objects.requireNonNull(updatedAtInMillis, "QueryGroup.updatedAtInMillis can't be null"); + + validateName(name); + validateResourceLimits(resourceLimits); + validateUpdatedAtInMillis(updatedAtInMillis); + } + + /** + * Verification for CreateQueryGroupRequest.name + * @param name - name to be verified + */ + public static void validateName(String name) { + if (name.isEmpty()) { + throw new IllegalArgumentException("QueryGroup.name cannot be empty"); + } + if (name.length() > MAX_CHARS_ALLOWED_IN_NAME) { + throw new IllegalArgumentException("QueryGroup.name shouldn't be more than 50 chars long"); + } + if (name.startsWith("-") || name.startsWith("_")) { + throw new IllegalArgumentException("QueryGroup.name cannot start with '_' or '-'."); + } + if (name.matches(".*[ ,:\"*+/\\\\|?#><].*")) { + throw new IllegalArgumentException("QueryGroup.name can't contain spaces, commas, quotes, slashes, :, *, +, |, ?, #, >, or <"); + } + } + + /** + * Verification for CreateQueryGroupRequest.resourceLimits + * @param resourceLimits - resourceLimits to be verified + */ + public static void validateResourceLimits(Map resourceLimits) { + if (resourceLimits.isEmpty()) { + throw new IllegalArgumentException("QueryGroup.resourceLimits should at least have 1 resource limit."); + } + for (Map.Entry resource : resourceLimits.entrySet()) { + String resourceName = resource.getKey(); + Double threshold = (Double) resource.getValue(); + Objects.requireNonNull(resourceName, "resourceName can't be null"); + Objects.requireNonNull(threshold, "resource value can't be null"); + + if (threshold < 0 || threshold > 1) { + throw new IllegalArgumentException("Resource value should be between 0 and 1"); + } + String str = String.valueOf(threshold); + if (str.contains(".") && str.split("\\.")[1].length() > 2) { + throw new IllegalArgumentException("Resource value should have at most two digits after the decimal point"); + } + if (!ALLOWED_RESOURCES.contains(resourceName.toLowerCase(Locale.ROOT))) { + throw new IllegalArgumentException( + "resource has to be valid, valid resources are: " + ALLOWED_RESOURCES.stream().reduce((x, e) -> x + ", " + e).get() + ); + } + } + } + + /** + * Verification for CreateQueryGroupRequest.updatedAtInMillis + * @param updatedAt - updated time to be verified + */ + public static void validateUpdatedAtInMillis(long updatedAt) { + long minValidTimestamp = Instant.ofEpochMilli(0L).getMillis(); + long currentSeconds = Instant.now().getMillis(); + if (minValidTimestamp > updatedAt || updatedAt > currentSeconds) { + throw new IllegalArgumentException("QueryGroup.updatedAtInMillis is not a valid epoch"); + } + } + + @Override + public CreateQueryGroupRequest read(StreamInput in) throws IOException { + return new CreateQueryGroupRequest(in); + } + + /** + * Generate a CreateQueryGroupRequest from XContent + * @param parser - A {@link XContentParser} object + */ + public static CreateQueryGroupRequest fromXContent(XContentParser parser) throws IOException { + + while (parser.currentToken() != XContentParser.Token.START_OBJECT) { + parser.nextToken(); + } + + if (parser.currentToken() != XContentParser.Token.START_OBJECT) { + throw new IllegalArgumentException("expected start object but got a " + parser.currentToken()); + } + + XContentParser.Token token; + String fieldName = ""; + String name = null; + String _id = UUIDs.randomBase64UUID(); + QueryGroupMode mode = null; + long updatedAtInMillis = Instant.now().getMillis(); + + // Map to hold resources + final Map resourceLimits_ = new HashMap<>(); + while ((token = parser.nextToken()) != null) { + if (token == XContentParser.Token.FIELD_NAME) { + fieldName = parser.currentName(); + } else if (token.isValue()) { + if (fieldName.equals("name")) { + name = parser.text(); + } else if (fieldName.equals("mode")) { + mode = QueryGroupMode.fromName(parser.text()); + } else if (ALLOWED_RESOURCES.contains(fieldName)) { + resourceLimits_.put(fieldName, parser.doubleValue()); + } else { + throw new IllegalArgumentException("unrecognised [field=" + fieldName + " in QueryGroup"); + } + } + } + return new CreateQueryGroupRequest(name, _id, mode, resourceLimits_, updatedAtInMillis); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + /** + * name getter + */ + public String getName() { + return name; + } + + /** + * name setter + * @param name - name to be set + */ + public void setName(String name) { + this.name = name; + } + + /** + * resourceLimits getter + */ + public Map getResourceLimits() { + return resourceLimits; + } + + /** + * resourceLimits setter + * @param resourceLimits - resourceLimit to be set + */ + public void setResourceLimits(Map resourceLimits) { + this.resourceLimits = resourceLimits; + } + + /** + * mode getter + */ + public QueryGroupMode getMode() { + return mode; + } + + /** + * mode setter + * @param mode - mode to be set + */ + public void setMode(QueryGroupMode mode) { + this.mode = mode; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + QueryGroup.writeToOutputStream(out, name, _id, mode, resourceLimits, updatedAtInMillis); + } + + /** + * _id getter + */ + public String get_id() { + return _id; + } + + /** + * UUID setter + * @param _id - _id to be set + */ + public void set_id(String _id) { + this._id = _id; + } + + /** + * updatedAtInMillis getter + */ + public long getUpdatedAtInMillis() { + return updatedAtInMillis; + } + + /** + * updatedAtInMillis setter + * @param updatedAtInMillis - updatedAtInMillis to be set + */ + public void setUpdatedAtInMillis(long updatedAtInMillis) { + this.updatedAtInMillis = updatedAtInMillis; + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupResponse.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupResponse.java similarity index 52% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupResponse.java rename to plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupResponse.java index 530500b22a507..b431706960e42 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupResponse.java +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupResponse.java @@ -6,9 +6,9 @@ * compatible open source license. */ -package org.opensearch.plugin.rlg; +package org.opensearch.plugin.qg; -import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.core.action.ActionResponse; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.core.common.io.stream.StreamOutput; @@ -20,53 +20,58 @@ import java.io.IOException; /** - * Response for the create API for resource limit groups + * Response for the create API for QueryGroup * * @opensearch.internal */ -public class CreateResourceLimitGroupResponse extends ActionResponse implements ToXContent, ToXContentObject { - private final ResourceLimitGroup resourceLimitGroup; +public class CreateQueryGroupResponse extends ActionResponse implements ToXContent, ToXContentObject { + private final QueryGroup queryGroup; private RestStatus restStatus; /** - * Constructor for CreateResourceLimitGroupResponse + * Constructor for CreateQueryGroupResponse */ - public CreateResourceLimitGroupResponse() { - this.resourceLimitGroup = null; + public CreateQueryGroupResponse() { + this.queryGroup = null; } /** - * Constructor for CreateResourceLimitGroupResponse - * @param resourceLimitGroup - The resource limit group to be created + * Constructor for CreateQueryGroupResponse + * @param queryGroup - The resource limit group to be created */ - public CreateResourceLimitGroupResponse(final ResourceLimitGroup resourceLimitGroup) { - this.resourceLimitGroup = resourceLimitGroup; + public CreateQueryGroupResponse(final QueryGroup queryGroup) { + this.queryGroup = queryGroup; } /** - * Constructor for CreateResourceLimitGroupResponse + * Constructor for CreateQueryGroupResponse * @param in - A {@link StreamInput} object */ - public CreateResourceLimitGroupResponse(StreamInput in) throws IOException { - resourceLimitGroup = new ResourceLimitGroup(in); + public CreateQueryGroupResponse(StreamInput in) throws IOException { + queryGroup = new QueryGroup(in); } @Override public void writeTo(StreamOutput out) throws IOException { - resourceLimitGroup.writeTo(out); + queryGroup.writeTo(out); } @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - resourceLimitGroup.toXContent(builder, params); + builder.startObject(); + builder.field("name", queryGroup.getName()); + builder.field("mode", queryGroup.getMode().getName()); + builder.field("updatedAt", queryGroup.getUpdatedAtInMillis()); + builder.mapContents(queryGroup.getResourceLimits()); + builder.endObject(); return builder; } /** - * resourceLimitGroup getter + * queryGroup getter */ - public ResourceLimitGroup getResourceLimitGroup() { - return resourceLimitGroup; + public QueryGroup getQueryGroup() { + return queryGroup; } /** diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupAction.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupAction.java new file mode 100644 index 0000000000000..2d5acc49c7cf3 --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupAction.java @@ -0,0 +1,37 @@ +/* + * 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.qg; + +import org.opensearch.action.ActionType; + +/** + * Rest action to delete QueryGroup + * + * @opensearch.api + */ +public class DeleteQueryGroupAction extends ActionType { + + /** + /** + * An instance of DeleteQueryGroupAction + */ + public static final DeleteQueryGroupAction INSTANCE = new DeleteQueryGroupAction(); + + /** + * Name for DeleteQueryGroupAction + */ + public static final String NAME = "cluster:admin/opensearch/query_group/_delete"; + + /** + * Default constructor + */ + private DeleteQueryGroupAction() { + super(NAME, DeleteQueryGroupResponse::new); + } +} diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupRequest.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupRequest.java new file mode 100644 index 0000000000000..eb35bb3a2c80e --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupRequest.java @@ -0,0 +1,74 @@ +/* + * 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.qg; + +import org.opensearch.action.ActionRequest; +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.common.io.stream.Writeable; + +import java.io.IOException; + +/** + * A request for delete QueryGroup + * + * @opensearch.internal + */ +public class DeleteQueryGroupRequest extends ActionRequest implements Writeable.Reader { + String name; + + /** + * Default constructor for DeleteQueryGroupRequest + * @param name - name for the QueryGroup to get + */ + public DeleteQueryGroupRequest(String name) { + this.name = name; + } + + /** + * Constructor for DeleteQueryGroupRequest + * @param in - A {@link StreamInput} object + */ + public DeleteQueryGroupRequest(StreamInput in) throws IOException { + super(in); + name = in.readOptionalString(); + } + + @Override + public DeleteQueryGroupRequest read(StreamInput in) throws IOException { + return new DeleteQueryGroupRequest(in); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + /** + * Name getter + */ + public String getName() { + return name; + } + + /** + * Name setter + * @param name - name to be set + */ + public void setName(String name) { + this.name = name; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeOptionalString(name); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupResponse.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupResponse.java similarity index 53% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupResponse.java rename to plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupResponse.java index 995863439b596..37e97a490908e 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupResponse.java +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupResponse.java @@ -6,9 +6,9 @@ * compatible open source license. */ -package org.opensearch.plugin.rlg; +package org.opensearch.plugin.qg; -import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.core.action.ActionResponse; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.core.common.io.stream.StreamOutput; @@ -21,48 +21,53 @@ import java.util.List; /** - * Response for the delete API for resource limit groups + * Response for the delete API for QueryGroup * * @opensearch.internal */ -public class DeleteResourceLimitGroupResponse extends ActionResponse implements ToXContent, ToXContentObject { - private final List resourceLimitGroups; +public class DeleteQueryGroupResponse extends ActionResponse implements ToXContent, ToXContentObject { + private final List queryGroups; private RestStatus restStatus; /** - * Constructor for DeleteResourceLimitGroupResponse + * Constructor for DeleteQueryGroupResponse */ - public DeleteResourceLimitGroupResponse() { - this.resourceLimitGroups = null; + public DeleteQueryGroupResponse() { + this.queryGroups = null; } /** - * Constructor for DeleteResourceLimitGroupResponse - * @param resourceLimitGroups - The resource limit group list to be fetched + * Constructor for DeleteQueryGroupResponse + * @param queryGroups - The QueryGroup list to be fetched */ - public DeleteResourceLimitGroupResponse(final List resourceLimitGroups) { - this.resourceLimitGroups = resourceLimitGroups; + public DeleteQueryGroupResponse(final List queryGroups) { + this.queryGroups = queryGroups; } /** - * Constructor for DeleteResourceLimitGroupResponse + * Constructor for DeleteQueryGroupResponse * @param in - A {@link StreamInput} object */ - public DeleteResourceLimitGroupResponse(StreamInput in) throws IOException { - this.resourceLimitGroups = in.readList(ResourceLimitGroup::new); + public DeleteQueryGroupResponse(StreamInput in) throws IOException { + this.queryGroups = in.readList(QueryGroup::new); } @Override public void writeTo(StreamOutput out) throws IOException { - out.writeList(resourceLimitGroups); + out.writeList(queryGroups); } @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); builder.startArray("deleted"); - for (ResourceLimitGroup rlg : resourceLimitGroups) { - rlg.toXContent(builder, params); + for (QueryGroup group : queryGroups) { + builder.startObject(); + builder.field("name", group.getName()); + builder.field("mode", group.getMode().getName()); + builder.field("updatedAt", group.getUpdatedAtInMillis()); + builder.mapContents(group.getResourceLimits()); + builder.endObject(); } builder.endArray(); builder.endObject(); @@ -70,10 +75,10 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws } /** - * resourceLimitGroup getter + * queryGroups getter */ - public List getResourceLimitGroups() { - return resourceLimitGroups; + public List getQueryGroups() { + return queryGroups; } /** diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupAction.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupAction.java new file mode 100644 index 0000000000000..8da51a4f13be7 --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupAction.java @@ -0,0 +1,37 @@ +/* + * 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.qg; + +import org.opensearch.action.ActionType; + +/** + * Rest action to get QueryGroup + * + * @opensearch.api + */ +public class GetQueryGroupAction extends ActionType { + + /** + /** + * An instance of GetQueryGroupAction + */ + public static final GetQueryGroupAction INSTANCE = new GetQueryGroupAction(); + + /** + * Name for GetQueryGroupAction + */ + public static final String NAME = "cluster:admin/opensearch/query_group/_get"; + + /** + * Default constructor + */ + private GetQueryGroupAction() { + super(NAME, GetQueryGroupResponse::new); + } +} diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupRequest.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupRequest.java new file mode 100644 index 0000000000000..f49cd3b3a9922 --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupRequest.java @@ -0,0 +1,74 @@ +/* + * 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.qg; + +import org.opensearch.action.ActionRequest; +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.common.io.stream.Writeable; + +import java.io.IOException; + +/** + * A request for get QueryGroup + * + * @opensearch.internal + */ +public class GetQueryGroupRequest extends ActionRequest implements Writeable.Reader { + String name; + + /** + * Default constructor for GetQueryGroupRequest + * @param name - name for the QueryGroup to get + */ + public GetQueryGroupRequest(String name) { + this.name = name; + } + + /** + * Constructor for GetQueryGroupRequest + * @param in - A {@link StreamInput} object + */ + public GetQueryGroupRequest(StreamInput in) throws IOException { + super(in); + name = in.readOptionalString(); + } + + @Override + public GetQueryGroupRequest read(StreamInput in) throws IOException { + return new GetQueryGroupRequest(in); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + /** + * Name getter + */ + public String getName() { + return name; + } + + /** + * Name setter + * @param name - name to be set + */ + public void setName(String name) { + this.name = name; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeOptionalString(name); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupResponse.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupResponse.java similarity index 52% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupResponse.java rename to plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupResponse.java index 99bc92f6f5cd3..452da52d9861f 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupResponse.java +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupResponse.java @@ -6,9 +6,9 @@ * compatible open source license. */ -package org.opensearch.plugin.rlg; +package org.opensearch.plugin.qg; -import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.core.action.ActionResponse; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.core.common.io.stream.StreamOutput; @@ -21,48 +21,53 @@ import java.util.List; /** - * Response for the get API for resource limit groups + * Response for the get API for QueryGroup * * @opensearch.internal */ -public class GetResourceLimitGroupResponse extends ActionResponse implements ToXContent, ToXContentObject { - private final List resourceLimitGroups; +public class GetQueryGroupResponse extends ActionResponse implements ToXContent, ToXContentObject { + private final List queryGroups; private RestStatus restStatus; /** - * Constructor for GetResourceLimitGroupResponse + * Constructor for GetQueryGroupResponse */ - public GetResourceLimitGroupResponse() { - this.resourceLimitGroups = null; + public GetQueryGroupResponse() { + this.queryGroups = null; } /** - * Constructor for GetResourceLimitGroupResponse - * @param resourceLimitGroups - The resource limit group list to be fetched + * Constructor for GetQueryGroupResponse + * @param queryGroups - The QueryGroup list to be fetched */ - public GetResourceLimitGroupResponse(final List resourceLimitGroups) { - this.resourceLimitGroups = resourceLimitGroups; + public GetQueryGroupResponse(final List queryGroups) { + this.queryGroups = queryGroups; } /** - * Constructor for GetResourceLimitGroupResponse + * Constructor for GetQueryGroupResponse * @param in - A {@link StreamInput} object */ - public GetResourceLimitGroupResponse(StreamInput in) throws IOException { - this.resourceLimitGroups = in.readList(ResourceLimitGroup::new); + public GetQueryGroupResponse(StreamInput in) throws IOException { + this.queryGroups = in.readList(QueryGroup::new); } @Override public void writeTo(StreamOutput out) throws IOException { - out.writeList(resourceLimitGroups); + out.writeList(queryGroups); } @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); - builder.startArray("resource_limit_groups"); - for (ResourceLimitGroup rlg : resourceLimitGroups) { - rlg.toXContent(builder, params); + builder.startArray("query_groups"); + for (QueryGroup group : queryGroups) { + builder.startObject(); + builder.field("name", group.getName()); + builder.field("mode", group.getMode().getName()); + builder.field("updatedAt", group.getUpdatedAtInMillis()); + builder.mapContents(group.getResourceLimits()); + builder.endObject(); } builder.endArray(); builder.endObject(); @@ -70,10 +75,10 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws } /** - * resourceLimitGroup getter + * queryGroups getter */ - public List getResourceLimitGroups() { - return resourceLimitGroups; + public List getQueryGroups() { + return queryGroups; } /** diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/ResourceLimitGroupPlugin.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/QueryGroupPlugin.java similarity index 55% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/ResourceLimitGroupPlugin.java rename to plugins/query-group/src/main/java/org/opensearch/plugin/qg/QueryGroupPlugin.java index 3a41762b4e7b5..78295b26da93a 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/ResourceLimitGroupPlugin.java +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/QueryGroupPlugin.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.rlg; +package org.opensearch.plugin.qg; import org.opensearch.action.ActionRequest; import org.opensearch.cluster.metadata.IndexNameExpressionResolver; @@ -17,10 +17,10 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.settings.SettingsFilter; import org.opensearch.core.action.ActionResponse; -import org.opensearch.plugin.rlg.rest.RestCreateResourceLimitGroupAction; -import org.opensearch.plugin.rlg.rest.RestDeleteResourceLimitGroupAction; -import org.opensearch.plugin.rlg.rest.RestGetResourceLimitGroupAction; -import org.opensearch.plugin.rlg.rest.RestUpdateResourceLimitGroupAction; +import org.opensearch.plugin.qg.rest.RestCreateQueryGroupAction; +import org.opensearch.plugin.qg.rest.RestDeleteQueryGroupAction; +import org.opensearch.plugin.qg.rest.RestGetQueryGroupAction; +import org.opensearch.plugin.qg.rest.RestUpdateQueryGroupAction; import org.opensearch.plugins.ActionPlugin; import org.opensearch.plugins.Plugin; import org.opensearch.rest.RestController; @@ -31,22 +31,22 @@ import java.util.function.Supplier; /** - * Plugin class for Resource Limit Group + * Plugin class for QueryGroup */ -public class ResourceLimitGroupPlugin extends Plugin implements ActionPlugin { +public class QueryGroupPlugin extends Plugin implements ActionPlugin { /** * Default constructor */ - public ResourceLimitGroupPlugin() {} + public QueryGroupPlugin() {} @Override public List> getActions() { return List.of( - new ActionPlugin.ActionHandler<>(CreateResourceLimitGroupAction.INSTANCE, TransportCreateResourceLimitGroupAction.class), - new ActionPlugin.ActionHandler<>(GetResourceLimitGroupAction.INSTANCE, TransportGetResourceLimitGroupAction.class), - new ActionPlugin.ActionHandler<>(UpdateResourceLimitGroupAction.INSTANCE, TransportUpdateResourceLimitGroupAction.class), - new ActionPlugin.ActionHandler<>(DeleteResourceLimitGroupAction.INSTANCE, TransportDeleteResourceLimitGroupAction.class) + new ActionPlugin.ActionHandler<>(CreateQueryGroupAction.INSTANCE, TransportCreateQueryGroupAction.class), + new ActionPlugin.ActionHandler<>(GetQueryGroupAction.INSTANCE, TransportGetQueryGroupAction.class), + new ActionPlugin.ActionHandler<>(UpdateQueryGroupAction.INSTANCE, TransportUpdateQueryGroupAction.class), + new ActionPlugin.ActionHandler<>(DeleteQueryGroupAction.INSTANCE, TransportDeleteQueryGroupAction.class) ); } @@ -61,15 +61,15 @@ public List getRestHandlers( Supplier nodesInCluster ) { return List.of( - new RestCreateResourceLimitGroupAction(), - new RestGetResourceLimitGroupAction(), - new RestUpdateResourceLimitGroupAction(), - new RestDeleteResourceLimitGroupAction() + new RestCreateQueryGroupAction(), + new RestGetQueryGroupAction(), + new RestUpdateQueryGroupAction(), + new RestDeleteQueryGroupAction() ); } @Override public Collection createGuiceModules() { - return List.of(new ResourceLimitGroupPluginModule()); + return List.of(new QueryGroupPluginModule()); } } diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/QueryGroupPluginModule.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/QueryGroupPluginModule.java new file mode 100644 index 0000000000000..379ca9372fe60 --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/QueryGroupPluginModule.java @@ -0,0 +1,32 @@ +/* + * 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.qg; + +import org.opensearch.cluster.metadata.QueryGroup; +import org.opensearch.common.inject.AbstractModule; +import org.opensearch.common.inject.TypeLiteral; +import org.opensearch.plugin.qg.service.Persistable; +import org.opensearch.plugin.qg.service.QueryGroupPersistenceService; + +/** + * Guice Module to manage QueryGroup related objects + */ +public class QueryGroupPluginModule extends AbstractModule { + + /** + * Constructor for QueryGroupPluginModule + */ + public QueryGroupPluginModule() {} + + @Override + protected void configure() { + bind(new TypeLiteral>() { + }).to(QueryGroupPersistenceService.class).asEagerSingleton(); + } +} diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportCreateQueryGroupAction.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportCreateQueryGroupAction.java new file mode 100644 index 0000000000000..a146dcbaa671e --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportCreateQueryGroupAction.java @@ -0,0 +1,65 @@ +/* + * 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.qg; + +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.cluster.metadata.QueryGroup; +import org.opensearch.common.inject.Inject; +import org.opensearch.core.action.ActionListener; +import org.opensearch.plugin.qg.service.Persistable; +import org.opensearch.tasks.Task; +import org.opensearch.threadpool.ThreadPool; +import org.opensearch.transport.TransportService; + +import static org.opensearch.cluster.metadata.QueryGroup.builder; + +/** + * Transport action for create QueryGroup + * + * @opensearch.internal + */ +public class TransportCreateQueryGroupAction extends HandledTransportAction { + + private final ThreadPool threadPool; + private final Persistable queryGroupPersistenceService; + + /** + * Constructor for TransportCreateQueryGroupAction + * + * @param actionName - action name + * @param transportService - a {@link TransportService} object + * @param actionFilters - a {@link ActionFilters} object + * @param threadPool - a {@link ThreadPool} object + * @param queryGroupPersistenceService - a {@link Persistable} object + */ + @Inject + public TransportCreateQueryGroupAction( + String actionName, + TransportService transportService, + ActionFilters actionFilters, + ThreadPool threadPool, + Persistable queryGroupPersistenceService + ) { + super(CreateQueryGroupAction.NAME, transportService, actionFilters, CreateQueryGroupRequest::new); + this.threadPool = threadPool; + this.queryGroupPersistenceService = queryGroupPersistenceService; + } + + @Override + protected void doExecute(Task task, CreateQueryGroupRequest request, ActionListener listener) { + QueryGroup queryGroup = builder().name(request.getName()) + ._id(request.get_id()) + .mode(request.getMode().getName()) + .resourceLimits(request.getResourceLimits()) + .updatedAt(request.getUpdatedAtInMillis()) + .build(); + threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> queryGroupPersistenceService.persist(queryGroup, listener)); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportGetResourceLimitGroupAction.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportDeleteQueryGroupAction.java similarity index 50% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportGetResourceLimitGroupAction.java rename to plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportDeleteQueryGroupAction.java index ba2ff776770fe..c0237fd832c98 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportGetResourceLimitGroupAction.java +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportDeleteQueryGroupAction.java @@ -6,55 +6,53 @@ * compatible open source license. */ -package org.opensearch.plugin.rlg; +package org.opensearch.plugin.qg; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; -import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.common.inject.Inject; import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.rlg.service.Persistable; +import org.opensearch.plugin.qg.service.Persistable; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportService; /** - * Transport action for get Resource Limit Group + * Transport action for delete QueryGroup * * @opensearch.internal */ -public class TransportGetResourceLimitGroupAction extends HandledTransportAction< - GetResourceLimitGroupRequest, - GetResourceLimitGroupResponse> { +public class TransportDeleteQueryGroupAction extends HandledTransportAction { private final ThreadPool threadPool; - private final Persistable resourceLimitGroupPersistenceService; + private final Persistable queryGroupPersistenceService; /** - * Constructor for TransportGetResourceLimitGroupAction + * Constructor for TransportDeleteQueryGroupAction * - * @param actionName - acrtion name + * @param actionName - action name * @param transportService - a {@link TransportService} object * @param actionFilters - a {@link ActionFilters} object * @param threadPool - a {@link ThreadPool} object - * @param resourceLimitGroupPersistenceService - a {@link Persistable} object + * @param queryGroupPersistenceService - a {@link Persistable} object */ @Inject - public TransportGetResourceLimitGroupAction( + public TransportDeleteQueryGroupAction( String actionName, TransportService transportService, ActionFilters actionFilters, ThreadPool threadPool, - Persistable resourceLimitGroupPersistenceService + Persistable queryGroupPersistenceService ) { - super(GetResourceLimitGroupAction.NAME, transportService, actionFilters, GetResourceLimitGroupRequest::new); + super(DeleteQueryGroupAction.NAME, transportService, actionFilters, DeleteQueryGroupRequest::new); this.threadPool = threadPool; - this.resourceLimitGroupPersistenceService = resourceLimitGroupPersistenceService; + this.queryGroupPersistenceService = queryGroupPersistenceService; } @Override - protected void doExecute(Task task, GetResourceLimitGroupRequest request, ActionListener listener) { + protected void doExecute(Task task, DeleteQueryGroupRequest request, ActionListener listener) { String name = request.getName(); - threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> resourceLimitGroupPersistenceService.get(name, listener)); + threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> queryGroupPersistenceService.delete(name, listener)); } } diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportGetQueryGroupAction.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportGetQueryGroupAction.java new file mode 100644 index 0000000000000..11725891b5980 --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportGetQueryGroupAction.java @@ -0,0 +1,58 @@ +/* + * 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.qg; + +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.cluster.metadata.QueryGroup; +import org.opensearch.common.inject.Inject; +import org.opensearch.core.action.ActionListener; +import org.opensearch.plugin.qg.service.Persistable; +import org.opensearch.tasks.Task; +import org.opensearch.threadpool.ThreadPool; +import org.opensearch.transport.TransportService; + +/** + * Transport action for get QueryGroup + * + * @opensearch.internal + */ +public class TransportGetQueryGroupAction extends HandledTransportAction { + + private final ThreadPool threadPool; + private final Persistable queryGroupPersistenceService; + + /** + * Constructor for TransportGetQueryGroupAction + * + * @param actionName - action name + * @param transportService - a {@link TransportService} object + * @param actionFilters - a {@link ActionFilters} object + * @param threadPool - a {@link ThreadPool} object + * @param queryGroupPersistenceService - a {@link Persistable} object + */ + @Inject + public TransportGetQueryGroupAction( + String actionName, + TransportService transportService, + ActionFilters actionFilters, + ThreadPool threadPool, + Persistable queryGroupPersistenceService + ) { + super(GetQueryGroupAction.NAME, transportService, actionFilters, GetQueryGroupRequest::new); + this.threadPool = threadPool; + this.queryGroupPersistenceService = queryGroupPersistenceService; + } + + @Override + protected void doExecute(Task task, GetQueryGroupRequest request, ActionListener listener) { + String name = request.getName(); + threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> queryGroupPersistenceService.get(name, listener)); + } +} diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportUpdateQueryGroupAction.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportUpdateQueryGroupAction.java new file mode 100644 index 0000000000000..5cc0bd01ac418 --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportUpdateQueryGroupAction.java @@ -0,0 +1,57 @@ +/* + * 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.qg; + +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.cluster.metadata.QueryGroup; +import org.opensearch.common.inject.Inject; +import org.opensearch.core.action.ActionListener; +import org.opensearch.plugin.qg.service.Persistable; +import org.opensearch.tasks.Task; +import org.opensearch.threadpool.ThreadPool; +import org.opensearch.transport.TransportService; + +/** + * Transport action for update QueryGroup + * + * @opensearch.internal + */ +public class TransportUpdateQueryGroupAction extends HandledTransportAction { + + private final ThreadPool threadPool; + private final Persistable queryGroupPersistenceService; + + /** + * Constructor for TransportUpdateQueryGroupAction + * + * @param actionName - action name + * @param transportService - a {@link TransportService} object + * @param actionFilters - a {@link ActionFilters} object + * @param threadPool - a {@link ThreadPool} object + * @param queryGroupPersistenceService - a {@link Persistable} object + */ + @Inject + public TransportUpdateQueryGroupAction( + String actionName, + TransportService transportService, + ActionFilters actionFilters, + ThreadPool threadPool, + Persistable queryGroupPersistenceService + ) { + super(UpdateQueryGroupAction.NAME, transportService, actionFilters, UpdateQueryGroupRequest::new); + this.threadPool = threadPool; + this.queryGroupPersistenceService = queryGroupPersistenceService; + } + + @Override + protected void doExecute(Task task, UpdateQueryGroupRequest request, ActionListener listener) { + threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> queryGroupPersistenceService.update(request, listener)); + } +} diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupAction.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupAction.java new file mode 100644 index 0000000000000..f68e9b52ea160 --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupAction.java @@ -0,0 +1,36 @@ +/* + * 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.qg; + +import org.opensearch.action.ActionType; + +/** + * Rest action to update QueryGroup + * + * @opensearch.api + */ +public class UpdateQueryGroupAction extends ActionType { + + /** + * An instance of UpdateQueryGroupAction + */ + public static final UpdateQueryGroupAction INSTANCE = new UpdateQueryGroupAction(); + + /** + * Name for UpdateQueryGroupAction + */ + public static final String NAME = "cluster:admin/opensearch/query_group/_update"; + + /** + * Default constructor + */ + private UpdateQueryGroupAction() { + super(NAME, UpdateQueryGroupResponse::new); + } +} diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupRequest.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupRequest.java new file mode 100644 index 0000000000000..e447f2054b4d5 --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupRequest.java @@ -0,0 +1,261 @@ +/* + * 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.qg; + +import org.opensearch.action.ActionRequest; +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.cluster.metadata.QueryGroup; +import org.opensearch.cluster.metadata.QueryGroup.QueryGroupMode; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.common.io.stream.Writeable; +import org.opensearch.core.xcontent.XContentParser; +import org.joda.time.Instant; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; + +import static org.opensearch.cluster.metadata.QueryGroup.ALLOWED_RESOURCES; +import static org.opensearch.plugin.qg.CreateQueryGroupRequest.validateName; +import static org.opensearch.plugin.qg.CreateQueryGroupRequest.validateUpdatedAtInMillis; + +/** + * A request for update QueryGroup + * + * @opensearch.internal + */ +public class UpdateQueryGroupRequest extends ActionRequest implements Writeable.Reader { + String name; + Map resourceLimits; + QueryGroupMode mode; + long updatedAtInMillis; + + /** + * Default constructor for UpdateQueryGroupRequest + */ + public UpdateQueryGroupRequest() {} + + /** + * Constructor for UpdateQueryGroupRequest + * @param resourceLimitGroup - A {@link QueryGroup} object + */ + public UpdateQueryGroupRequest(QueryGroup resourceLimitGroup) { + this.name = resourceLimitGroup.getName(); + this.mode = resourceLimitGroup.getMode(); + this.resourceLimits = resourceLimitGroup.getResourceLimits(); + this.updatedAtInMillis = resourceLimitGroup.getUpdatedAtInMillis(); + verifyUpdateQueryGroupRequest(name, resourceLimits, updatedAtInMillis); + } + + /** + * Constructor for UpdateQueryGroupRequest + * @param name - QueryGroup name for UpdateQueryGroupRequest + * @param mode - QueryGroup mode for UpdateQueryGroupRequest + * @param resourceLimits - QueryGroup resourceLimits for UpdateQueryGroupRequest + * @param updatedAtInMillis - QueryGroup updated time in millis for UpdateQueryGroupRequest + */ + public UpdateQueryGroupRequest(String name, QueryGroupMode mode, Map resourceLimits, long updatedAtInMillis) { + this.name = name; + this.mode = mode; + this.resourceLimits = resourceLimits; + this.updatedAtInMillis = updatedAtInMillis; + verifyUpdateQueryGroupRequest(name, resourceLimits, updatedAtInMillis); + } + + /** + * Constructor for UpdateQueryGroupRequest + * @param in - A {@link StreamInput} object + */ + public UpdateQueryGroupRequest(StreamInput in) throws IOException { + super(in); + name = in.readString(); + if (in.readBoolean()) { + resourceLimits = in.readMap(); + } else { + resourceLimits = new HashMap<>(); + } + if (in.readBoolean()) { + mode = QueryGroupMode.fromName(in.readString()); + } + updatedAtInMillis = in.readLong(); + verifyUpdateQueryGroupRequest(name, resourceLimits, updatedAtInMillis); + } + + /** + * Verification for UpdateQueryGroupRequest + * @param name - QueryGroup name for UpdateQueryGroupRequest + * @param resourceLimits - QueryGroup resourceLimits for UpdateQueryGroupRequest + * @param updatedAtInMillis - QueryGroup updated time in millis for UpdateQueryGroupRequest + */ + private void verifyUpdateQueryGroupRequest(String name, Map resourceLimits, long updatedAtInMillis) { + Objects.requireNonNull(name, "QueryGroup.name can't be null"); + Objects.requireNonNull(resourceLimits, "QueryGroup.resourceLimits can't be null"); + Objects.requireNonNull(updatedAtInMillis, "QueryGroup.updatedAtInMillis can't be null"); + + validateName(name); + validateResourceLimits(resourceLimits); + validateUpdatedAtInMillis(updatedAtInMillis); + } + + /** + * Verification for resourceLimits + * @param resourceLimits - QueryGroup resourceLimits for UpdateQueryGroupRequest + */ + public static void validateResourceLimits(Map resourceLimits) { + if (resourceLimits == null) return; + for (Map.Entry resource : resourceLimits.entrySet()) { + String resourceName = resource.getKey(); + Double threshold = (Double) resource.getValue(); + Objects.requireNonNull(resourceName, "resourceName can't be null"); + Objects.requireNonNull(threshold, "resource value can't be null"); + + if (threshold < 0 || threshold > 1) { + throw new IllegalArgumentException("Resource value should be between 0 and 1"); + } + String str = String.valueOf(threshold); + if (str.contains(".") && str.split("\\.")[1].length() > 2) { + throw new IllegalArgumentException("Resource value should have at most two digits after the decimal point"); + } + if (!ALLOWED_RESOURCES.contains(resourceName.toLowerCase(Locale.ROOT))) { + throw new IllegalArgumentException( + "resource has to be valid, valid resources are: " + ALLOWED_RESOURCES.stream().reduce((x, e) -> x + ", " + e).get() + ); + } + } + } + + @Override + public UpdateQueryGroupRequest read(StreamInput in) throws IOException { + return new UpdateQueryGroupRequest(in); + } + + /** + * Generate a UpdateQueryGroupRequest from XContent + * @param parser - A {@link XContentParser} object + * @param name - name of the QueryGroup to be updated + */ + public static UpdateQueryGroupRequest fromXContent(XContentParser parser, String name) throws IOException { + while (parser.currentToken() != XContentParser.Token.START_OBJECT) { + parser.nextToken(); + } + + if (parser.currentToken() != XContentParser.Token.START_OBJECT) { + throw new IllegalArgumentException("expected start object but got a " + parser.currentToken()); + } + + XContentParser.Token token; + String fieldName = ""; + QueryGroupMode mode = null; + long updatedAtInMillis = Instant.now().getMillis(); + + // Map to hold resources + final Map resourceLimits_ = new HashMap<>(); + while ((token = parser.nextToken()) != null) { + if (token == XContentParser.Token.FIELD_NAME) { + fieldName = parser.currentName(); + } else if (token.isValue()) { + if (fieldName.equals("mode")) { + mode = QueryGroupMode.fromName(parser.text()); + } else if (ALLOWED_RESOURCES.contains(fieldName)) { + resourceLimits_.put(fieldName, parser.doubleValue()); + } else { + throw new IllegalArgumentException("unrecognised [field=" + fieldName + " in QueryGroup"); + } + } + } + return new UpdateQueryGroupRequest(name, mode, resourceLimits_, updatedAtInMillis); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + /** + * name getter + */ + public String getName() { + return name; + } + + /** + * name setter + * @param name - name to be set + */ + public void setName(String name) { + this.name = name; + } + + /** + * ResourceLimits getter + */ + public Map getResourceLimits() { + return resourceLimits; + } + + /** + * ResourceLimits setter + * @param resourceLimits - ResourceLimit to be set + */ + public void setResourceLimits(Map resourceLimits) { + this.resourceLimits = resourceLimits; + } + + /** + * Mode getter + */ + public QueryGroupMode getMode() { + return mode; + } + + /** + * Mode setter + * @param mode - mode to be set + */ + public void setMode(QueryGroupMode mode) { + this.mode = mode; + } + + /** + * updatedAtInMillis getter + */ + public long getUpdatedAtInMillis() { + return updatedAtInMillis; + } + + /** + * updatedAtInMillis setter + * @param updatedAtInMillis - updatedAtInMillis to be set + */ + public void setUpdatedAtInMillis(long updatedAtInMillis) { + this.updatedAtInMillis = updatedAtInMillis; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeString(name); + if (resourceLimits == null || resourceLimits.isEmpty()) { + out.writeBoolean(false); + } else { + out.writeBoolean(true); + out.writeMap(resourceLimits); + } + if (mode == null) { + out.writeBoolean(false); + } else { + out.writeBoolean(true); + out.writeString(mode.getName()); + } + out.writeLong(updatedAtInMillis); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupResponse.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupResponse.java similarity index 52% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupResponse.java rename to plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupResponse.java index 3f8a5e3c9c683..07387b9756f80 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupResponse.java +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupResponse.java @@ -6,9 +6,9 @@ * compatible open source license. */ -package org.opensearch.plugin.rlg; +package org.opensearch.plugin.qg; -import org.opensearch.cluster.metadata.ResourceLimitGroup; +import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.core.action.ActionResponse; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.core.common.io.stream.StreamOutput; @@ -20,53 +20,58 @@ import java.io.IOException; /** - * Response for the update API for resource limit groups + * Response for the update API for QueryGroup * * @opensearch.internal */ -public class UpdateResourceLimitGroupResponse extends ActionResponse implements ToXContent, ToXContentObject { - private final ResourceLimitGroup resourceLimitGroup; +public class UpdateQueryGroupResponse extends ActionResponse implements ToXContent, ToXContentObject { + private final QueryGroup queryGroup; private RestStatus restStatus; /** - * Constructor for UpdateResourceLimitGroupResponse + * Constructor for UpdateQueryGroupResponse */ - public UpdateResourceLimitGroupResponse() { - this.resourceLimitGroup = null; + public UpdateQueryGroupResponse() { + this.queryGroup = null; } /** - * Constructor for UpdateResourceLimitGroupResponse - * @param resourceLimitGroup - The resource limit group to be updated + * Constructor for UpdateQueryGroupResponse + * @param queryGroup - The QueryGroup to be updated */ - public UpdateResourceLimitGroupResponse(final ResourceLimitGroup resourceLimitGroup) { - this.resourceLimitGroup = resourceLimitGroup; + public UpdateQueryGroupResponse(final QueryGroup queryGroup) { + this.queryGroup = queryGroup; } /** - * Constructor for UpdateResourceLimitGroupResponse + * Constructor for UpdateQueryGroupResponse * @param in - A {@link StreamInput} object */ - public UpdateResourceLimitGroupResponse(StreamInput in) throws IOException { - resourceLimitGroup = new ResourceLimitGroup(in); + public UpdateQueryGroupResponse(StreamInput in) throws IOException { + queryGroup = new QueryGroup(in); } @Override public void writeTo(StreamOutput out) throws IOException { - resourceLimitGroup.writeTo(out); + queryGroup.writeTo(out); } @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - resourceLimitGroup.toXContent(builder, params); + builder.startObject(); + builder.field("name", queryGroup.getName()); + builder.field("mode", queryGroup.getMode().getName()); + builder.field("updatedAt", queryGroup.getUpdatedAtInMillis()); + builder.mapContents(queryGroup.getResourceLimits()); + builder.endObject(); return builder; } /** - * resourceLimitGroup getter + * queryGroup getter */ - public ResourceLimitGroup getResourceLimitGroup() { - return resourceLimitGroup; + public QueryGroup getQueryGroup() { + return queryGroup; } /** diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/package-info.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/package-info.java similarity index 71% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/package-info.java rename to plugins/query-group/src/main/java/org/opensearch/plugin/qg/package-info.java index 8db7a9c279a5b..11b69d6964ffc 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/package-info.java +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/package-info.java @@ -7,6 +7,6 @@ */ /** - * Base Package of CRUD API of resource limit group + * Base Package of CRUD API of QueryGroup */ -package org.opensearch.plugin.rlg; +package org.opensearch.plugin.qg; diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestCreateQueryGroupAction.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestCreateQueryGroupAction.java new file mode 100644 index 0000000000000..5256eded7861e --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestCreateQueryGroupAction.java @@ -0,0 +1,80 @@ +/* + * 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.qg.rest; + +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.plugin.qg.CreateQueryGroupAction; +import org.opensearch.plugin.qg.CreateQueryGroupRequest; +import org.opensearch.plugin.qg.CreateQueryGroupResponse; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.BytesRestResponse; +import org.opensearch.rest.RestChannel; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.RestResponse; +import org.opensearch.rest.action.RestResponseListener; + +import java.io.IOException; +import java.util.List; + +import static org.opensearch.rest.RestRequest.Method.POST; +import static org.opensearch.rest.RestRequest.Method.PUT; + +/** + * Rest action to create a QueryGroup + * + * @opensearch.api + */ +public class RestCreateQueryGroupAction extends BaseRestHandler { + + /** + * Constructor for RestCreateQueryGroupAction + */ + public RestCreateQueryGroupAction() {} + + @Override + public String getName() { + return "create_query_group"; + } + + /** + * The list of {@link Route}s that this RestHandler is responsible for handling. + */ + @Override + public List routes() { + return List.of(new Route(POST, "_query_group/"), new Route(PUT, "_query_group/")); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + CreateQueryGroupRequest createQueryGroupRequest = new CreateQueryGroupRequest(); + request.applyContentParser((parser) -> parseRestRequest(createQueryGroupRequest, parser)); + return channel -> client.execute(CreateQueryGroupAction.INSTANCE, createQueryGroupRequest, createQueryGroupResponse(channel)); + } + + private void parseRestRequest(CreateQueryGroupRequest request, XContentParser parser) throws IOException { + final CreateQueryGroupRequest createQueryGroupRequest = CreateQueryGroupRequest.fromXContent(parser); + request.setName(createQueryGroupRequest.getName()); + request.set_id(createQueryGroupRequest.get_id()); + request.setMode(createQueryGroupRequest.getMode()); + request.setResourceLimits(createQueryGroupRequest.getResourceLimits()); + request.setUpdatedAtInMillis(createQueryGroupRequest.getUpdatedAtInMillis()); + } + + private RestResponseListener createQueryGroupResponse(final RestChannel channel) { + return new RestResponseListener<>(channel) { + @Override + public RestResponse buildResponse(final CreateQueryGroupResponse response) throws Exception { + return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS)); + } + }; + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestDeleteResourceLimitGroupAction.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestDeleteQueryGroupAction.java similarity index 53% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestDeleteResourceLimitGroupAction.java rename to plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestDeleteQueryGroupAction.java index a0c213bbb7860..a5a775e120714 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestDeleteResourceLimitGroupAction.java +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestDeleteQueryGroupAction.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.plugin.rlg.rest; +package org.opensearch.plugin.qg.rest; import org.opensearch.client.node.NodeClient; import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.plugin.rlg.DeleteResourceLimitGroupAction; -import org.opensearch.plugin.rlg.DeleteResourceLimitGroupRequest; -import org.opensearch.plugin.rlg.DeleteResourceLimitGroupResponse; +import org.opensearch.plugin.qg.DeleteQueryGroupAction; +import org.opensearch.plugin.qg.DeleteQueryGroupRequest; +import org.opensearch.plugin.qg.DeleteQueryGroupResponse; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.RestChannel; @@ -27,20 +27,20 @@ import static org.opensearch.rest.RestRequest.Method.DELETE; /** - * Rest action to delete a resource limit group + * Rest action to delete a QueryGroup * * @opensearch.api */ -public class RestDeleteResourceLimitGroupAction extends BaseRestHandler { +public class RestDeleteQueryGroupAction extends BaseRestHandler { /** - * Constructor for RestDeleteResourceLimitGroupAction + * Constructor for RestDeleteQueryGroupAction */ - public RestDeleteResourceLimitGroupAction() {} + public RestDeleteQueryGroupAction() {} @Override public String getName() { - return "delete_resource_limit_group"; + return "delete_query_group"; } /** @@ -48,24 +48,20 @@ public String getName() { */ @Override public List routes() { - return List.of(new Route(DELETE, "_resource_limit_group/{name}"), new Route(DELETE, "_resource_limit_group/")); + return List.of(new Route(DELETE, "_query_group/{name}"), new Route(DELETE, "_query_group/")); } @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { String name = request.param("name"); - DeleteResourceLimitGroupRequest deleteResourceLimitGroupRequest = new DeleteResourceLimitGroupRequest(name); - return channel -> client.execute( - DeleteResourceLimitGroupAction.INSTANCE, - deleteResourceLimitGroupRequest, - deleteResourceLimitGroupResponse(channel) - ); + DeleteQueryGroupRequest deleteQueryGroupRequest = new DeleteQueryGroupRequest(name); + return channel -> client.execute(DeleteQueryGroupAction.INSTANCE, deleteQueryGroupRequest, deleteQueryGroupResponse(channel)); } - private RestResponseListener deleteResourceLimitGroupResponse(final RestChannel channel) { + private RestResponseListener deleteQueryGroupResponse(final RestChannel channel) { return new RestResponseListener<>(channel) { @Override - public RestResponse buildResponse(final DeleteResourceLimitGroupResponse response) throws Exception { + public RestResponse buildResponse(final DeleteQueryGroupResponse response) throws Exception { return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS)); } }; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestGetResourceLimitGroupAction.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestGetQueryGroupAction.java similarity index 54% rename from plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestGetResourceLimitGroupAction.java rename to plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestGetQueryGroupAction.java index d2dcf9e7d366c..9a216c07605c3 100644 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestGetResourceLimitGroupAction.java +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestGetQueryGroupAction.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.plugin.rlg.rest; +package org.opensearch.plugin.qg.rest; import org.opensearch.client.node.NodeClient; import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.plugin.rlg.GetResourceLimitGroupAction; -import org.opensearch.plugin.rlg.GetResourceLimitGroupRequest; -import org.opensearch.plugin.rlg.GetResourceLimitGroupResponse; +import org.opensearch.plugin.qg.GetQueryGroupAction; +import org.opensearch.plugin.qg.GetQueryGroupRequest; +import org.opensearch.plugin.qg.GetQueryGroupResponse; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.RestChannel; @@ -27,20 +27,20 @@ import static org.opensearch.rest.RestRequest.Method.GET; /** - * Rest action to get a resource limit group + * Rest action to get a QueryGroup0 * * @opensearch.api */ -public class RestGetResourceLimitGroupAction extends BaseRestHandler { +public class RestGetQueryGroupAction extends BaseRestHandler { /** - * Constructor for RestGetResourceLimitGroupAction + * Constructor for RestGetQueryGroupAction */ - public RestGetResourceLimitGroupAction() {} + public RestGetQueryGroupAction() {} @Override public String getName() { - return "get_resource_limit_group"; + return "get_query_group"; } /** @@ -48,24 +48,20 @@ public String getName() { */ @Override public List routes() { - return List.of(new Route(GET, "_resource_limit_group/{name}"), new Route(GET, "_resource_limit_group/")); + return List.of(new Route(GET, "_query_group/{name}"), new Route(GET, "_query_group/")); } @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { String name = request.param("name"); - GetResourceLimitGroupRequest getResourceLimitGroupRequest = new GetResourceLimitGroupRequest(name); - return channel -> client.execute( - GetResourceLimitGroupAction.INSTANCE, - getResourceLimitGroupRequest, - getResourceLimitGroupResponse(channel) - ); + GetQueryGroupRequest getQueryGroupRequest = new GetQueryGroupRequest(name); + return channel -> client.execute(GetQueryGroupAction.INSTANCE, getQueryGroupRequest, getQueryGroupResponse(channel)); } - private RestResponseListener getResourceLimitGroupResponse(final RestChannel channel) { + private RestResponseListener getQueryGroupResponse(final RestChannel channel) { return new RestResponseListener<>(channel) { @Override - public RestResponse buildResponse(final GetResourceLimitGroupResponse response) throws Exception { + public RestResponse buildResponse(final GetQueryGroupResponse response) throws Exception { return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS)); } }; diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestUpdateQueryGroupAction.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestUpdateQueryGroupAction.java new file mode 100644 index 0000000000000..7cec01987e875 --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestUpdateQueryGroupAction.java @@ -0,0 +1,80 @@ +/* + * 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.qg.rest; + +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.plugin.qg.UpdateQueryGroupAction; +import org.opensearch.plugin.qg.UpdateQueryGroupRequest; +import org.opensearch.plugin.qg.UpdateQueryGroupResponse; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.BytesRestResponse; +import org.opensearch.rest.RestChannel; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.RestResponse; +import org.opensearch.rest.action.RestResponseListener; + +import java.io.IOException; +import java.util.List; + +import static org.opensearch.rest.RestRequest.Method.POST; +import static org.opensearch.rest.RestRequest.Method.PUT; + +/** + * Rest action to update a QueryGroup + * + * @opensearch.api + */ +public class RestUpdateQueryGroupAction extends BaseRestHandler { + + /** + * Constructor for RestUpdateQueryGroupAction + */ + public RestUpdateQueryGroupAction() {} + + @Override + public String getName() { + return "update_query_group"; + } + + /** + * The list of {@link Route}s that this RestHandler is responsible for handling. + */ + @Override + public List routes() { + return List.of(new Route(POST, "_query_group/{name}"), new Route(PUT, "_query_group/{name}")); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + String name = request.param("name"); + UpdateQueryGroupRequest updateQueryGroupRequest = new UpdateQueryGroupRequest(); + request.applyContentParser((parser) -> parseRestRequest(updateQueryGroupRequest, parser, name)); + return channel -> client.execute(UpdateQueryGroupAction.INSTANCE, updateQueryGroupRequest, updateQueryGroupResponse(channel)); + } + + private void parseRestRequest(UpdateQueryGroupRequest request, XContentParser parser, String name) throws IOException { + final UpdateQueryGroupRequest updateQueryGroupRequest = UpdateQueryGroupRequest.fromXContent(parser, name); + request.setName(updateQueryGroupRequest.getName()); + request.setResourceLimits(updateQueryGroupRequest.getResourceLimits()); + request.setMode(updateQueryGroupRequest.getMode()); + request.setUpdatedAtInMillis(updateQueryGroupRequest.getUpdatedAtInMillis()); + } + + private RestResponseListener updateQueryGroupResponse(final RestChannel channel) { + return new RestResponseListener<>(channel) { + @Override + public RestResponse buildResponse(final UpdateQueryGroupResponse response) throws Exception { + return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS)); + } + }; + } +} diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/package-info.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/package-info.java new file mode 100644 index 0000000000000..630b03b1d82f1 --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/package-info.java @@ -0,0 +1,12 @@ +/* + * 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 for the rest classes for QueryGroup CRUD operations + */ +package org.opensearch.plugin.qg.rest; diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/Persistable.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/Persistable.java new file mode 100644 index 0000000000000..b973190f5122c --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/Persistable.java @@ -0,0 +1,50 @@ +/* + * 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.qg.service; + +import org.opensearch.core.action.ActionListener; +import org.opensearch.plugin.qg.CreateQueryGroupResponse; +import org.opensearch.plugin.qg.DeleteQueryGroupResponse; +import org.opensearch.plugin.qg.GetQueryGroupResponse; +import org.opensearch.plugin.qg.UpdateQueryGroupRequest; +import org.opensearch.plugin.qg.UpdateQueryGroupResponse; + +/** + * This interface defines the key APIs for implementing QueruGroup persistence + */ +public interface Persistable { + + /** + * persists the QueryGroup in a durable storage + * @param queryGroup + * @param listener + */ + void persist(T queryGroup, ActionListener listener); + + /** + * update the QueryGroup in a durable storage + * @param updateQueryGroupRequest + * @param listener + */ + void update(UpdateQueryGroupRequest updateQueryGroupRequest, ActionListener listener); + + /** + * fetch the QueryGroup in a durable storage + * @param name + * @param listener + */ + void get(String name, ActionListener listener); + + /** + * delete the QueryGroup in a durable storage + * @param name + * @param listener + */ + void delete(String name, ActionListener listener); +} diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/QueryGroupPersistenceService.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/QueryGroupPersistenceService.java new file mode 100644 index 0000000000000..776721cc4fe77 --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/QueryGroupPersistenceService.java @@ -0,0 +1,438 @@ +/* + * 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.qg.service; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.cluster.ClusterState; +import org.opensearch.cluster.ClusterStateUpdateTask; +import org.opensearch.cluster.metadata.Metadata; +import org.opensearch.cluster.metadata.QueryGroup; +import org.opensearch.cluster.metadata.QueryGroup.QueryGroupMode; +import org.opensearch.cluster.service.ClusterManagerTaskThrottler.ThrottlingKey; +import org.opensearch.cluster.service.ClusterService; +import org.opensearch.common.Priority; +import org.opensearch.common.inject.Inject; +import org.opensearch.common.settings.ClusterSettings; +import org.opensearch.common.settings.Settings; +import org.opensearch.core.action.ActionListener; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.plugin.qg.CreateQueryGroupResponse; +import org.opensearch.plugin.qg.DeleteQueryGroupResponse; +import org.opensearch.plugin.qg.GetQueryGroupResponse; +import org.opensearch.plugin.qg.UpdateQueryGroupRequest; +import org.opensearch.plugin.qg.UpdateQueryGroupResponse; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.DoubleAdder; + +import static org.opensearch.search.query_group.QueryGroupServiceSettings.MAX_QUERY_GROUP_COUNT; +import static org.opensearch.search.query_group.QueryGroupServiceSettings.QUERY_GROUP_COUNT_SETTING_NAME; + +/** + * This class defines the functions for QueryGroup persistence + */ +public class QueryGroupPersistenceService implements Persistable { + private static final Logger logger = LogManager.getLogger(QueryGroupPersistenceService.class); + private final ClusterService clusterService; + private static final String SOURCE = "query-group-persistence-service"; + private static final String CREATE_QUERY_GROUP_THROTTLING_KEY = "create-query-group"; + private static final String UPDATE_QUERY_GROUP_THROTTLING_KEY = "update-query-group"; + private static final String DELETE_QUERY_GROUP_THROTTLING_KEY = "delete-query-group"; + private final AtomicInteger inflightCreateQueryGroupRequestCount; + private final Map inflightResourceLimitValues; + private volatile int maxQueryGroupCount; + final ThrottlingKey createQueryGroupThrottlingKey; + final ThrottlingKey updateQueryGroupThrottlingKey; + final ThrottlingKey deleteQueryGroupThrottlingKey; + + /** + * Constructor for QueryGroupPersistenceService + * + * @param clusterService {@link ClusterService} - The cluster service to be used by QueryGroupPersistenceService + * @param settings {@link Settings} - The settings to be used by QueryGroupPersistenceService + * @param clusterSettings {@link ClusterSettings} - The cluster settings to be used by QueryGroupPersistenceService + */ + @Inject + public QueryGroupPersistenceService( + final ClusterService clusterService, + final Settings settings, + final ClusterSettings clusterSettings + ) { + this.clusterService = clusterService; + this.createQueryGroupThrottlingKey = clusterService.registerClusterManagerTask(CREATE_QUERY_GROUP_THROTTLING_KEY, true); + this.deleteQueryGroupThrottlingKey = clusterService.registerClusterManagerTask(DELETE_QUERY_GROUP_THROTTLING_KEY, true); + this.updateQueryGroupThrottlingKey = clusterService.registerClusterManagerTask(UPDATE_QUERY_GROUP_THROTTLING_KEY, true); + maxQueryGroupCount = MAX_QUERY_GROUP_COUNT.get(settings); + clusterSettings.addSettingsUpdateConsumer(MAX_QUERY_GROUP_COUNT, this::setMaxQueryGroupCount); + inflightCreateQueryGroupRequestCount = new AtomicInteger(); + inflightResourceLimitValues = new HashMap<>(); + } + + /** + * Set maxQueryGroupCount to be newMaxQueryGroupCount + * @param newMaxQueryGroupCount - the max number of QueryGroup allowed + */ + public void setMaxQueryGroupCount(int newMaxQueryGroupCount) { + if (newMaxQueryGroupCount < 0) { + throw new IllegalArgumentException("node.query_group.max_count can't be negative"); + } + this.maxQueryGroupCount = newMaxQueryGroupCount; + } + + @Override + public void persist(QueryGroup queryGroup, ActionListener listener) { + persistInClusterStateMetadata(queryGroup, listener); + } + + @Override + public void update(UpdateQueryGroupRequest updateQueryGroupRequest, ActionListener listener) { + updateInClusterStateMetadata(updateQueryGroupRequest, listener); + } + + @Override + public void get(String name, ActionListener listener) { + ClusterState currentState = clusterService.state(); + List resultGroups = getFromClusterStateMetadata(name, currentState); + if (resultGroups.isEmpty() && name != null && !name.isEmpty()) { + logger.warn("No QueryGroup exists with the provided name: {}", name); + Exception e = new RuntimeException("No QueryGroup exists with the provided name: " + name); + GetQueryGroupResponse response = new GetQueryGroupResponse(); + response.setRestStatus(RestStatus.NOT_FOUND); + listener.onFailure(e); + return; + } + GetQueryGroupResponse response = new GetQueryGroupResponse(resultGroups); + response.setRestStatus(RestStatus.OK); + listener.onResponse(response); + } + + @Override + public void delete(String name, ActionListener listener) { + deleteInClusterStateMetadata(name, listener); + } + + /** + * Update cluster state to include the new QueryGroup + * @param queryGroup {@link QueryGroup} - the QueryGroup we're currently creating + */ + void persistInClusterStateMetadata(QueryGroup queryGroup, ActionListener listener) { + clusterService.submitStateUpdateTask(SOURCE, new ClusterStateUpdateTask(Priority.URGENT) { + @Override + public ClusterState execute(ClusterState currentState) throws Exception { + return saveQueryGroupInClusterState(queryGroup, currentState); + } + + @Override + public ThrottlingKey getClusterManagerThrottlingKey() { + return createQueryGroupThrottlingKey; + } + + @Override + public void onFailure(String source, Exception e) { + restoreInflightValues(queryGroup.getResourceLimits()); + inflightCreateQueryGroupRequestCount.decrementAndGet(); + logger.warn("failed to save QueryGroup object due to error: {}, for source: {}", e.getMessage(), source); + CreateQueryGroupResponse response = new CreateQueryGroupResponse(); + response.setRestStatus(RestStatus.FAILED_DEPENDENCY); + listener.onFailure(e); + } + + @Override + public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { + restoreInflightValues(queryGroup.getResourceLimits()); + inflightCreateQueryGroupRequestCount.decrementAndGet(); + CreateQueryGroupResponse response = new CreateQueryGroupResponse(queryGroup); + response.setRestStatus(RestStatus.OK); + listener.onResponse(response); + } + }); + } + + /** + * Get the allocation value for resourceName for the QueryGroup + * @param resourceName - the resourceName we want to get the usage for + * @param resourceLimits - the resource limit from which to get the allocation value for resourceName + */ + private double getResourceLimitValue(String resourceName, final Map resourceLimits) { + return (double) resourceLimits.getOrDefault(resourceName, 0.0); + } + + /** + * This method will be executed before we submit the new cluster state + * @param queryGroup - the QueryGroup we're currently creating + * @param currentClusterState - the cluster state before the update + */ + ClusterState saveQueryGroupInClusterState(final QueryGroup queryGroup, final ClusterState currentClusterState) { + final Metadata metadata = currentClusterState.metadata(); + String groupName = queryGroup.getName(); + final Set previousGroups = metadata.queryGroups(); + + // check if there's any resource allocation that exceed limit of 1.0 + String resourceNameWithThresholdExceeded = ""; + for (String resourceName : queryGroup.getResourceLimits().keySet()) { + double existingUsage = calculateExistingUsage(resourceName, previousGroups, groupName); + double newGroupUsage = getResourceLimitValue(resourceName, queryGroup.getResourceLimits()); + inflightResourceLimitValues.computeIfAbsent(resourceName, k -> new DoubleAdder()).add(newGroupUsage); + double totalUsage = existingUsage + inflightResourceLimitValues.get(resourceName).doubleValue(); + if (totalUsage > 1) { + resourceNameWithThresholdExceeded = resourceName; + } + } + // check if group count exceed max + boolean groupCountExceeded = inflightCreateQueryGroupRequestCount.incrementAndGet() + previousGroups.size() > maxQueryGroupCount; + + if (previousGroups.stream().anyMatch(group -> group.getName().equals(groupName))) { + logger.warn("QueryGroup with name {} already exists. Not creating a new one.", groupName); + throw new RuntimeException("QueryGroup with name " + groupName + " already exists. Not creating a new one."); + } + if (!resourceNameWithThresholdExceeded.isEmpty()) { + logger.error("Total resource allocation for {} will go above the max limit of 1.0", resourceNameWithThresholdExceeded); + throw new RuntimeException( + "Total resource allocation for " + resourceNameWithThresholdExceeded + " will go above the max limit of 1.0" + ); + } + if (groupCountExceeded) { + logger.error("{} value exceeded its assigned limit of {}", QUERY_GROUP_COUNT_SETTING_NAME, maxQueryGroupCount); + throw new RuntimeException("Can't create more than " + maxQueryGroupCount + " QueryGroups in the system"); + } + Metadata newData = Metadata.builder(metadata).put(queryGroup).build(); + + return ClusterState.builder(currentClusterState).metadata(newData).build(); + } + + /** + * This method restores the inflight values to be before the QueryGroup is processed + * @param resourceLimits - the resourceLimits we're currently restoring + */ + void restoreInflightValues(Map resourceLimits) { + if (resourceLimits == null || resourceLimits.isEmpty()) { + return; + } + for (String currResourceName : resourceLimits.keySet()) { + inflightResourceLimitValues.get(currResourceName).add(-getResourceLimitValue(currResourceName, resourceLimits)); + } + } + + /** + * This method calculates the existing total usage of the resource (except the group that we're updating here) + * @param resourceName - the resource name we're calculating + * @param groupsList - existing QueryGroups + * @param groupName - the QueryGroup name we're updating + */ + private double calculateExistingUsage(String resourceName, Set groupsList, String groupName) { + double existingUsage = 0; + for (QueryGroup group : groupsList) { + if (!group.getName().equals(groupName)) { + existingUsage += getResourceLimitValue(resourceName, group.getResourceLimits()); + } + } + return existingUsage; + } + + /** + * Modify cluster state to update the QueryGroup + * @param toUpdateGroup {@link QueryGroup} - the QueryGroup that we want to update + */ + void updateInClusterStateMetadata(UpdateQueryGroupRequest toUpdateGroup, ActionListener listener) { + clusterService.submitStateUpdateTask(SOURCE, new ClusterStateUpdateTask(Priority.URGENT) { + @Override + public ClusterState execute(ClusterState currentState) { + return updateQueryGroupInClusterState(toUpdateGroup, currentState); + } + + @Override + public ThrottlingKey getClusterManagerThrottlingKey() { + return updateQueryGroupThrottlingKey; + } + + @Override + public void onFailure(String source, Exception e) { + restoreInflightValues(toUpdateGroup.getResourceLimits()); + logger.warn("Failed to update QueryGroup due to error: {}, for source: {}", e.getMessage(), source); + UpdateQueryGroupResponse response = new UpdateQueryGroupResponse(); + response.setRestStatus(RestStatus.FAILED_DEPENDENCY); + listener.onFailure(e); + } + + @Override + public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { + restoreInflightValues(toUpdateGroup.getResourceLimits()); + String name = toUpdateGroup.getName(); + Optional findUpdatedGroup = newState.metadata() + .queryGroups() + .stream() + .filter(group -> group.getName().equals(name)) + .findFirst(); + assert findUpdatedGroup.isPresent(); + QueryGroup updatedGroup = findUpdatedGroup.get(); + UpdateQueryGroupResponse response = new UpdateQueryGroupResponse(updatedGroup); + response.setRestStatus(RestStatus.OK); + listener.onResponse(response); + } + }); + } + + /** + * Modify cluster state to update the existing QueryGroup + * @param updateQueryGroupRequest {@link QueryGroup} - the QueryGroup that we want to update + * @param currentState - current cluster state + */ + public ClusterState updateQueryGroupInClusterState(UpdateQueryGroupRequest updateQueryGroupRequest, ClusterState currentState) { + final Metadata metadata = currentState.metadata(); + Set existingGroups = currentState.metadata().queryGroups(); + String name = updateQueryGroupRequest.getName(); + String resourceNameWithThresholdExceeded = ""; + + // check if there's any resource allocation that exceed limit of 1.0 + if (updateQueryGroupRequest.getResourceLimits() != null) { + for (String resourceName : updateQueryGroupRequest.getResourceLimits().keySet()) { + double existingUsage = calculateExistingUsage(resourceName, existingGroups, name); + double newGroupUsage = getResourceLimitValue(resourceName, updateQueryGroupRequest.getResourceLimits()); + inflightResourceLimitValues.computeIfAbsent(resourceName, k -> new DoubleAdder()).add(newGroupUsage); + double totalUsage = existingUsage + inflightResourceLimitValues.get(resourceName).doubleValue(); + if (totalUsage > 1) { + resourceNameWithThresholdExceeded = resourceName; + } + } + } + + Optional findExistingGroup = existingGroups.stream().filter(group -> group.getName().equals(name)).findFirst(); + + if (findExistingGroup.isEmpty()) { + logger.warn("No QueryGroup exists with the provided name: {}", name); + throw new RuntimeException("No QueryGroup exists with the provided name: " + name); + } + if (!resourceNameWithThresholdExceeded.isEmpty()) { + logger.error("Total resource allocation for {} will go above the max limit of 1.0", resourceNameWithThresholdExceeded); + throw new RuntimeException( + "Total resource allocation for " + resourceNameWithThresholdExceeded + " will go above the max limit of 1.0" + ); + } + + // build the QueryGroup with updated fields + QueryGroup existingGroup = findExistingGroup.get(); + String _id = existingGroup.get_id(); + long updatedAtInMillis = updateQueryGroupRequest.getUpdatedAtInMillis(); + Map existingResourceLimits = existingGroup.getResourceLimits(); + Map updatedResourceLimits = new HashMap<>(); + if (existingResourceLimits != null) { + updatedResourceLimits.putAll(existingResourceLimits); + } + if (updateQueryGroupRequest.getResourceLimits() != null) { + updatedResourceLimits.putAll(updateQueryGroupRequest.getResourceLimits()); + } + QueryGroupMode mode = updateQueryGroupRequest.getMode() == null ? existingGroup.getMode() : updateQueryGroupRequest.getMode(); + + QueryGroup updatedGroup = new QueryGroup(name, _id, mode, updatedResourceLimits, updatedAtInMillis); + return ClusterState.builder(currentState) + .metadata(Metadata.builder(metadata).remove(existingGroup).put(updatedGroup).build()) + .build(); + } + + /** + * Modify cluster state to delete the QueryGroup + * @param name - the name for QueryGroup to be deleted + */ + void deleteInClusterStateMetadata(String name, ActionListener listener) { + clusterService.submitStateUpdateTask(SOURCE, new ClusterStateUpdateTask(Priority.URGENT) { + @Override + public ClusterState execute(ClusterState currentState) throws Exception { + return deleteQueryGroupInClusterState(name, currentState); + } + + @Override + public ThrottlingKey getClusterManagerThrottlingKey() { + return deleteQueryGroupThrottlingKey; + } + + @Override + public void onFailure(String source, Exception e) { + logger.warn("Failed to delete QueryGroup due to error: {}, for source: {}", e.getMessage(), source); + DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(); + response.setRestStatus(RestStatus.NOT_FOUND); + listener.onFailure(e); + } + + @Override + public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { + final Set oldGroupsMap = oldState.metadata().queryGroups(); + final Set newGroupsMap = newState.metadata().queryGroups(); + List deletedGroups = new ArrayList<>(); + for (QueryGroup group : oldGroupsMap) { + if (!newGroupsMap.contains(group)) { + deletedGroups.add(group); + } + } + DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(deletedGroups); + response.setRestStatus(RestStatus.OK); + listener.onResponse(response); + } + }); + } + + /** + * Modify cluster state to delete the QueryGroup + * @param name - the name for QueryGroup to be deleted + * @param currentClusterState - current cluster state + */ + ClusterState deleteQueryGroupInClusterState(final String name, final ClusterState currentClusterState) { + final Metadata metadata = currentClusterState.metadata(); + final Set previousGroups = metadata.queryGroups(); + + if (name == null || name.isEmpty()) { // delete all + return ClusterState.builder(currentClusterState) + .metadata(Metadata.builder(metadata).queryGroups(new HashSet<>()).build()) + .build(); + } else { + Optional findExistingGroup = previousGroups.stream().filter(group -> group.getName().equals(name)).findFirst(); + if (findExistingGroup.isEmpty()) { + logger.error("The QueryGroup with provided name {} doesn't exist", name); + throw new RuntimeException("No QueryGroup exists with the provided name: " + name); + } + return ClusterState.builder(currentClusterState) + .metadata(Metadata.builder(metadata).remove(findExistingGroup.get()).build()) + .build(); + } + } + + List getFromClusterStateMetadata(String name, ClusterState currentState) { + Set currentGroups = currentState.getMetadata().queryGroups(); + List resultGroups = new ArrayList<>(); + if (name == null || name.isEmpty()) { + resultGroups = new ArrayList<>(currentGroups); + } + Optional findResultGroups = currentGroups.stream().filter(group -> group.getName().equals(name)).findFirst(); + if (findResultGroups.isPresent()) { + resultGroups = List.of(findResultGroups.get()); + } + return resultGroups; + } + + /** + * inflightCreateQueryGroupRequestCount getter + */ + public AtomicInteger getInflightCreateQueryGroupRequestCount() { + return inflightCreateQueryGroupRequestCount; + } + + /** + * inflightResourceLimitValues getter + */ + public Map getInflightResourceLimitValues() { + return inflightResourceLimitValues; + } +} diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/package-info.java b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/package-info.java new file mode 100644 index 0000000000000..3bb6e35d7b78e --- /dev/null +++ b/plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/package-info.java @@ -0,0 +1,12 @@ +/* + * 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 for the service classes for QueryGroup CRUD operations + */ +package org.opensearch.plugin.qg.service; diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/CreateQueryGroupRequestTests.java b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/CreateQueryGroupRequestTests.java new file mode 100644 index 0000000000000..d45a49b0bc4bc --- /dev/null +++ b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/CreateQueryGroupRequestTests.java @@ -0,0 +1,96 @@ +/* + * 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.qg; + +import org.opensearch.cluster.metadata.QueryGroup.QueryGroupMode; +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.test.OpenSearchTestCase; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static org.opensearch.plugin.qg.QueryGroupTestUtils.MONITOR; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.NAME_ONE; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.TIMESTAMP_ONE; +import static org.opensearch.plugin.qg.QueryGroupTestUtils._ID_ONE; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.compareResourceLimits; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupOne; + +public class CreateQueryGroupRequestTests extends OpenSearchTestCase { + + public void testSerialization() throws IOException { + CreateQueryGroupRequest request = new CreateQueryGroupRequest(queryGroupOne); + BytesStreamOutput out = new BytesStreamOutput(); + request.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + CreateQueryGroupRequest otherRequest = new CreateQueryGroupRequest(streamInput); + assertEquals(request.getName(), otherRequest.getName()); + assertEquals(request.getResourceLimits().size(), otherRequest.getResourceLimits().size()); + assertEquals(request.getMode(), otherRequest.getMode()); + compareResourceLimits(request.getResourceLimits(), otherRequest.getResourceLimits()); + assertEquals(request.getUpdatedAtInMillis(), otherRequest.getUpdatedAtInMillis()); + } + + public void testInvalidName() { + assertThrows( + IllegalArgumentException.class, + () -> new CreateQueryGroupRequest("", _ID_ONE, QueryGroupMode.fromName(MONITOR), Map.of("jvm", 0.3), TIMESTAMP_ONE) + ); + assertThrows( + IllegalArgumentException.class, + () -> new CreateQueryGroupRequest("-test", _ID_ONE, QueryGroupMode.fromName(MONITOR), Map.of("jvm", 0.3), TIMESTAMP_ONE) + ); + assertThrows( + IllegalArgumentException.class, + () -> new CreateQueryGroupRequest(":test", _ID_ONE, QueryGroupMode.fromName(MONITOR), Map.of("jvm", 0.3), TIMESTAMP_ONE) + ); + } + + public void testInvalidResourceLimitList() { + assertThrows( + IllegalArgumentException.class, + () -> new CreateQueryGroupRequest(NAME_ONE, _ID_ONE, QueryGroupMode.fromName(MONITOR), new HashMap<>(), TIMESTAMP_ONE) + ); + + assertThrows( + IllegalArgumentException.class, + () -> new CreateQueryGroupRequest( + NAME_ONE, + _ID_ONE, + QueryGroupMode.fromName(MONITOR), + Map.of("jvm", 0.3, "jvm", 0.4), + TIMESTAMP_ONE + ) + ); + + assertThrows( + IllegalArgumentException.class, + () -> new CreateQueryGroupRequest(NAME_ONE, _ID_ONE, QueryGroupMode.fromName(MONITOR), Map.of("jvm", -0.3), TIMESTAMP_ONE) + ); + + assertThrows( + IllegalArgumentException.class, + () -> new CreateQueryGroupRequest(NAME_ONE, _ID_ONE, QueryGroupMode.fromName(MONITOR), Map.of("jvm", 12.0), TIMESTAMP_ONE) + ); + + assertThrows( + IllegalArgumentException.class, + () -> new CreateQueryGroupRequest(NAME_ONE, _ID_ONE, QueryGroupMode.fromName(MONITOR), Map.of("cpu", 0.3), TIMESTAMP_ONE) + ); + } + + public void testInvalidEnforcement() { + assertThrows( + IllegalArgumentException.class, + () -> new CreateQueryGroupRequest(NAME_ONE, _ID_ONE, QueryGroupMode.fromName("random"), Map.of("jvm", 0.3), TIMESTAMP_ONE) + ); + } +} diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/CreateQueryGroupResponseTests.java b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/CreateQueryGroupResponseTests.java new file mode 100644 index 0000000000000..905e5b8648ed5 --- /dev/null +++ b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/CreateQueryGroupResponseTests.java @@ -0,0 +1,32 @@ +/* + * 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.qg; + +import org.opensearch.cluster.metadata.QueryGroup; +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.test.OpenSearchTestCase; + +import java.io.IOException; +import java.util.List; + +public class CreateQueryGroupResponseTests extends OpenSearchTestCase { + + public void testSerialization() throws IOException { + CreateQueryGroupResponse response = new CreateQueryGroupResponse(QueryGroupTestUtils.queryGroupOne); + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + CreateQueryGroupResponse otherResponse = new CreateQueryGroupResponse(streamInput); + assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); + QueryGroup responseGroup = response.getQueryGroup(); + QueryGroup otherResponseGroup = otherResponse.getQueryGroup(); + QueryGroupTestUtils.compareQueryGroups(List.of(responseGroup), List.of(otherResponseGroup)); + } +} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/GetResourceLimitGroupRequestTests.java b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/DeleteQueryGroupRequestTests.java similarity index 61% rename from plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/GetResourceLimitGroupRequestTests.java rename to plugins/query-group/src/test/java/org/opensearch/plugin/qg/DeleteQueryGroupRequestTests.java index bda42d7398957..de0ced93a2eaf 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/GetResourceLimitGroupRequestTests.java +++ b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/DeleteQueryGroupRequestTests.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.rlg; +package org.opensearch.plugin.qg; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.core.common.io.stream.StreamInput; @@ -14,27 +14,25 @@ import java.io.IOException; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.NAME_ONE; - -public class GetResourceLimitGroupRequestTests extends OpenSearchTestCase { +public class DeleteQueryGroupRequestTests extends OpenSearchTestCase { public void testSerialization() throws IOException { - GetResourceLimitGroupRequest request = new GetResourceLimitGroupRequest(NAME_ONE); - assertEquals(NAME_ONE, request.getName()); + DeleteQueryGroupRequest request = new DeleteQueryGroupRequest(QueryGroupTestUtils.NAME_ONE); + assertEquals(QueryGroupTestUtils.NAME_ONE, request.getName()); BytesStreamOutput out = new BytesStreamOutput(); request.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); - GetResourceLimitGroupRequest otherRequest = new GetResourceLimitGroupRequest(streamInput); + DeleteQueryGroupRequest otherRequest = new DeleteQueryGroupRequest(streamInput); assertEquals(request.getName(), otherRequest.getName()); } public void testSerializationWithNull() throws IOException { - GetResourceLimitGroupRequest request = new GetResourceLimitGroupRequest((String) null); + DeleteQueryGroupRequest request = new DeleteQueryGroupRequest((String) null); assertNull(request.getName()); BytesStreamOutput out = new BytesStreamOutput(); request.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); - GetResourceLimitGroupRequest otherRequest = new GetResourceLimitGroupRequest(streamInput); + DeleteQueryGroupRequest otherRequest = new DeleteQueryGroupRequest(streamInput); assertEquals(request.getName(), otherRequest.getName()); } } diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/DeleteQueryGroupResponseTests.java b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/DeleteQueryGroupResponseTests.java new file mode 100644 index 0000000000000..682dca443fc89 --- /dev/null +++ b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/DeleteQueryGroupResponseTests.java @@ -0,0 +1,67 @@ +/* + * 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.qg; + +import org.opensearch.cluster.metadata.QueryGroup; +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.test.OpenSearchTestCase; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static org.opensearch.plugin.qg.QueryGroupTestUtils.compareQueryGroups; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupList; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupOne; + +public class DeleteQueryGroupResponseTests extends OpenSearchTestCase { + + public void testSerializationSingleQueryGroup() throws IOException { + List list = List.of(queryGroupOne); + DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(list); + assertEquals(response.getQueryGroups(), list); + + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + + DeleteQueryGroupResponse otherResponse = new DeleteQueryGroupResponse(streamInput); + assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); + compareQueryGroups(response.getQueryGroups(), otherResponse.getQueryGroups()); + } + + public void testSerializationMultipleQueryGroup() throws IOException { + DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(queryGroupList()); + assertEquals(response.getQueryGroups(), queryGroupList()); + + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + + DeleteQueryGroupResponse otherResponse = new DeleteQueryGroupResponse(streamInput); + assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); + assertEquals(2, otherResponse.getQueryGroups().size()); + compareQueryGroups(response.getQueryGroups(), otherResponse.getQueryGroups()); + } + + public void testSerializationNull() throws IOException { + List list = new ArrayList<>(); + DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(list); + assertEquals(response.getQueryGroups(), list); + + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + + DeleteQueryGroupResponse otherResponse = new DeleteQueryGroupResponse(streamInput); + assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); + assertEquals(0, otherResponse.getQueryGroups().size()); + } +} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupRequestTests.java b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/GetQueryGroupRequestTests.java similarity index 60% rename from plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupRequestTests.java rename to plugins/query-group/src/test/java/org/opensearch/plugin/qg/GetQueryGroupRequestTests.java index 29c4f00d4ac4e..555c56abfa254 100644 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupRequestTests.java +++ b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/GetQueryGroupRequestTests.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.rlg; +package org.opensearch.plugin.qg; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.core.common.io.stream.StreamInput; @@ -14,27 +14,25 @@ import java.io.IOException; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.NAME_ONE; - -public class DeleteResourceLimitGroupRequestTests extends OpenSearchTestCase { +public class GetQueryGroupRequestTests extends OpenSearchTestCase { public void testSerialization() throws IOException { - DeleteResourceLimitGroupRequest request = new DeleteResourceLimitGroupRequest(NAME_ONE); - assertEquals(NAME_ONE, request.getName()); + GetQueryGroupRequest request = new GetQueryGroupRequest(QueryGroupTestUtils.NAME_ONE); + assertEquals(QueryGroupTestUtils.NAME_ONE, request.getName()); BytesStreamOutput out = new BytesStreamOutput(); request.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); - DeleteResourceLimitGroupRequest otherRequest = new DeleteResourceLimitGroupRequest(streamInput); + GetQueryGroupRequest otherRequest = new GetQueryGroupRequest(streamInput); assertEquals(request.getName(), otherRequest.getName()); } public void testSerializationWithNull() throws IOException { - DeleteResourceLimitGroupRequest request = new DeleteResourceLimitGroupRequest((String) null); + GetQueryGroupRequest request = new GetQueryGroupRequest((String) null); assertNull(request.getName()); BytesStreamOutput out = new BytesStreamOutput(); request.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); - DeleteResourceLimitGroupRequest otherRequest = new DeleteResourceLimitGroupRequest(streamInput); + GetQueryGroupRequest otherRequest = new GetQueryGroupRequest(streamInput); assertEquals(request.getName(), otherRequest.getName()); } } diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/GetQueryGroupResponseTests.java b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/GetQueryGroupResponseTests.java new file mode 100644 index 0000000000000..ca7035e3cdbb4 --- /dev/null +++ b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/GetQueryGroupResponseTests.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.qg; + +import org.opensearch.cluster.metadata.QueryGroup; +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.test.OpenSearchTestCase; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class GetQueryGroupResponseTests extends OpenSearchTestCase { + + public void testSerializationSingleQueryGroup() throws IOException { + List list = new ArrayList<>(); + list.add(QueryGroupTestUtils.queryGroupOne); + GetQueryGroupResponse response = new GetQueryGroupResponse(list); + assertEquals(response.getQueryGroups(), list); + + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + + GetQueryGroupResponse otherResponse = new GetQueryGroupResponse(streamInput); + assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); + QueryGroupTestUtils.compareQueryGroups(response.getQueryGroups(), otherResponse.getQueryGroups()); + } + + public void testSerializationMultipleQueryGroup() throws IOException { + GetQueryGroupResponse response = new GetQueryGroupResponse(QueryGroupTestUtils.queryGroupList()); + assertEquals(response.getQueryGroups(), QueryGroupTestUtils.queryGroupList()); + + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + + GetQueryGroupResponse otherResponse = new GetQueryGroupResponse(streamInput); + assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); + assertEquals(2, otherResponse.getQueryGroups().size()); + QueryGroupTestUtils.compareQueryGroups(response.getQueryGroups(), otherResponse.getQueryGroups()); + } + + public void testSerializationNull() throws IOException { + List list = new ArrayList<>(); + GetQueryGroupResponse response = new GetQueryGroupResponse(list); + assertEquals(response.getQueryGroups(), list); + + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + + GetQueryGroupResponse otherResponse = new GetQueryGroupResponse(streamInput); + assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); + assertEquals(0, otherResponse.getQueryGroups().size()); + } +} diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/QueryGroupTestUtils.java b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/QueryGroupTestUtils.java new file mode 100644 index 0000000000000..dd4ab97f34a0f --- /dev/null +++ b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/QueryGroupTestUtils.java @@ -0,0 +1,125 @@ +/* + * 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.qg; + +import org.opensearch.cluster.ClusterName; +import org.opensearch.cluster.ClusterState; +import org.opensearch.cluster.metadata.Metadata; +import org.opensearch.cluster.metadata.QueryGroup; +import org.opensearch.cluster.service.ClusterService; +import org.opensearch.common.settings.ClusterSettings; +import org.opensearch.common.settings.Settings; +import org.opensearch.plugin.qg.service.QueryGroupPersistenceService; +import org.opensearch.threadpool.ThreadPool; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.DoubleAdder; +import java.util.stream.Collectors; + +import static org.opensearch.cluster.metadata.QueryGroup.builder; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +public class QueryGroupTestUtils { + public static final String SANDBOX_MAX_SETTING_NAME = "node.sandbox.max_count"; + public static final String NAME_ONE = "sandbox_one"; + public static final String NAME_TWO = "sandbox_two"; + public static final String _ID_ONE = "AgfUO5Ja9yfsYlONlYi3TQ=="; + public static final String _ID_TWO = "G5iIqHy4g7eK1qIAAAAIH53=1"; + public static final String NAME_NONE_EXISTED = "sandbox_none_existed"; + public static final String MONITOR = "monitor"; + public static final long TIMESTAMP_ONE = 4513232413L; + public static final long TIMESTAMP_TWO = 4513232415L; + public static final QueryGroup queryGroupOne = builder().name(NAME_ONE) + ._id(_ID_ONE) + .mode(MONITOR) + .resourceLimits(Map.of("jvm", 0.3)) + .updatedAt(TIMESTAMP_ONE) + .build(); + + public static final QueryGroup queryGroupTwo = builder().name(NAME_TWO) + ._id(_ID_TWO) + .mode(MONITOR) + .resourceLimits(Map.of("jvm", 0.6)) + .updatedAt(TIMESTAMP_TWO) + .build(); + + public static final Map queryGroupMap = Map.of(NAME_ONE, queryGroupOne, NAME_TWO, queryGroupTwo); + + public static List queryGroupList() { + return List.of(queryGroupOne, queryGroupTwo); + } + + public static ClusterState clusterState() { + final Metadata metadata = Metadata.builder().queryGroups(new HashSet<>(queryGroupList())).build(); + return ClusterState.builder(new ClusterName("_name")).metadata(metadata).build(); + } + + public static Settings settings() { + return Settings.builder().build(); + } + + public static ClusterSettings clusterSettings() { + return new ClusterSettings(settings(), ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + } + + public static QueryGroupPersistenceService queryGroupPersistenceService() { + ClusterService clusterService = new ClusterService(settings(), clusterSettings(), mock(ThreadPool.class)); + return new QueryGroupPersistenceService(clusterService, settings(), clusterSettings()); + } + + public static List prepareSandboxPersistenceService(List queryGroups) { + Metadata metadata = Metadata.builder().queryGroups(new HashSet<>(queryGroups)).build(); + Settings settings = Settings.builder().build(); + ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + ClusterService clusterService = new ClusterService(settings, clusterSettings, mock(ThreadPool.class)); + ClusterState clusterState = ClusterState.builder(new ClusterName("_name")).metadata(metadata).build(); + QueryGroupPersistenceService queryGroupPersistenceService = new QueryGroupPersistenceService( + clusterService, + settings, + clusterSettings + ); + return List.of(queryGroupPersistenceService, clusterState); + } + + public static void compareResourceLimits(Map resourceLimitMapOne, Map resourceLimitMapTwo) { + for (String resourceName : resourceLimitMapOne.keySet()) { + assertTrue(resourceLimitMapTwo.containsKey(resourceName)); + assertEquals(resourceLimitMapOne.get(resourceName), resourceLimitMapTwo.get(resourceName)); + } + } + + public static void compareQueryGroups(List listOne, List listTwo) { + assertEquals(listOne.size(), listTwo.size()); + for (QueryGroup groupOne : listOne) { + String groupOneName = groupOne.getName(); + List groupTwoList = listTwo.stream().filter(sb -> sb.getName().equals(groupOneName)).collect(Collectors.toList()); + assertEquals(1, groupTwoList.size()); + QueryGroup groupTwo = groupTwoList.get(0); + assertEquals(groupOne.getName(), groupTwo.getName()); + assertEquals(groupOne.get_id(), groupTwo.get_id()); + compareResourceLimits(groupOne.getResourceLimits(), groupTwo.getResourceLimits()); + assertEquals(groupOne.getMode(), groupTwo.getMode()); + assertEquals(groupOne.getUpdatedAtInMillis(), groupTwo.getUpdatedAtInMillis()); + } + } + + public static void assertInflightValuesAreZero(QueryGroupPersistenceService queryGroupPersistenceService) { + assertEquals(0, queryGroupPersistenceService.getInflightCreateQueryGroupRequestCount().get()); + Map inflightResourceMap = queryGroupPersistenceService.getInflightResourceLimitValues(); + if (inflightResourceMap != null) { + for (String resourceName : inflightResourceMap.keySet()) { + assertEquals(0, inflightResourceMap.get(resourceName).intValue()); + } + } + } +} diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/UpdateQueryGroupRequestTests.java b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/UpdateQueryGroupRequestTests.java new file mode 100644 index 0000000000000..c505694be4011 --- /dev/null +++ b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/UpdateQueryGroupRequestTests.java @@ -0,0 +1,119 @@ +/* + * 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.qg; + +import org.opensearch.cluster.metadata.QueryGroup; +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.test.OpenSearchTestCase; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static org.opensearch.plugin.qg.QueryGroupTestUtils.MONITOR; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.NAME_ONE; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.TIMESTAMP_ONE; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.compareResourceLimits; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupOne; + +public class UpdateQueryGroupRequestTests extends OpenSearchTestCase { + + public void testSerialization() throws IOException { + UpdateQueryGroupRequest request = new UpdateQueryGroupRequest(queryGroupOne); + BytesStreamOutput out = new BytesStreamOutput(); + request.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + UpdateQueryGroupRequest otherRequest = new UpdateQueryGroupRequest(streamInput); + assertEquals(request.getName(), otherRequest.getName()); + assertEquals(request.getResourceLimits().size(), otherRequest.getResourceLimits().size()); + assertEquals(request.getMode(), otherRequest.getMode()); + compareResourceLimits(request.getResourceLimits(), otherRequest.getResourceLimits()); + assertEquals(request.getUpdatedAtInMillis(), otherRequest.getUpdatedAtInMillis()); + } + + public void testSerializationOnlyName() throws IOException { + UpdateQueryGroupRequest request = new UpdateQueryGroupRequest(NAME_ONE, null, new HashMap<>(), TIMESTAMP_ONE); + BytesStreamOutput out = new BytesStreamOutput(); + request.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + UpdateQueryGroupRequest otherRequest = new UpdateQueryGroupRequest(streamInput); + assertEquals(request.getName(), otherRequest.getName()); + assertEquals(request.getResourceLimits(), otherRequest.getResourceLimits()); + assertEquals(request.getMode(), otherRequest.getMode()); + assertEquals(request.getUpdatedAtInMillis(), otherRequest.getUpdatedAtInMillis()); + } + + public void testSerializationOnlyResourceLimit() throws IOException { + UpdateQueryGroupRequest request = new UpdateQueryGroupRequest(NAME_ONE, null, Map.of("jvm", 0.4), TIMESTAMP_ONE); + BytesStreamOutput out = new BytesStreamOutput(); + request.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + UpdateQueryGroupRequest otherRequest = new UpdateQueryGroupRequest(streamInput); + assertEquals(request.getName(), otherRequest.getName()); + assertEquals(request.getResourceLimits().size(), otherRequest.getResourceLimits().size()); + compareResourceLimits(request.getResourceLimits(), otherRequest.getResourceLimits()); + assertEquals(request.getMode(), otherRequest.getMode()); + assertEquals(request.getUpdatedAtInMillis(), otherRequest.getUpdatedAtInMillis()); + } + + public void testInvalidName() { + assertThrows( + IllegalArgumentException.class, + () -> new UpdateQueryGroupRequest("", QueryGroup.QueryGroupMode.fromName(MONITOR), Map.of("jvm", 0.3), TIMESTAMP_ONE) + ); + assertThrows( + IllegalArgumentException.class, + () -> new UpdateQueryGroupRequest("-test", QueryGroup.QueryGroupMode.fromName(MONITOR), Map.of("jvm", 0.3), TIMESTAMP_ONE) + ); + assertThrows( + IllegalArgumentException.class, + () -> new UpdateQueryGroupRequest(":test", QueryGroup.QueryGroupMode.fromName(MONITOR), Map.of("jvm", 0.3), TIMESTAMP_ONE) + ); + } + + public void testInvalidResourceLimitList() { + assertThrows( + NullPointerException.class, + () -> new UpdateQueryGroupRequest(NAME_ONE, QueryGroup.QueryGroupMode.fromName(MONITOR), null, TIMESTAMP_ONE) + ); + + assertThrows( + IllegalArgumentException.class, + () -> new UpdateQueryGroupRequest( + NAME_ONE, + QueryGroup.QueryGroupMode.fromName(MONITOR), + Map.of("jvm", 0.3, "jvm", 0.4), + TIMESTAMP_ONE + ) + ); + + assertThrows( + IllegalArgumentException.class, + () -> new UpdateQueryGroupRequest(NAME_ONE, QueryGroup.QueryGroupMode.fromName(MONITOR), Map.of("jvm", -0.3), TIMESTAMP_ONE) + ); + + assertThrows( + IllegalArgumentException.class, + () -> new UpdateQueryGroupRequest(NAME_ONE, QueryGroup.QueryGroupMode.fromName(MONITOR), Map.of("jvm", 12.0), TIMESTAMP_ONE) + ); + + assertThrows( + IllegalArgumentException.class, + () -> new UpdateQueryGroupRequest(NAME_ONE, QueryGroup.QueryGroupMode.fromName(MONITOR), Map.of("cpu", 0.3), TIMESTAMP_ONE) + ); + } + + public void testInvalidEnforcement() { + assertThrows( + IllegalArgumentException.class, + () -> new UpdateQueryGroupRequest(NAME_ONE, QueryGroup.QueryGroupMode.fromName("random"), Map.of("jvm", 0.3), TIMESTAMP_ONE) + ); + } +} diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/UpdateQueryGroupResponseTests.java b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/UpdateQueryGroupResponseTests.java new file mode 100644 index 0000000000000..dfe3a590951b3 --- /dev/null +++ b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/UpdateQueryGroupResponseTests.java @@ -0,0 +1,32 @@ +/* + * 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.qg; + +import org.opensearch.cluster.metadata.QueryGroup; +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.test.OpenSearchTestCase; + +import java.io.IOException; +import java.util.List; + +public class UpdateQueryGroupResponseTests extends OpenSearchTestCase { + + public void testSerialization() throws IOException { + UpdateQueryGroupResponse response = new UpdateQueryGroupResponse(QueryGroupTestUtils.queryGroupOne); + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + StreamInput streamInput = out.bytes().streamInput(); + UpdateQueryGroupResponse otherResponse = new UpdateQueryGroupResponse(streamInput); + assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); + QueryGroup responseGroup = response.getQueryGroup(); + QueryGroup otherResponseGroup = otherResponse.getQueryGroup(); + QueryGroupTestUtils.compareQueryGroups(List.of(responseGroup), List.of(otherResponseGroup)); + } +} diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/service/QueryGroupPersistenceServiceTests.java b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/service/QueryGroupPersistenceServiceTests.java new file mode 100644 index 0000000000000..ffa22bb1b4542 --- /dev/null +++ b/plugins/query-group/src/test/java/org/opensearch/plugin/qg/service/QueryGroupPersistenceServiceTests.java @@ -0,0 +1,237 @@ +/* + * 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.qg.service; + +import org.opensearch.cluster.ClusterName; +import org.opensearch.cluster.ClusterState; +import org.opensearch.cluster.metadata.Metadata; +import org.opensearch.cluster.metadata.QueryGroup; +import org.opensearch.cluster.metadata.QueryGroup.QueryGroupMode; +import org.opensearch.cluster.service.ClusterService; +import org.opensearch.common.settings.ClusterSettings; +import org.opensearch.common.settings.Settings; +import org.opensearch.plugin.qg.UpdateQueryGroupRequest; +import org.opensearch.test.OpenSearchTestCase; +import org.opensearch.threadpool.ThreadPool; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.opensearch.cluster.metadata.QueryGroup.builder; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.MONITOR; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.NAME_NONE_EXISTED; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.NAME_ONE; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.NAME_TWO; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.SANDBOX_MAX_SETTING_NAME; +import static org.opensearch.plugin.qg.QueryGroupTestUtils._ID_ONE; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.assertInflightValuesAreZero; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.clusterState; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.compareQueryGroups; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.prepareSandboxPersistenceService; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupList; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupMap; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupOne; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupPersistenceService; +import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupTwo; +import static org.mockito.Mockito.mock; + +public class QueryGroupPersistenceServiceTests extends OpenSearchTestCase { + + public void testGetSingleQueryGroup() { + List groups = queryGroupPersistenceService().getFromClusterStateMetadata(NAME_ONE, clusterState()); + assertEquals(1, groups.size()); + QueryGroup queryGroup = groups.get(0); + compareQueryGroups(List.of(queryGroupOne), List.of(queryGroup)); + assertInflightValuesAreZero(queryGroupPersistenceService()); + } + + public void testGetAllQueryGroups() { + assertEquals(2, clusterState().metadata().queryGroups().size()); + List res = queryGroupPersistenceService().getFromClusterStateMetadata(null, clusterState()); + assertEquals(2, res.size()); + Set currentNAME = res.stream().map(QueryGroup::getName).collect(Collectors.toSet()); + assertTrue(currentNAME.contains(NAME_ONE)); + assertTrue(currentNAME.contains(NAME_TWO)); + compareQueryGroups(queryGroupList(), res); + assertInflightValuesAreZero(queryGroupPersistenceService()); + } + + public void testGetZeroQueryGroups() { + Settings settings = Settings.builder().build(); + ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + QueryGroupPersistenceService sandboxPersistenceService = new QueryGroupPersistenceService( + mock(ClusterService.class), + settings, + clusterSettings + ); + List res = sandboxPersistenceService.getFromClusterStateMetadata(NAME_NONE_EXISTED, clusterState()); + assertEquals(0, res.size()); + assertInflightValuesAreZero(queryGroupPersistenceService()); + } + + public void testDeleteSingleQueryGroup() { + ClusterState newClusterState = queryGroupPersistenceService().deleteQueryGroupInClusterState(NAME_TWO, clusterState()); + Set afterDeletionGroups = newClusterState.getMetadata().queryGroups(); + assertEquals(1, afterDeletionGroups.size()); + List oldSandbox = List.of(queryGroupMap.get(NAME_ONE)); + compareQueryGroups(new ArrayList<>(afterDeletionGroups), oldSandbox); + assertInflightValuesAreZero(queryGroupPersistenceService()); + } + + public void testDeleteAllQueryGroups() { + ClusterState newClusterState = queryGroupPersistenceService().deleteQueryGroupInClusterState(null, clusterState()); + Set afterDeletionGroups = newClusterState.getMetadata().queryGroups(); + assertEquals(0, afterDeletionGroups.size()); + assertInflightValuesAreZero(queryGroupPersistenceService()); + } + + public void testDeleteNonExistedQueryGroup() { + assertThrows( + RuntimeException.class, + () -> queryGroupPersistenceService().deleteQueryGroupInClusterState(NAME_NONE_EXISTED, clusterState()) + ); + } + + public void testUpdateQueryGroupAllFields() { + QueryGroup updated = builder().name(NAME_ONE) + ._id(_ID_ONE) + .mode(MONITOR) + .resourceLimits(Map.of("jvm", 0.15)) + .updatedAt(1690934400000L) + .build(); + UpdateQueryGroupRequest updateQueryGroupRequest = new UpdateQueryGroupRequest( + NAME_ONE, + QueryGroupMode.fromName(MONITOR), + Map.of("jvm", 0.15), + 1690934400000L + ); + ClusterState newClusterState = queryGroupPersistenceService().updateQueryGroupInClusterState( + updateQueryGroupRequest, + clusterState() + ); + List updatedSandboxes = new ArrayList<>(newClusterState.getMetadata().queryGroups()); + assertEquals(2, updatedSandboxes.size()); + compareQueryGroups(List.of(queryGroupTwo, updated), updatedSandboxes); + assertInflightValuesAreZero(queryGroupPersistenceService()); + } + + public void testUpdateQueryGroupResourceLimitsOnly() { + QueryGroup updated = builder().name(NAME_ONE) + ._id(_ID_ONE) + .mode(MONITOR) + .resourceLimits(Map.of("jvm", 0.15)) + .updatedAt(1690934400000L) + .build(); + UpdateQueryGroupRequest updateQueryGroupRequest = new UpdateQueryGroupRequest( + NAME_ONE, + QueryGroupMode.fromName(MONITOR), + Map.of("jvm", 0.15), + 1690934400000L + ); + ClusterState newClusterState = queryGroupPersistenceService().updateQueryGroupInClusterState( + updateQueryGroupRequest, + clusterState() + ); + Set updatedSandboxesMap = newClusterState.getMetadata().queryGroups(); + assertEquals(2, updatedSandboxesMap.size()); + Optional findUpdatedGroupOne = newClusterState.metadata() + .queryGroups() + .stream() + .filter(group -> group.getName().equals(NAME_ONE)) + .findFirst(); + Optional findUpdatedGroupTwo = newClusterState.metadata() + .queryGroups() + .stream() + .filter(group -> group.getName().equals(NAME_TWO)) + .findFirst(); + assertTrue(findUpdatedGroupOne.isPresent()); + assertTrue(findUpdatedGroupTwo.isPresent()); + compareQueryGroups(List.of(updated), List.of(findUpdatedGroupOne.get())); + assertInflightValuesAreZero(queryGroupPersistenceService()); + } + + public void testCreateQueryGroup() { + List setup = prepareSandboxPersistenceService(new ArrayList<>()); + QueryGroupPersistenceService queryGroupPersistenceService1 = (QueryGroupPersistenceService) setup.get(0); + ClusterState clusterState = (ClusterState) setup.get(1); + ClusterState newClusterState = queryGroupPersistenceService1.saveQueryGroupInClusterState(queryGroupOne, clusterState); + Set updatedGroupsMap = newClusterState.getMetadata().queryGroups(); + assertEquals(1, updatedGroupsMap.size()); + Optional findUpdatedGroupOne = newClusterState.metadata() + .queryGroups() + .stream() + .filter(group -> group.getName().equals(NAME_ONE)) + .findFirst(); + assertTrue(findUpdatedGroupOne.isPresent()); + compareQueryGroups(List.of(queryGroupOne), List.of(findUpdatedGroupOne.get())); + assertInflightValuesAreZero(queryGroupPersistenceService()); + } + + public void testCreateAnotherQueryGroup() { + List setup = prepareSandboxPersistenceService(List.of(queryGroupOne)); + QueryGroupPersistenceService queryGroupPersistenceService1 = (QueryGroupPersistenceService) setup.get(0); + ClusterState clusterState = (ClusterState) setup.get(1); + ClusterState newClusterState = queryGroupPersistenceService1.saveQueryGroupInClusterState(queryGroupTwo, clusterState); + Set updatedGroups = newClusterState.getMetadata().queryGroups(); + assertEquals(2, updatedGroups.size()); + compareQueryGroups(queryGroupList(), new ArrayList<>(updatedGroups)); + assertInflightValuesAreZero(queryGroupPersistenceService()); + } + + public void testCreateQueryGroupDuplicateName() { + List setup = prepareSandboxPersistenceService(List.of(queryGroupOne)); + QueryGroupPersistenceService queryGroupPersistenceService1 = (QueryGroupPersistenceService) setup.get(0); + ClusterState clusterState = (ClusterState) setup.get(1); + QueryGroup toCreate = builder().name(NAME_ONE) + ._id("W5iIqHyhgi4K1qIAAAAIHw==") + .mode(MONITOR) + .resourceLimits(Map.of("jvm", 0.3)) + .updatedAt(1690934400000L) + .build(); + assertThrows(RuntimeException.class, () -> queryGroupPersistenceService1.saveQueryGroupInClusterState(toCreate, clusterState)); + } + + public void testCreateQueryGroupOverflowAllocation() { + List setup = prepareSandboxPersistenceService(List.of(queryGroupTwo)); + QueryGroup toCreate = builder().name(NAME_TWO) + ._id("W5iIqHyhgi4K1qIAAAAIHw==") + .mode(MONITOR) + .resourceLimits(Map.of("jvm", 0.5)) + .updatedAt(1690934400000L) + .build(); + QueryGroupPersistenceService queryGroupPersistenceService1 = (QueryGroupPersistenceService) setup.get(0); + ClusterState clusterState = (ClusterState) setup.get(1); + assertThrows(RuntimeException.class, () -> queryGroupPersistenceService1.saveQueryGroupInClusterState(toCreate, clusterState)); + } + + public void testCreateQueryGroupOverflowCount() { + QueryGroup toCreate = builder().name(NAME_NONE_EXISTED) + ._id("W5iIqHyhgi4K1qIAAAAIHw==") + .mode(MONITOR) + .resourceLimits(Map.of("jvm", 0.5)) + .updatedAt(1690934400000L) + .build(); + Metadata metadata = Metadata.builder().queryGroups(new HashSet<>(queryGroupList())).build(); + Settings settings = Settings.builder().put(SANDBOX_MAX_SETTING_NAME, 2).build(); + ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + ClusterService clusterService = new ClusterService(settings, clusterSettings, mock(ThreadPool.class)); + ClusterState clusterState = ClusterState.builder(new ClusterName("_name")).metadata(metadata).build(); + QueryGroupPersistenceService queryGroupPersistenceService1 = new QueryGroupPersistenceService( + clusterService, + settings, + clusterSettings + ); + assertThrows(RuntimeException.class, () -> queryGroupPersistenceService1.saveQueryGroupInClusterState(toCreate, clusterState)); + } +} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupAction.java deleted file mode 100644 index b3ec61f55e9b3..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupAction.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.action.ActionType; - -/** - * Rest action to create Resource Limit Group - * - * @opensearch.api - */ -public class CreateResourceLimitGroupAction extends ActionType { - - /** - * An instance of CreateResourceLimitGroupAction - */ - public static final CreateResourceLimitGroupAction INSTANCE = new CreateResourceLimitGroupAction(); - - /** - * Name for CreateResourceLimitGroupAction - */ - public static final String NAME = "cluster:admin/opensearch/resource_limit_group/_create"; - - /** - * Default constructor - */ - private CreateResourceLimitGroupAction() { - super(NAME, CreateResourceLimitGroupResponse::new); - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupRequest.java deleted file mode 100644 index d7a8c6ac196f3..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupRequest.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.action.ActionRequest; -import org.opensearch.action.ActionRequestValidationException; -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.common.io.stream.Writeable; -import org.opensearch.core.xcontent.XContentParser; - -import java.io.IOException; -import java.util.List; - -/** - * A request for create Resource Limit Group - * - * @opensearch.internal - */ -public class CreateResourceLimitGroupRequest extends ActionRequest implements Writeable.Reader { - private String name; - private String uuid; - private List resourceLimits; - private String enforcement; - private String createdAt; - private String updatedAt; - - /** - * Default constructor for CreateResourceLimitGroupRequest - */ - public CreateResourceLimitGroupRequest() {} - - /** - * Constructor for CreateResourceLimitGroupRequest - * @param resourceLimitGroup - A {@link ResourceLimitGroup} object - */ - public CreateResourceLimitGroupRequest(ResourceLimitGroup resourceLimitGroup) { - this.name = resourceLimitGroup.getName(); - this.uuid = resourceLimitGroup.getUUID(); - this.resourceLimits = resourceLimitGroup.getResourceLimits(); - this.enforcement = resourceLimitGroup.getEnforcement(); - this.createdAt = resourceLimitGroup.getCreatedAt(); - this.updatedAt = resourceLimitGroup.getUpdatedAt(); - } - - /** - * Constructor for CreateResourceLimitGroupRequest - * @param in - A {@link StreamInput} object - */ - public CreateResourceLimitGroupRequest(StreamInput in) throws IOException { - super(in); - name = in.readString(); - uuid = in.readString(); - resourceLimits = in.readList(ResourceLimit::new); - enforcement = in.readString(); - createdAt = in.readString(); - updatedAt = in.readString(); - } - - @Override - public CreateResourceLimitGroupRequest read(StreamInput in) throws IOException { - return new CreateResourceLimitGroupRequest(in); - } - - /** - * Generate a CreateResourceLimitGroupRequest from XContent - * @param parser - A {@link XContentParser} object - */ - public static CreateResourceLimitGroupRequest fromXContent(XContentParser parser) throws IOException { - ResourceLimitGroup resourceLimitGroup = ResourceLimitGroup.fromXContent(parser); - return new CreateResourceLimitGroupRequest(resourceLimitGroup); - } - - @Override - public ActionRequestValidationException validate() { - return null; - } - - /** - * name getter - */ - public String getName() { - return name; - } - - /** - * name setter - * @param name - name to be set - */ - public void setName(String name) { - this.name = name; - } - - /** - * resourceLimits getter - */ - public List getResourceLimits() { - return resourceLimits; - } - - /** - * resourceLimits setter - * @param resourceLimits - resourceLimit to be set - */ - public void setResourceLimits(List resourceLimits) { - this.resourceLimits = resourceLimits; - } - - /** - * Enforcement getter - */ - public String getEnforcement() { - return enforcement; - } - - /** - * Enforcement setter - * @param enforcement - enforcement to be set - */ - public void setEnforcement(String enforcement) { - this.enforcement = enforcement; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - ResourceLimitGroup.writeToOutputStream(out, name, uuid, resourceLimits, enforcement, createdAt, updatedAt); - } - - /** - * UUID getter - */ - public String getUUID() { - return uuid; - } - - /** - * UUID setter - * @param uuid - uuid to be set - */ - public void setUUID(String uuid) { - this.uuid = uuid; - } - - /** - * createdAt getter - */ - public String getCreatedAt() { - return createdAt; - } - - /** - * createdAt setter - * @param createdAt - createdAt to be set - */ - public void setCreatedAt(String createdAt) { - this.createdAt = createdAt; - } - - /** - * updatedAt getter - */ - public String getUpdatedAt() { - return updatedAt; - } - - /** - * updatedAt setter - * @param updatedAt - updatedAt to be set - */ - public void setUpdatedAt(String updatedAt) { - this.updatedAt = updatedAt; - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupAction.java deleted file mode 100644 index 44a2c87ac31fd..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupAction.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.action.ActionType; - -/** - * Rest action to delete Resource Limit Group - * - * @opensearch.api - */ -public class DeleteResourceLimitGroupAction extends ActionType { - - /** - /** - * An instance of DeleteResourceLimitGroupAction - */ - public static final DeleteResourceLimitGroupAction INSTANCE = new DeleteResourceLimitGroupAction(); - - /** - * Name for DeleteResourceLimitGroupAction - */ - public static final String NAME = "cluster:admin/opensearch/resource_limit_group/_delete"; - - /** - * Default constructor - */ - private DeleteResourceLimitGroupAction() { - super(NAME, DeleteResourceLimitGroupResponse::new); - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupRequest.java deleted file mode 100644 index 690df6cbaa306..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupRequest.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.action.ActionRequest; -import org.opensearch.action.ActionRequestValidationException; -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.common.io.stream.Writeable; -import org.opensearch.core.xcontent.XContentParser; - -import java.io.IOException; - -/** - * A request for delete Resource Limit Group - * - * @opensearch.internal - */ -public class DeleteResourceLimitGroupRequest extends ActionRequest implements Writeable.Reader { - String name; - - /** - * Default constructor for DeleteResourceLimitGroupRequest - * @param name - name for the Resource Limit Group to get - */ - public DeleteResourceLimitGroupRequest(String name) { - this.name = name; - } - - /** - * Constructor for DeleteResourceLimitGroupRequest - * @param resourceLimitGroup - A {@link ResourceLimitGroup} object - */ - public DeleteResourceLimitGroupRequest(ResourceLimitGroup resourceLimitGroup) { - this.name = resourceLimitGroup.getName(); - } - - /** - * Constructor for DeleteResourceLimitGroupRequest - * @param in - A {@link StreamInput} object - */ - public DeleteResourceLimitGroupRequest(StreamInput in) throws IOException { - super(in); - name = in.readOptionalString(); - } - - @Override - public DeleteResourceLimitGroupRequest read(StreamInput in) throws IOException { - return new DeleteResourceLimitGroupRequest(in); - } - - /** - * Generate a DeleteResourceLimitGroupRequest from XContent - * @param parser - A {@link XContentParser} object - */ - public static DeleteResourceLimitGroupRequest fromXContent(XContentParser parser) throws IOException { - ResourceLimitGroup resourceLimitGroup = ResourceLimitGroup.fromXContent(parser); - return new DeleteResourceLimitGroupRequest(resourceLimitGroup); - } - - @Override - public ActionRequestValidationException validate() { - return null; - } - - /** - * Name getter - */ - public String getName() { - return name; - } - - /** - * Name setter - * @param name - name to be set - */ - public void setName(String name) { - this.name = name; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeOptionalString(name); - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupAction.java deleted file mode 100644 index e2f193bd7e592..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupAction.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.action.ActionType; - -/** - * Rest action to get Resource Limit Group - * - * @opensearch.api - */ -public class GetResourceLimitGroupAction extends ActionType { - - /** - /** - * An instance of GetResourceLimitGroupAction - */ - public static final GetResourceLimitGroupAction INSTANCE = new GetResourceLimitGroupAction(); - - /** - * Name for GetResourceLimitGroupAction - */ - public static final String NAME = "cluster:admin/opensearch/resource_limit_group/_get"; - - /** - * Default constructor - */ - private GetResourceLimitGroupAction() { - super(NAME, GetResourceLimitGroupResponse::new); - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupRequest.java deleted file mode 100644 index 50cb467bec09c..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/GetResourceLimitGroupRequest.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.action.ActionRequest; -import org.opensearch.action.ActionRequestValidationException; -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.common.io.stream.Writeable; -import org.opensearch.core.xcontent.XContentParser; - -import java.io.IOException; - -/** - * A request for get Resource Limit Group - * - * @opensearch.internal - */ -public class GetResourceLimitGroupRequest extends ActionRequest implements Writeable.Reader { - String name; - - /** - * Default constructor for GetResourceLimitGroupRequest - * @param name - name for the Resource Limit Group to get - */ - public GetResourceLimitGroupRequest(String name) { - this.name = name; - } - - /** - * Constructor for GetResourceLimitGroupRequest - * @param resourceLimitGroup - A {@link ResourceLimitGroup} object - */ - public GetResourceLimitGroupRequest(ResourceLimitGroup resourceLimitGroup) { - this.name = resourceLimitGroup.getName(); - } - - /** - * Constructor for GetResourceLimitGroupRequest - * @param in - A {@link StreamInput} object - */ - public GetResourceLimitGroupRequest(StreamInput in) throws IOException { - super(in); - name = in.readOptionalString(); - } - - @Override - public GetResourceLimitGroupRequest read(StreamInput in) throws IOException { - return new GetResourceLimitGroupRequest(in); - } - - /** - * Generate a GetResourceLimitGroupRequest from XContent - * @param parser - A {@link XContentParser} object - */ - public static GetResourceLimitGroupRequest fromXContent(XContentParser parser) throws IOException { - ResourceLimitGroup resourceLimitGroup = ResourceLimitGroup.fromXContent(parser); - return new GetResourceLimitGroupRequest(resourceLimitGroup); - } - - @Override - public ActionRequestValidationException validate() { - return null; - } - - /** - * Name getter - */ - public String getName() { - return name; - } - - /** - * Name setter - * @param name - name to be set - */ - public void setName(String name) { - this.name = name; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeOptionalString(name); - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/ResourceLimitGroupPluginModule.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/ResourceLimitGroupPluginModule.java deleted file mode 100644 index 07bcc7eb2bde3..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/ResourceLimitGroupPluginModule.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.common.inject.AbstractModule; -import org.opensearch.common.inject.TypeLiteral; -import org.opensearch.plugin.rlg.service.Persistable; -import org.opensearch.plugin.rlg.service.ResourceLimitGroupPersistenceService; - -/** - * Guice Module to manage ResourceLimitGroup related objects - */ -public class ResourceLimitGroupPluginModule extends AbstractModule { - - /** - * Constructor for ResourceLimitGroupPluginModule - */ - public ResourceLimitGroupPluginModule() {} - - @Override - protected void configure() { - // bind(Persistable.class).to(ResourceLimitGroupPersistenceService.class).asEagerSingleton(); - bind(new TypeLiteral>() { - }).to(ResourceLimitGroupPersistenceService.class).asEagerSingleton(); - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportCreateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportCreateResourceLimitGroupAction.java deleted file mode 100644 index fc3bd773c0b1d..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportCreateResourceLimitGroupAction.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.action.support.ActionFilters; -import org.opensearch.action.support.HandledTransportAction; -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.common.inject.Inject; -import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.rlg.service.Persistable; -import org.opensearch.tasks.Task; -import org.opensearch.threadpool.ThreadPool; -import org.opensearch.transport.TransportService; - -/** - * Transport action for create Resource Limit Group - * - * @opensearch.internal - */ -public class TransportCreateResourceLimitGroupAction extends HandledTransportAction< - CreateResourceLimitGroupRequest, - CreateResourceLimitGroupResponse> { - - private final ThreadPool threadPool; - private final Persistable resourceLimitGroupPersistenceService; - - /** - * Constructor for TransportCreateResourceLimitGroupAction - * - * @param actionName - acrtion name - * @param transportService - a {@link TransportService} object - * @param actionFilters - a {@link ActionFilters} object - * @param threadPool - a {@link ThreadPool} object - * @param resourceLimitGroupPersistenceService - a {@link Persistable} object - */ - @Inject - public TransportCreateResourceLimitGroupAction( - String actionName, - TransportService transportService, - ActionFilters actionFilters, - ThreadPool threadPool, - Persistable resourceLimitGroupPersistenceService - ) { - super(CreateResourceLimitGroupAction.NAME, transportService, actionFilters, CreateResourceLimitGroupRequest::new); - this.threadPool = threadPool; - this.resourceLimitGroupPersistenceService = resourceLimitGroupPersistenceService; - } - - @Override - protected void doExecute( - Task task, - CreateResourceLimitGroupRequest request, - ActionListener listener - ) { - ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup( - request.getName(), - request.getUUID(), - request.getResourceLimits(), - request.getEnforcement(), - request.getCreatedAt(), - request.getUpdatedAt() - ); - threadPool.executor(ThreadPool.Names.GENERIC) - .execute(() -> resourceLimitGroupPersistenceService.persist(resourceLimitGroup, listener)); - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportDeleteResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportDeleteResourceLimitGroupAction.java deleted file mode 100644 index ee4ff508f9966..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportDeleteResourceLimitGroupAction.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.action.support.ActionFilters; -import org.opensearch.action.support.HandledTransportAction; -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.common.inject.Inject; -import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.rlg.service.Persistable; -import org.opensearch.tasks.Task; -import org.opensearch.threadpool.ThreadPool; -import org.opensearch.transport.TransportService; - -/** - * Transport action for delete Resource Limit Group - * - * @opensearch.internal - */ -public class TransportDeleteResourceLimitGroupAction extends HandledTransportAction< - DeleteResourceLimitGroupRequest, - DeleteResourceLimitGroupResponse> { - - private final ThreadPool threadPool; - private final Persistable resourceLimitGroupPersistenceService; - - /** - * Constructor for TransportDeleteResourceLimitGroupAction - * - * @param actionName - acrtion name - * @param transportService - a {@link TransportService} object - * @param actionFilters - a {@link ActionFilters} object - * @param threadPool - a {@link ThreadPool} object - * @param resourceLimitGroupPersistenceService - a {@link Persistable} object - */ - @Inject - public TransportDeleteResourceLimitGroupAction( - String actionName, - TransportService transportService, - ActionFilters actionFilters, - ThreadPool threadPool, - Persistable resourceLimitGroupPersistenceService - ) { - super(DeleteResourceLimitGroupAction.NAME, transportService, actionFilters, DeleteResourceLimitGroupRequest::new); - this.threadPool = threadPool; - this.resourceLimitGroupPersistenceService = resourceLimitGroupPersistenceService; - } - - @Override - protected void doExecute( - Task task, - DeleteResourceLimitGroupRequest request, - ActionListener listener - ) { - String name = request.getName(); - threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> resourceLimitGroupPersistenceService.delete(name, listener)); - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportUpdateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportUpdateResourceLimitGroupAction.java deleted file mode 100644 index 90a208d48053a..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/TransportUpdateResourceLimitGroupAction.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.action.support.ActionFilters; -import org.opensearch.action.support.HandledTransportAction; -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.common.inject.Inject; -import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.rlg.service.Persistable; -import org.opensearch.tasks.Task; -import org.opensearch.threadpool.ThreadPool; -import org.opensearch.transport.TransportService; - -/** - * Transport action for update Resource Limit Group - * - * @opensearch.internal - */ -public class TransportUpdateResourceLimitGroupAction extends HandledTransportAction< - UpdateResourceLimitGroupRequest, - UpdateResourceLimitGroupResponse> { - - private final ThreadPool threadPool; - private final Persistable resourceLimitGroupPersistenceService; - - /** - * Constructor for TransportUpdateResourceLimitGroupAction - * - * @param actionName - acrtion name - * @param transportService - a {@link TransportService} object - * @param actionFilters - a {@link ActionFilters} object - * @param threadPool - a {@link ThreadPool} object - * @param resourceLimitGroupPersistenceService - a {@link Persistable} object - */ - @Inject - public TransportUpdateResourceLimitGroupAction( - String actionName, - TransportService transportService, - ActionFilters actionFilters, - ThreadPool threadPool, - Persistable resourceLimitGroupPersistenceService - ) { - super(UpdateResourceLimitGroupAction.NAME, transportService, actionFilters, UpdateResourceLimitGroupRequest::new); - this.threadPool = threadPool; - this.resourceLimitGroupPersistenceService = resourceLimitGroupPersistenceService; - } - - @Override - protected void doExecute( - Task task, - UpdateResourceLimitGroupRequest request, - ActionListener listener - ) { - ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup( - request.getName(), - null, - request.getResourceLimits(), - request.getEnforcement(), - null, - request.getUpdatedAt() - ); - threadPool.executor(ThreadPool.Names.GENERIC) - .execute(() -> resourceLimitGroupPersistenceService.update(resourceLimitGroup, listener)); - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupAction.java deleted file mode 100644 index afa5be86b05a6..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupAction.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.action.ActionType; - -/** - * Rest action to update Resource Limit Group - * - * @opensearch.api - */ -public class UpdateResourceLimitGroupAction extends ActionType { - - /** - * An instance of UpdateResourceLimitGroupAction - */ - public static final UpdateResourceLimitGroupAction INSTANCE = new UpdateResourceLimitGroupAction(); - - /** - * Name for UpdateResourceLimitGroupAction - */ - public static final String NAME = "cluster:admin/opensearch/resource_limit_group/_update"; - - /** - * Default constructor - */ - private UpdateResourceLimitGroupAction() { - super(NAME, UpdateResourceLimitGroupResponse::new); - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupRequest.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupRequest.java deleted file mode 100644 index ab9aafce4dd62..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupRequest.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.action.ActionRequest; -import org.opensearch.action.ActionRequestValidationException; -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.common.io.stream.Writeable; -import org.opensearch.core.xcontent.XContentParser; - -import java.io.IOException; -import java.util.List; - -/** - * A request for update Resource Limit Group - * - * @opensearch.internal - */ -public class UpdateResourceLimitGroupRequest extends ActionRequest implements Writeable.Reader { - String name; - List resourceLimits; - String enforcement; - String updatedAt; - - /** - * Default constructor for UpdateResourceLimitGroupRequest - * @param name - name for Resource Limit Group - */ - public UpdateResourceLimitGroupRequest(String name) { - this.name = name; - } - - /** - * Constructor for UpdateResourceLimitGroupRequest - * @param resourceLimitGroup - A {@link ResourceLimitGroup} object - */ - public UpdateResourceLimitGroupRequest(ResourceLimitGroup resourceLimitGroup) { - this.name = resourceLimitGroup.getName(); - this.resourceLimits = resourceLimitGroup.getResourceLimits(); - this.enforcement = resourceLimitGroup.getEnforcement(); - this.updatedAt = resourceLimitGroup.getUpdatedAt(); - } - - /** - * Constructor for UpdateResourceLimitGroupRequest - * @param in - A {@link StreamInput} object - */ - public UpdateResourceLimitGroupRequest(StreamInput in) throws IOException { - super(in); - name = in.readString(); - if (in.readBoolean()) { - resourceLimits = in.readList(ResourceLimit::new); - } - enforcement = in.readOptionalString(); - updatedAt = in.readString(); - } - - @Override - public UpdateResourceLimitGroupRequest read(StreamInput in) throws IOException { - return new UpdateResourceLimitGroupRequest(in); - } - - /** - * Generate a UpdateResourceLimitGroupRequest from XContent - * @param parser - A {@link XContentParser} object - */ - public static UpdateResourceLimitGroupRequest fromXContent(XContentParser parser) throws IOException { - ResourceLimitGroup resourceLimitGroup = ResourceLimitGroup.fromXContentOptionalFields(parser); - return new UpdateResourceLimitGroupRequest(resourceLimitGroup); - } - - @Override - public ActionRequestValidationException validate() { - return null; - } - - /** - * name getter - */ - public String getName() { - return name; - } - - /** - * name setter - * @param name - name to be set - */ - public void setName(String name) { - this.name = name; - } - - /** - * ResourceLimits getter - */ - public List getResourceLimits() { - return resourceLimits; - } - - /** - * ResourceLimits setter - * @param resourceLimits - ResourceLimit to be set - */ - public void setResourceLimits(List resourceLimits) { - this.resourceLimits = resourceLimits; - } - - /** - * Enforcement getter - */ - public String getEnforcement() { - return enforcement; - } - - /** - * Enforcement setter - * @param enforcement - enforcement to be set - */ - public void setEnforcement(String enforcement) { - this.enforcement = enforcement; - } - - /** - * updatedAt getter - */ - public String getUpdatedAt() { - return updatedAt; - } - - /** - * updatedAt setter - * @param updatedAt - updatedAt to be set - */ - public void setUpdatedAt(String updatedAt) { - this.updatedAt = updatedAt; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(name); - if (resourceLimits == null || resourceLimits.isEmpty()) { - out.writeBoolean(false); - } else { - out.writeBoolean(true); - out.writeList(resourceLimits); - } - out.writeOptionalString(enforcement); - out.writeString(updatedAt); - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestCreateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestCreateResourceLimitGroupAction.java deleted file mode 100644 index 9002d7ba48acb..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestCreateResourceLimitGroupAction.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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.rlg.rest; - -import org.opensearch.client.node.NodeClient; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.core.xcontent.XContentParser; -import org.opensearch.plugin.rlg.CreateResourceLimitGroupAction; -import org.opensearch.plugin.rlg.CreateResourceLimitGroupRequest; -import org.opensearch.plugin.rlg.CreateResourceLimitGroupResponse; -import org.opensearch.rest.BaseRestHandler; -import org.opensearch.rest.BytesRestResponse; -import org.opensearch.rest.RestChannel; -import org.opensearch.rest.RestRequest; -import org.opensearch.rest.RestResponse; -import org.opensearch.rest.action.RestResponseListener; - -import java.io.IOException; -import java.util.List; - -import static org.opensearch.rest.RestRequest.Method.POST; -import static org.opensearch.rest.RestRequest.Method.PUT; - -/** - * Rest action to create a resource limit group - * - * @opensearch.api - */ -public class RestCreateResourceLimitGroupAction extends BaseRestHandler { - - /** - * Constructor for RestCreateResourceLimitGroupAction - */ - public RestCreateResourceLimitGroupAction() {} - - @Override - public String getName() { - return "create_resource_limit_group"; - } - - /** - * The list of {@link Route}s that this RestHandler is responsible for handling. - */ - @Override - public List routes() { - return List.of(new Route(POST, "_resource_limit_group/"), new Route(PUT, "_resource_limit_group/")); - } - - @Override - protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { - CreateResourceLimitGroupRequest createResourceLimitGroupRequest = new CreateResourceLimitGroupRequest(); - request.applyContentParser((parser) -> parseRestRequest(createResourceLimitGroupRequest, parser)); - return channel -> client.execute( - CreateResourceLimitGroupAction.INSTANCE, - createResourceLimitGroupRequest, - createResourceLimitGroupResponse(channel) - ); - } - - private void parseRestRequest(CreateResourceLimitGroupRequest request, XContentParser parser) throws IOException { - final CreateResourceLimitGroupRequest createResourceLimitGroupRequest = CreateResourceLimitGroupRequest.fromXContent(parser); - request.setName(createResourceLimitGroupRequest.getName()); - request.setUUID(createResourceLimitGroupRequest.getUUID()); - request.setResourceLimits(createResourceLimitGroupRequest.getResourceLimits()); - request.setEnforcement(createResourceLimitGroupRequest.getEnforcement()); - request.setCreatedAt(createResourceLimitGroupRequest.getCreatedAt()); - request.setUpdatedAt(createResourceLimitGroupRequest.getUpdatedAt()); - } - - private RestResponseListener createResourceLimitGroupResponse(final RestChannel channel) { - return new RestResponseListener<>(channel) { - @Override - public RestResponse buildResponse(final CreateResourceLimitGroupResponse response) throws Exception { - return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS)); - } - }; - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestUpdateResourceLimitGroupAction.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestUpdateResourceLimitGroupAction.java deleted file mode 100644 index f6a769d7e0104..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/RestUpdateResourceLimitGroupAction.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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.rlg.rest; - -import org.opensearch.client.node.NodeClient; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.core.xcontent.XContentParser; -import org.opensearch.plugin.rlg.UpdateResourceLimitGroupAction; -import org.opensearch.plugin.rlg.UpdateResourceLimitGroupRequest; -import org.opensearch.plugin.rlg.UpdateResourceLimitGroupResponse; -import org.opensearch.rest.BaseRestHandler; -import org.opensearch.rest.BytesRestResponse; -import org.opensearch.rest.RestChannel; -import org.opensearch.rest.RestRequest; -import org.opensearch.rest.RestResponse; -import org.opensearch.rest.action.RestResponseListener; - -import java.io.IOException; -import java.util.List; - -import static org.opensearch.rest.RestRequest.Method.POST; -import static org.opensearch.rest.RestRequest.Method.PUT; - -/** - * Rest action to update a resource limit group - * - * @opensearch.api - */ -public class RestUpdateResourceLimitGroupAction extends BaseRestHandler { - - /** - * Constructor for RestUpdateResourceLimitGroupAction - */ - public RestUpdateResourceLimitGroupAction() {} - - @Override - public String getName() { - return "update_resource_limit_group"; - } - - /** - * The list of {@link Route}s that this RestHandler is responsible for handling. - */ - @Override - public List routes() { - return List.of(new Route(POST, "_resource_limit_group/{name}"), new Route(PUT, "_resource_limit_group/{name}")); - } - - @Override - protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { - String name = request.param("name"); - UpdateResourceLimitGroupRequest updateResourceLimitGroupRequest = new UpdateResourceLimitGroupRequest(name); - request.applyContentParser((parser) -> parseRestRequest(updateResourceLimitGroupRequest, parser)); - return channel -> client.execute( - UpdateResourceLimitGroupAction.INSTANCE, - updateResourceLimitGroupRequest, - updateResourceLimitGroupResponse(channel) - ); - } - - private void parseRestRequest(UpdateResourceLimitGroupRequest request, XContentParser parser) throws IOException { - final UpdateResourceLimitGroupRequest updateResourceLimitGroupRequest = UpdateResourceLimitGroupRequest.fromXContent(parser); - request.setResourceLimits(updateResourceLimitGroupRequest.getResourceLimits()); - request.setEnforcement(updateResourceLimitGroupRequest.getEnforcement()); - request.setUpdatedAt(updateResourceLimitGroupRequest.getUpdatedAt()); - } - - private RestResponseListener updateResourceLimitGroupResponse(final RestChannel channel) { - return new RestResponseListener<>(channel) { - @Override - public RestResponse buildResponse(final UpdateResourceLimitGroupResponse response) throws Exception { - return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS)); - } - }; - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/package-info.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/package-info.java deleted file mode 100644 index 6f0597a33e76c..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/rest/package-info.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * 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 for the rest classes for resource limit group CRUD operations - */ -package org.opensearch.plugin.rlg.rest; diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/Persistable.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/Persistable.java deleted file mode 100644 index 70d221c73070f..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/Persistable.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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.rlg.service; - -import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.rlg.CreateResourceLimitGroupResponse; -import org.opensearch.plugin.rlg.DeleteResourceLimitGroupResponse; -import org.opensearch.plugin.rlg.GetResourceLimitGroupResponse; -import org.opensearch.plugin.rlg.UpdateResourceLimitGroupResponse; - -/** - * This interface defines the key APIs for implementing resource limit group persistence - */ -public interface Persistable { - - // void persist(ResourceLimitGroup resourceLimitGroup, ActionListener listener); - - /** - * persists the resource limit group in a durable storage - * @param resourceLimitGroup - * @param listener - */ - void persist(T resourceLimitGroup, ActionListener listener); - - /** - * update the resource limit group in a durable storage - * @param resourceLimitGroup - * @param listener - */ - void update(T resourceLimitGroup, ActionListener listener); - - /** - * fetch the resource limit group in a durable storage - * @param name - * @param listener - */ - void get(String name, ActionListener listener); - - /** - * delete the resource limit group in a durable storage - * @param name - * @param listener - */ - void delete(String name, ActionListener listener); -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceService.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceService.java deleted file mode 100644 index 210b6224a4cb4..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceService.java +++ /dev/null @@ -1,464 +0,0 @@ -/* - * 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.rlg.service; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.opensearch.cluster.ClusterState; -import org.opensearch.cluster.ClusterStateUpdateTask; -import org.opensearch.cluster.metadata.Metadata; -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; -import org.opensearch.cluster.service.ClusterManagerTaskThrottler.ThrottlingKey; -import org.opensearch.cluster.service.ClusterService; -import org.opensearch.common.Priority; -import org.opensearch.common.inject.Inject; -import org.opensearch.common.settings.ClusterSettings; -import org.opensearch.common.settings.Settings; -import org.opensearch.core.action.ActionListener; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.plugin.rlg.CreateResourceLimitGroupResponse; -import org.opensearch.plugin.rlg.DeleteResourceLimitGroupResponse; -import org.opensearch.plugin.rlg.GetResourceLimitGroupResponse; -import org.opensearch.plugin.rlg.UpdateResourceLimitGroupResponse; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.DoubleAdder; -import java.util.stream.Collectors; - -import static org.opensearch.search.resource_limit_group.ResourceLimitGroupServiceSettings.MAX_RESOURCE_LIMIT_GROUP_COUNT; -import static org.opensearch.search.resource_limit_group.ResourceLimitGroupServiceSettings.RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME; - -/** - * This class defines the functions for Resource Limit Group persistence - */ -public class ResourceLimitGroupPersistenceService implements Persistable { - private static final Logger logger = LogManager.getLogger(ResourceLimitGroupPersistenceService.class); - private final ClusterService clusterService; - private static final String SOURCE = "resource-limit-group-persistence-service"; - private static final String CREATE_RESOURCE_LIMIT_GROUP_THROTTLING_KEY = "create-resource-limit-group"; - private static final String UPDATE_RESOURCE_LIMIT_GROUP_THROTTLING_KEY = "update-resource-limit-group"; - private static final String DELETE_RESOURCE_LIMIT_GROUP_THROTTLING_KEY = "delete-resource-limit-group"; - private final AtomicInteger inflightCreateResourceLimitGroupRequestCount; - private final Map inflightResourceLimitValues; - private volatile int maxResourceLimitGroupCount; - final ThrottlingKey createResourceLimitGroupThrottlingKey; - final ThrottlingKey updateResourceLimitGroupThrottlingKey; - final ThrottlingKey deleteResourceLimitGroupThrottlingKey; - - /** - * Constructor for Resource Limit GroupPersistenceService - * - * @param clusterService {@link ClusterService} - The cluster service to be used by ResourceLimitGroupPersistenceService - * @param settings {@link Settings} - The settings to be used by ResourceLimitGroupPersistenceService - * @param clusterSettings {@link ClusterSettings} - The cluster settings to be used by ResourceLimitGroupPersistenceService - */ - @Inject - public ResourceLimitGroupPersistenceService( - final ClusterService clusterService, - final Settings settings, - final ClusterSettings clusterSettings - ) { - this.clusterService = clusterService; - this.createResourceLimitGroupThrottlingKey = clusterService.registerClusterManagerTask( - CREATE_RESOURCE_LIMIT_GROUP_THROTTLING_KEY, - true - ); - this.deleteResourceLimitGroupThrottlingKey = clusterService.registerClusterManagerTask( - DELETE_RESOURCE_LIMIT_GROUP_THROTTLING_KEY, - true - ); - this.updateResourceLimitGroupThrottlingKey = clusterService.registerClusterManagerTask( - UPDATE_RESOURCE_LIMIT_GROUP_THROTTLING_KEY, - true - ); - maxResourceLimitGroupCount = MAX_RESOURCE_LIMIT_GROUP_COUNT.get(settings); - clusterSettings.addSettingsUpdateConsumer(MAX_RESOURCE_LIMIT_GROUP_COUNT, this::setMaxResourceLimitGroupCount); - inflightCreateResourceLimitGroupRequestCount = new AtomicInteger(); - inflightResourceLimitValues = new HashMap<>(); - } - - /** - * Set maxResourceLimitGroupCount to be newMaxResourceLimitGroupCount - * - * @param newMaxResourceLimitGroupCount - the max number of resource limit group allowed - */ - public void setMaxResourceLimitGroupCount(int newMaxResourceLimitGroupCount) { - if (newMaxResourceLimitGroupCount < 0) { - throw new IllegalArgumentException("node.resource_limit_group.max_count can't be negative"); - } - this.maxResourceLimitGroupCount = newMaxResourceLimitGroupCount; - } - - @Override - public void persist(ResourceLimitGroup resourceLimitGroup, ActionListener listener) { - persistInClusterStateMetadata(resourceLimitGroup, listener); - } - - @Override - public void update(ResourceLimitGroup resourceLimitGroup, ActionListener listener) { - updateInClusterStateMetadata(resourceLimitGroup, listener); - } - - @Override - public void get(String name, ActionListener listener) { - ClusterState currentState = clusterService.state(); - List resultGroups = getFromClusterStateMetadata(name, currentState); - if (resultGroups.isEmpty() && name != null && !name.isEmpty()) { - logger.warn("No Resource Limit Group exists with the provided name: {}", name); - Exception e = new RuntimeException("No Resource Limit Group exists with the provided name: " + name); - GetResourceLimitGroupResponse response = new GetResourceLimitGroupResponse(); - response.setRestStatus(RestStatus.NOT_FOUND); - listener.onFailure(e); - return; - } - GetResourceLimitGroupResponse response = new GetResourceLimitGroupResponse(resultGroups); - response.setRestStatus(RestStatus.OK); - listener.onResponse(response); - } - - @Override - public void delete(String name, ActionListener listener) { - deleteInClusterStateMetadata(name, listener); - } - - /** - * Update cluster state to include the new Resource Limit Group - * @param resourceLimitGroup {@link ResourceLimitGroup} - the resource limit group we're currently creating - */ - void persistInClusterStateMetadata(ResourceLimitGroup resourceLimitGroup, ActionListener listener) { - clusterService.submitStateUpdateTask(SOURCE, new ClusterStateUpdateTask(Priority.URGENT) { - @Override - public ClusterState execute(ClusterState currentState) throws Exception { - return saveResourceLimitGroupInClusterState(resourceLimitGroup, currentState); - } - - @Override - public ThrottlingKey getClusterManagerThrottlingKey() { - return createResourceLimitGroupThrottlingKey; - } - - @Override - public void onFailure(String source, Exception e) { - restoreInflightValues(resourceLimitGroup); - inflightCreateResourceLimitGroupRequestCount.decrementAndGet(); - logger.warn("failed to save Resource Limit Group object due to error: {}, for source: {}", e.getMessage(), source); - CreateResourceLimitGroupResponse response = new CreateResourceLimitGroupResponse(); - response.setRestStatus(RestStatus.FAILED_DEPENDENCY); - listener.onFailure(e); - } - - @Override - public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { - restoreInflightValues(resourceLimitGroup); - inflightCreateResourceLimitGroupRequestCount.decrementAndGet(); - CreateResourceLimitGroupResponse response = new CreateResourceLimitGroupResponse(resourceLimitGroup); - response.setRestStatus(RestStatus.OK); - listener.onResponse(response); - } - }); - } - - /** - * Get the allocation value for resourceName for the Resource Limit Group - * @param resourceLimitGroup {@link ResourceLimitGroup} - the resource limit group from which to get the JVM allocation value - */ - private double getResourceLimitValue(String resourceName, final ResourceLimitGroup resourceLimitGroup) { - double value = 0.0; - List resourceLimits = resourceLimitGroup.getResourceLimits(); - for (ResourceLimit resourceLimit : resourceLimits) { - if (resourceLimit.getResourceName().equals(resourceName)) { - value = resourceLimit.getValue(); - break; - } - } - return value; - } - - /** - * This method will be executed before we submit the new cluster state - * @param resourceLimitGroup - the resource limit group we're currently creating - * @param currentClusterState - the cluster state before the update - */ - ClusterState saveResourceLimitGroupInClusterState(final ResourceLimitGroup resourceLimitGroup, final ClusterState currentClusterState) { - final Metadata metadata = currentClusterState.metadata(); - String groupName = resourceLimitGroup.getName(); - final List previousGroups = new ArrayList<>(metadata.resourceLimitGroups().values()); - - // check if there's any resource allocation that exceed limit of 1.0 - String resourceNameWithThresholdExceeded = ""; - for (ResourceLimit resourceLimit : resourceLimitGroup.getResourceLimits()) { - String resourceName = resourceLimit.getResourceName(); - double existingUsage = calculateExistingUsage(resourceName, previousGroups, groupName); - double newGroupUsage = getResourceLimitValue(resourceName, resourceLimitGroup); - inflightResourceLimitValues.computeIfAbsent(resourceName, k -> new DoubleAdder()).add(newGroupUsage); - double totalUsage = existingUsage + inflightResourceLimitValues.get(resourceName).doubleValue(); - if (totalUsage > 1) { - resourceNameWithThresholdExceeded = resourceName; - } - } - // check if group count exceed max - boolean groupCountExceeded = inflightCreateResourceLimitGroupRequestCount.incrementAndGet() + previousGroups - .size() > maxResourceLimitGroupCount; - - if (metadata.resourceLimitGroups().containsKey(groupName)) { - logger.warn("Resource Limit Group with name {} already exists. Not creating a new one.", groupName); - throw new RuntimeException("Resource Limit Group with name " + groupName + " already exists. Not creating a new one."); - } - if (!resourceNameWithThresholdExceeded.isEmpty()) { - logger.error("Total resource allocation for {} will go above the max limit of 1.0", resourceNameWithThresholdExceeded); - throw new RuntimeException( - "Total resource allocation for " + resourceNameWithThresholdExceeded + " will go above the max limit of 1.0" - ); - } - if (groupCountExceeded) { - logger.error("{} value exceeded its assigned limit of {}", RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME, maxResourceLimitGroupCount); - throw new RuntimeException("Can't create more than " + maxResourceLimitGroupCount + " Resource Limit Groups in the system"); - } - - return ClusterState.builder(currentClusterState).metadata(Metadata.builder(metadata).put(resourceLimitGroup).build()).build(); - } - - /** - * This method restores the inflight values to be before the resource limit group is processed - * @param resourceLimitGroup - the resource limit group we're currently creating - */ - void restoreInflightValues(ResourceLimitGroup resourceLimitGroup) { - if (resourceLimitGroup.getResourceLimits() == null || resourceLimitGroup.getResourceLimits().isEmpty()) { - return; - } - for (ResourceLimit rl : resourceLimitGroup.getResourceLimits()) { - String currResourceName = rl.getResourceName(); - inflightResourceLimitValues.get(currResourceName).add(-getResourceLimitValue(currResourceName, resourceLimitGroup)); - } - } - - /** - * This method calculates the existing total usage of the resource (except the group that we're updating here) - * @param resourceName - the resource name we're calculating - * @param groupsList - existing resource limit groups - * @param groupName - the resource limit group name we're updating - */ - private double calculateExistingUsage(String resourceName, List groupsList, String groupName) { - double existingUsage = 0; - for (ResourceLimitGroup group : groupsList) { - if (!group.getName().equals(groupName)) { - existingUsage += getResourceLimitValue(resourceName, group); - } - } - return existingUsage; - } - - /** - * Modify cluster state to update the Resource Limit Group - * @param toUpdateGroup {@link ResourceLimitGroup} - the resource limit group that we want to update - */ - void updateInClusterStateMetadata( - ResourceLimitGroup toUpdateGroup, - ActionListener listener - ) { - clusterService.submitStateUpdateTask(SOURCE, new ClusterStateUpdateTask(Priority.URGENT) { - @Override - public ClusterState execute(ClusterState currentState) { - return updateResourceLimitGroupInClusterState(toUpdateGroup, currentState); - } - - @Override - public ThrottlingKey getClusterManagerThrottlingKey() { - return updateResourceLimitGroupThrottlingKey; - } - - @Override - public void onFailure(String source, Exception e) { - restoreInflightValues(toUpdateGroup); - logger.warn("Failed to update Resource Limit Group due to error: {}, for source: {}", e.getMessage(), source); - UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(); - response.setRestStatus(RestStatus.FAILED_DEPENDENCY); - listener.onFailure(e); - } - - @Override - public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { - restoreInflightValues(toUpdateGroup); - String name = toUpdateGroup.getName(); - assert newState.metadata().resourceLimitGroups().containsKey(name); - ResourceLimitGroup updatedGroup = newState.metadata().resourceLimitGroups().get(name); - UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(updatedGroup); - response.setRestStatus(RestStatus.OK); - listener.onResponse(response); - } - }); - } - - /** - * Modify cluster state to update the existing Resource Limit Group - * @param resourceLimitGroup {@link ResourceLimitGroup} - the resource limit group that we want to update - * @param currentState - current cluster state - */ - public ClusterState updateResourceLimitGroupInClusterState( - ResourceLimitGroup resourceLimitGroup, - ClusterState currentState - ) { - final Metadata metadata = currentState.metadata(); - Map currentGroupsMap = currentState.metadata().resourceLimitGroups(); - List currentGroupsList = new ArrayList<>(currentGroupsMap.values()); - String name = resourceLimitGroup.getName(); - String resourceNameWithThresholdExceeded = ""; - - // check if there's any resource allocation that exceed limit of 1.0 - if (resourceLimitGroup.getResourceLimits() != null) { - for (ResourceLimit resourceLimit : resourceLimitGroup.getResourceLimits()) { - String resourceName = resourceLimit.getResourceName(); - double existingUsage = calculateExistingUsage(resourceName, currentGroupsList, name); - double newGroupUsage = getResourceLimitValue(resourceName, resourceLimitGroup); - inflightResourceLimitValues.computeIfAbsent(resourceName, k -> new DoubleAdder()).add(newGroupUsage); - double totalUsage = existingUsage + inflightResourceLimitValues.get(resourceName).doubleValue(); - if (totalUsage > 1) { - resourceNameWithThresholdExceeded = resourceName; - } - } - } - - if (!currentGroupsMap.containsKey(name)) { - logger.warn("No Resource Limit Group exists with the provided name: {}", name); - throw new RuntimeException("No Resource Limit Group exists with the provided name: " + name); - } - if (!resourceNameWithThresholdExceeded.isEmpty()) { - logger.error("Total resource allocation for {} will go above the max limit of 1.0", resourceNameWithThresholdExceeded); - throw new RuntimeException( - "Total resource allocation for " + resourceNameWithThresholdExceeded + " will go above the max limit of 1.0" - ); - } - - // build the resource limit group with updated fields - ResourceLimitGroup existingGroup = currentGroupsMap.get(name); - String uuid = existingGroup.getUUID(); - String createdAt = existingGroup.getCreatedAt(); - String updatedAt = resourceLimitGroup.getUpdatedAt(); - List resourceLimit; - if (resourceLimitGroup.getResourceLimits() == null || resourceLimitGroup.getResourceLimits().isEmpty()) { - resourceLimit = existingGroup.getResourceLimits(); - } else { - resourceLimit = new ArrayList<>(existingGroup.getResourceLimits()); - Map resourceLimitMap = resourceLimitGroup.getResourceLimits() - .stream() - .collect(Collectors.toMap(ResourceLimit::getResourceName, ResourceLimit::getValue)); - for (ResourceLimit rl : resourceLimit) { - String currResourceName = rl.getResourceName(); - if (resourceLimitMap.containsKey(currResourceName)) { - rl.setValue(resourceLimitMap.get(currResourceName)); - } - } - } - String enforcement = resourceLimitGroup.getEnforcement() == null - ? existingGroup.getEnforcement() - : resourceLimitGroup.getEnforcement(); - - ResourceLimitGroup updatedGroup = new ResourceLimitGroup(name, uuid, resourceLimit, enforcement, createdAt, updatedAt); - return ClusterState.builder(currentState) - .metadata(Metadata.builder(metadata).removeResourceLimitGroup(existingGroup.getName()).put(updatedGroup).build()) - .build(); - } - - /** - * Modify cluster state to delete the Resource Limit Group - * @param name - the name for resource limit group to be deleted - */ - void deleteInClusterStateMetadata(String name, ActionListener listener) { - clusterService.submitStateUpdateTask(SOURCE, new ClusterStateUpdateTask(Priority.URGENT) { - @Override - public ClusterState execute(ClusterState currentState) throws Exception { - return deleteResourceLimitGroupInClusterState(name, currentState); - } - - @Override - public ThrottlingKey getClusterManagerThrottlingKey() { - return deleteResourceLimitGroupThrottlingKey; - } - - @Override - public void onFailure(String source, Exception e) { - logger.warn("Failed to delete Resource Limit Group due to error: {}, for source: {}", e.getMessage(), source); - DeleteResourceLimitGroupResponse response = new DeleteResourceLimitGroupResponse(); - response.setRestStatus(RestStatus.NOT_FOUND); - listener.onFailure(e); - } - - @Override - public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { - final Map oldGroupsMap = oldState.metadata().resourceLimitGroups(); - final Map newGroupssMap = newState.metadata().resourceLimitGroups(); - List deletedGroups = new ArrayList<>(); - for (String name : oldGroupsMap.keySet()) { - if (!newGroupssMap.containsKey(name)) { - deletedGroups.add(oldGroupsMap.get(name)); - } - } - DeleteResourceLimitGroupResponse response = new DeleteResourceLimitGroupResponse(deletedGroups); - response.setRestStatus(RestStatus.OK); - listener.onResponse(response); - } - }); - } - - /** - * Modify cluster state to delete the Resource Limit Group - * @param name - the name for resource limit group to be deleted - * @param currentClusterState - current cluster state - */ - ClusterState deleteResourceLimitGroupInClusterState(final String name, final ClusterState currentClusterState) { - final Metadata metadata = currentClusterState.metadata(); - final Map previousGroups = metadata.resourceLimitGroups(); - Map resultGroups = new HashMap<>(previousGroups); - ; - if (name == null || name.equals("")) { - resultGroups = new HashMap<>(); - } else { - boolean nameExists = previousGroups.containsKey(name); - if (!nameExists) { - logger.error("The Resource Limit Group with provided name {} doesn't exist", name); - throw new RuntimeException("No Resource Limit Group exists with the provided name: " + name); - } - resultGroups.remove(name); - } - return ClusterState.builder(currentClusterState) - .metadata(Metadata.builder(metadata).resourceLimitGroups(resultGroups).build()) - .build(); - } - - List getFromClusterStateMetadata(String name, ClusterState currentState) { - Map currentGroupsMap = currentState.getMetadata().resourceLimitGroups(); - List currentGroups = new ArrayList<>(currentGroupsMap.values()); - List resultGroups = new ArrayList<>(); - if (name == null || name.equals("")) { - resultGroups = currentGroups; - } else if (currentGroupsMap.containsKey(name)) { - resultGroups = List.of(currentGroupsMap.get(name)); - } - return resultGroups; - } - - /** - * inflightCreateResourceLimitGroupRequestCount getter - */ - public AtomicInteger getInflightCreateResourceLimitGroupRequestCount() { - return inflightCreateResourceLimitGroupRequestCount; - } - - /** - * inflightResourceLimitValues getter - */ - public Map getInflightResourceLimitValues() { - return inflightResourceLimitValues; - } -} diff --git a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/package-info.java b/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/package-info.java deleted file mode 100644 index 3a953b1ee97d2..0000000000000 --- a/plugins/query-resource-limit-group/src/main/java/org/opensearch/plugin/rlg/service/package-info.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 for the rest classes for resource limit group CRUD operations - */ - -/** - * Package for the service classes for resource limit group CRUD operations - */ -package org.opensearch.plugin.rlg.service; diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupRequestTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupRequestTests.java deleted file mode 100644 index 9ef9133d5c888..0000000000000 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupRequestTests.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.common.io.stream.BytesStreamOutput; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.test.OpenSearchTestCase; - -import java.io.IOException; - -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.compareResourceLimits; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupOne; - -public class CreateResourceLimitGroupRequestTests extends OpenSearchTestCase { - - public void testSerialization() throws IOException { - CreateResourceLimitGroupRequest request = new CreateResourceLimitGroupRequest(resourceLimitGroupOne); - BytesStreamOutput out = new BytesStreamOutput(); - request.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - CreateResourceLimitGroupRequest otherRequest = new CreateResourceLimitGroupRequest(streamInput); - assertEquals(request.getName(), otherRequest.getName()); - assertEquals(request.getResourceLimits().size(), otherRequest.getResourceLimits().size()); - assertEquals(request.getEnforcement(), otherRequest.getEnforcement()); - compareResourceLimits(request.getResourceLimits(), otherRequest.getResourceLimits()); - assertEquals(request.getCreatedAt(), otherRequest.getCreatedAt()); - assertEquals(request.getUpdatedAt(), otherRequest.getUpdatedAt()); - } -} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupResponseTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupResponseTests.java deleted file mode 100644 index c89b3fd3e3299..0000000000000 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/CreateResourceLimitGroupResponseTests.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.common.io.stream.BytesStreamOutput; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.test.OpenSearchTestCase; - -import java.io.IOException; -import java.util.List; - -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.compareResourceLimitGroups; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupOne; - -public class CreateResourceLimitGroupResponseTests extends OpenSearchTestCase { - - public void testSerialization() throws IOException { - CreateResourceLimitGroupResponse response = new CreateResourceLimitGroupResponse(resourceLimitGroupOne); - BytesStreamOutput out = new BytesStreamOutput(); - response.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - CreateResourceLimitGroupResponse otherResponse = new CreateResourceLimitGroupResponse(streamInput); - assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); - ResourceLimitGroup responseGroup = response.getResourceLimitGroup(); - ResourceLimitGroup otherResponseGroup = otherResponse.getResourceLimitGroup(); - compareResourceLimitGroups(List.of(responseGroup), List.of(otherResponseGroup)); - } -} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupResponseTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupResponseTests.java deleted file mode 100644 index 587f1c4754270..0000000000000 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/DeleteResourceLimitGroupResponseTests.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.common.io.stream.BytesStreamOutput; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.test.OpenSearchTestCase; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.compareResourceLimitGroups; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupList; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupOne; - -public class DeleteResourceLimitGroupResponseTests extends OpenSearchTestCase { - - public void testSerializationSingleResourceLimitGroup() throws IOException { - List list = List.of(resourceLimitGroupOne); - DeleteResourceLimitGroupResponse response = new DeleteResourceLimitGroupResponse(list); - assertEquals(response.getResourceLimitGroups(), list); - - BytesStreamOutput out = new BytesStreamOutput(); - response.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - - DeleteResourceLimitGroupResponse otherResponse = new DeleteResourceLimitGroupResponse(streamInput); - assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); - compareResourceLimitGroups(response.getResourceLimitGroups(), otherResponse.getResourceLimitGroups()); - } - - public void testSerializationMultipleResourceLimitGroup() throws IOException { - DeleteResourceLimitGroupResponse response = new DeleteResourceLimitGroupResponse(resourceLimitGroupList); - assertEquals(response.getResourceLimitGroups(), resourceLimitGroupList); - - BytesStreamOutput out = new BytesStreamOutput(); - response.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - - DeleteResourceLimitGroupResponse otherResponse = new DeleteResourceLimitGroupResponse(streamInput); - assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); - assertEquals(2, otherResponse.getResourceLimitGroups().size()); - compareResourceLimitGroups(response.getResourceLimitGroups(), otherResponse.getResourceLimitGroups()); - } - - public void testSerializationNull() throws IOException { - List list = new ArrayList<>(); - DeleteResourceLimitGroupResponse response = new DeleteResourceLimitGroupResponse(list); - assertEquals(response.getResourceLimitGroups(), list); - - BytesStreamOutput out = new BytesStreamOutput(); - response.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - - DeleteResourceLimitGroupResponse otherResponse = new DeleteResourceLimitGroupResponse(streamInput); - assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); - assertEquals(0, otherResponse.getResourceLimitGroups().size()); - } -} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/GetResourceLimitGroupResponseTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/GetResourceLimitGroupResponseTests.java deleted file mode 100644 index 34616bcdaf89e..0000000000000 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/GetResourceLimitGroupResponseTests.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.common.io.stream.BytesStreamOutput; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.test.OpenSearchTestCase; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.compareResourceLimitGroups; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupList; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupOne; - -public class GetResourceLimitGroupResponseTests extends OpenSearchTestCase { - - public void testSerializationSingleResourceLimitGroup() throws IOException { - List list = new ArrayList<>(); - list.add(resourceLimitGroupOne); - GetResourceLimitGroupResponse response = new GetResourceLimitGroupResponse(list); - assertEquals(response.getResourceLimitGroups(), list); - - BytesStreamOutput out = new BytesStreamOutput(); - response.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - - GetResourceLimitGroupResponse otherResponse = new GetResourceLimitGroupResponse(streamInput); - assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); - compareResourceLimitGroups(response.getResourceLimitGroups(), otherResponse.getResourceLimitGroups()); - } - - public void testSerializationMultipleResourceLimitGroup() throws IOException { - GetResourceLimitGroupResponse response = new GetResourceLimitGroupResponse(resourceLimitGroupList); - assertEquals(response.getResourceLimitGroups(), resourceLimitGroupList); - - BytesStreamOutput out = new BytesStreamOutput(); - response.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - - GetResourceLimitGroupResponse otherResponse = new GetResourceLimitGroupResponse(streamInput); - assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); - assertEquals(2, otherResponse.getResourceLimitGroups().size()); - compareResourceLimitGroups(response.getResourceLimitGroups(), otherResponse.getResourceLimitGroups()); - } - - public void testSerializationNull() throws IOException { - List list = new ArrayList<>(); - GetResourceLimitGroupResponse response = new GetResourceLimitGroupResponse(list); - assertEquals(response.getResourceLimitGroups(), list); - - BytesStreamOutput out = new BytesStreamOutput(); - response.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - - GetResourceLimitGroupResponse otherResponse = new GetResourceLimitGroupResponse(streamInput); - assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); - assertEquals(0, otherResponse.getResourceLimitGroups().size()); - } -} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/ResourceLimitGroupTestUtils.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/ResourceLimitGroupTestUtils.java deleted file mode 100644 index ebacff9270e77..0000000000000 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/ResourceLimitGroupTestUtils.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.cluster.ClusterName; -import org.opensearch.cluster.ClusterState; -import org.opensearch.cluster.metadata.Metadata; -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; -import org.opensearch.cluster.service.ClusterService; -import org.opensearch.common.settings.ClusterSettings; -import org.opensearch.common.settings.Settings; -import org.opensearch.plugin.rlg.service.ResourceLimitGroupPersistenceService; -import org.opensearch.threadpool.ThreadPool; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.DoubleAdder; -import java.util.stream.Collectors; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; - -public class ResourceLimitGroupTestUtils { - public static final String SANDBOX_MAX_SETTING_NAME = "node.sandbox.max_count"; - public static final String NAME_ONE = "sandbox_one"; - public static final String NAME_TWO = "sandbox_two"; - public static final String UUID_ONE = "AgfUO5Ja9yfsYlONlYi3TQ=="; - public static final String UUID_TWO = "G5iIqHy4g7eK1qIAAAAIH53=1"; - public static final String NAME_NONE_EXISTED = "sandbox_none_existed"; - public static final String MONITOR = "monitor"; - public static final String TIMESTAMP_ONE = "2024-04-26 23:02:21"; - public static final String TIMESTAMP_TWO = "2024-04-21 19:08:06"; - public static final ResourceLimitGroup resourceLimitGroupOne = new ResourceLimitGroup( - NAME_ONE, - UUID_ONE, - List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.3)), - MONITOR, - TIMESTAMP_ONE, - TIMESTAMP_ONE - ); - public static final ResourceLimitGroup resourceLimitGroupTwo = new ResourceLimitGroup( - NAME_TWO, - UUID_TWO, - List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.6)), - MONITOR, - TIMESTAMP_TWO, - TIMESTAMP_TWO - ); - public static final Map resourceLimitGroupMap = Map.of( - NAME_ONE, - resourceLimitGroupOne, - NAME_TWO, - resourceLimitGroupTwo - ); - public static final List resourceLimitGroupList = List.of(resourceLimitGroupOne, resourceLimitGroupTwo); - public static final Metadata metadata = Metadata.builder().resourceLimitGroups(resourceLimitGroupMap).build(); - public static final ClusterState clusterState = ClusterState.builder(new ClusterName("_name")).metadata(metadata).build(); - - public static final Settings settings = Settings.builder().build(); - public static final ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - public static final ClusterService clusterService = new ClusterService(settings, clusterSettings, mock(ThreadPool.class)); - public static final ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService = - new ResourceLimitGroupPersistenceService(clusterService, settings, clusterSettings); - - public static List prepareSandboxPersistenceService(List resourceLimitGroups) { - Map resourceLimitGroupMap = new HashMap<>(); - for (ResourceLimitGroup group : resourceLimitGroups) { - resourceLimitGroupMap.put(group.getName(), group); - } - Metadata metadata = Metadata.builder().resourceLimitGroups(resourceLimitGroupMap).build(); - Settings settings = Settings.builder().build(); - ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - ClusterService clusterService = new ClusterService(settings, clusterSettings, mock(ThreadPool.class)); - ClusterState clusterState = ClusterState.builder(new ClusterName("_name")).metadata(metadata).build(); - ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService = new ResourceLimitGroupPersistenceService( - clusterService, - settings, - clusterSettings - ); - return List.of(resourceLimitGroupPersistenceService, clusterState); - } - - public static void compareResourceLimits(List limitsOne, List limitsTwo) { - assertEquals(limitsOne.size(), limitsTwo.size()); - Map resourceLimitMapOne = limitsOne.stream() - .collect(Collectors.toMap(ResourceLimitGroup.ResourceLimit::getResourceName, ResourceLimitGroup.ResourceLimit::getValue)); - Map resourceLimitMapTwo = limitsTwo.stream() - .collect(Collectors.toMap(ResourceLimitGroup.ResourceLimit::getResourceName, ResourceLimitGroup.ResourceLimit::getValue)); - for (String resourceName : resourceLimitMapOne.keySet()) { - assertTrue(resourceLimitMapTwo.containsKey(resourceName)); - assertEquals(resourceLimitMapOne.get(resourceName), resourceLimitMapTwo.get(resourceName)); - } - } - - public static void compareResourceLimitGroups(List listOne, List listTwo) { - assertEquals(listOne.size(), listTwo.size()); - for (ResourceLimitGroup groupOne : listOne) { - String groupOneName = groupOne.getName(); - List groupTwoList = listTwo.stream() - .filter(sb -> sb.getName().equals(groupOneName)) - .collect(Collectors.toList()); - assertEquals(1, groupTwoList.size()); - ResourceLimitGroup groupTwo = groupTwoList.get(0); - assertEquals(groupOne.getName(), groupTwo.getName()); - assertEquals(groupOne.getUUID(), groupTwo.getUUID()); - compareResourceLimits(groupOne.getResourceLimits(), groupTwo.getResourceLimits()); - assertEquals(groupOne.getEnforcement(), groupTwo.getEnforcement()); - assertEquals(groupOne.getCreatedAt(), groupTwo.getCreatedAt()); - assertEquals(groupOne.getUpdatedAt(), groupTwo.getUpdatedAt()); - } - } - - public static void assertInflightValuesAreZero(ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService) { - assertEquals(0, resourceLimitGroupPersistenceService.getInflightCreateResourceLimitGroupRequestCount().get()); - Map inflightResourceMap = resourceLimitGroupPersistenceService.getInflightResourceLimitValues(); - if (inflightResourceMap != null) { - for (String resourceName: inflightResourceMap.keySet()) { - assertEquals(0, inflightResourceMap.get(resourceName).intValue()); - } - } - } -} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupRequestTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupRequestTests.java deleted file mode 100644 index 423a33ab5422d..0000000000000 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupRequestTests.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; -import org.opensearch.common.io.stream.BytesStreamOutput; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.test.OpenSearchTestCase; - -import java.io.IOException; -import java.util.List; - -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.NAME_ONE; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.TIMESTAMP_ONE; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.compareResourceLimits; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupOne; - -public class UpdateResourceLimitGroupRequestTests extends OpenSearchTestCase { - - public void testSerialization() throws IOException { - UpdateResourceLimitGroupRequest request = new UpdateResourceLimitGroupRequest(resourceLimitGroupOne); - BytesStreamOutput out = new BytesStreamOutput(); - request.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - UpdateResourceLimitGroupRequest otherRequest = new UpdateResourceLimitGroupRequest(streamInput); - assertEquals(request.getName(), otherRequest.getName()); - assertEquals(request.getResourceLimits().size(), otherRequest.getResourceLimits().size()); - assertEquals(request.getEnforcement(), otherRequest.getEnforcement()); - compareResourceLimits(request.getResourceLimits(), otherRequest.getResourceLimits()); - assertEquals(request.getUpdatedAt(), otherRequest.getUpdatedAt()); - } - - public void testSerializationOnlyName() throws IOException { - ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup(NAME_ONE, null, null, null, null, TIMESTAMP_ONE); - UpdateResourceLimitGroupRequest request = new UpdateResourceLimitGroupRequest(resourceLimitGroup); - BytesStreamOutput out = new BytesStreamOutput(); - request.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - UpdateResourceLimitGroupRequest otherRequest = new UpdateResourceLimitGroupRequest(streamInput); - assertEquals(request.getName(), otherRequest.getName()); - assertEquals(request.getResourceLimits(), otherRequest.getResourceLimits()); - assertEquals(request.getEnforcement(), otherRequest.getEnforcement()); - assertEquals(request.getUpdatedAt(), otherRequest.getUpdatedAt()); - } - - public void testSerializationOnlyResourceLimit() throws IOException { - ResourceLimitGroup resourceLimitGroup = new ResourceLimitGroup( - NAME_ONE, - null, - List.of(new ResourceLimit("jvm", 0.4)), - null, - null, - TIMESTAMP_ONE - ); - UpdateResourceLimitGroupRequest request = new UpdateResourceLimitGroupRequest(resourceLimitGroup); - BytesStreamOutput out = new BytesStreamOutput(); - request.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - UpdateResourceLimitGroupRequest otherRequest = new UpdateResourceLimitGroupRequest(streamInput); - assertEquals(request.getName(), otherRequest.getName()); - assertEquals(request.getResourceLimits().size(), otherRequest.getResourceLimits().size()); - compareResourceLimits(request.getResourceLimits(), otherRequest.getResourceLimits()); - assertEquals(request.getEnforcement(), otherRequest.getEnforcement()); - assertEquals(request.getUpdatedAt(), otherRequest.getUpdatedAt()); - } -} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupResponseTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupResponseTests.java deleted file mode 100644 index eefe7cbc60c6a..0000000000000 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/UpdateResourceLimitGroupResponseTests.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.rlg; - -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.common.io.stream.BytesStreamOutput; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.test.OpenSearchTestCase; - -import java.io.IOException; -import java.util.List; - -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.compareResourceLimitGroups; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.resourceLimitGroupOne; - -public class UpdateResourceLimitGroupResponseTests extends OpenSearchTestCase { - - public void testSerialization() throws IOException { - UpdateResourceLimitGroupResponse response = new UpdateResourceLimitGroupResponse(resourceLimitGroupOne); - BytesStreamOutput out = new BytesStreamOutput(); - response.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - UpdateResourceLimitGroupResponse otherResponse = new UpdateResourceLimitGroupResponse(streamInput); - assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); - ResourceLimitGroup responseGroup = response.getResourceLimitGroup(); - ResourceLimitGroup otherResponseGroup = otherResponse.getResourceLimitGroup(); - compareResourceLimitGroups(List.of(responseGroup), List.of(otherResponseGroup)); - } -} diff --git a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceServiceTests.java b/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceServiceTests.java deleted file mode 100644 index b8a09060cd3c1..0000000000000 --- a/plugins/query-resource-limit-group/src/test/java/org/opensearch/plugin/rlg/service/ResourceLimitGroupPersistenceServiceTests.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * 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.rlg.service; - -import org.opensearch.cluster.ClusterName; -import org.opensearch.cluster.ClusterState; -import org.opensearch.cluster.metadata.Metadata; -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.cluster.service.ClusterService; -import org.opensearch.common.settings.ClusterSettings; -import org.opensearch.common.settings.Settings; -import org.opensearch.test.OpenSearchTestCase; -import org.opensearch.threadpool.ThreadPool; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import static org.mockito.Mockito.mock; -import static org.opensearch.plugin.rlg.ResourceLimitGroupTestUtils.*; - -public class ResourceLimitGroupPersistenceServiceTests extends OpenSearchTestCase { - - public void testGetSingleResourceLimitGroup() { - List groups = resourceLimitGroupPersistenceService.getFromClusterStateMetadata(NAME_ONE, clusterState); - assertEquals(1, groups.size()); - ResourceLimitGroup resourceLimitGroup = groups.get(0); - compareResourceLimitGroups(List.of(resourceLimitGroupOne), List.of(resourceLimitGroup)); - assertInflightValuesAreZero(resourceLimitGroupPersistenceService); - } - - public void testGetAllResourceLimitGroups() { - List res = resourceLimitGroupPersistenceService.getFromClusterStateMetadata(null, clusterState); - assertEquals(2, res.size()); - Set currentNAME = res.stream().map(ResourceLimitGroup::getName).collect(Collectors.toSet()); - assertTrue(currentNAME.contains(NAME_ONE)); - assertTrue(currentNAME.contains(NAME_TWO)); - compareResourceLimitGroups(resourceLimitGroupList, res); - assertInflightValuesAreZero(resourceLimitGroupPersistenceService); - } - - public void testGetZeroResourceLimitGroups() { - Settings settings = Settings.builder().build(); - ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - ResourceLimitGroupPersistenceService sandboxPersistenceService = new ResourceLimitGroupPersistenceService( - mock(ClusterService.class), - settings, - clusterSettings - ); - List res = sandboxPersistenceService.getFromClusterStateMetadata(NAME_NONE_EXISTED, clusterState); - assertEquals(0, res.size()); - assertInflightValuesAreZero(resourceLimitGroupPersistenceService); - } - - public void testDeleteSingleResourceLimitGroup() { - ClusterState newClusterState = resourceLimitGroupPersistenceService.deleteResourceLimitGroupInClusterState(NAME_TWO, clusterState); - Map afterDeletionGroups = newClusterState.getMetadata().resourceLimitGroups(); - assertEquals(1, afterDeletionGroups.size()); - List oldSandbox = List.of(resourceLimitGroupMap.get(NAME_ONE)); - compareResourceLimitGroups(new ArrayList<>(afterDeletionGroups.values()), oldSandbox); - assertInflightValuesAreZero(resourceLimitGroupPersistenceService); - } - - public void testDeleteAllResourceLimitGroups() { - ClusterState newClusterState = resourceLimitGroupPersistenceService.deleteResourceLimitGroupInClusterState(null, clusterState); - Map sandboxes = newClusterState.getMetadata().resourceLimitGroups(); - assertEquals(0, sandboxes.size()); - assertInflightValuesAreZero(resourceLimitGroupPersistenceService); - } - - public void testDeleteNonExistedResourceLimitGroup() { - assertThrows( - RuntimeException.class, - () -> resourceLimitGroupPersistenceService.deleteResourceLimitGroupInClusterState(NAME_NONE_EXISTED, clusterState) - ); - } - - public void testUpdateResourceLimitGroupAllFields() { - String updatedTime = "2024-04-28 23:02:22"; - ResourceLimitGroup updated = new ResourceLimitGroup( - NAME_ONE, - UUID_ONE, - List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.15)), - MONITOR, - TIMESTAMP_ONE, - updatedTime - ); - ClusterState newClusterState = resourceLimitGroupPersistenceService.updateResourceLimitGroupInClusterState( - updated, - clusterState - ); - List updatedSandboxes = new ArrayList<>(newClusterState.getMetadata().resourceLimitGroups().values()); - assertEquals(2, updatedSandboxes.size()); - compareResourceLimitGroups(List.of(resourceLimitGroupTwo, updated), updatedSandboxes); - assertInflightValuesAreZero(resourceLimitGroupPersistenceService); - } - - public void testUpdateResourceLimitGroupResourceLimitOnly() { - String updatedTime = "2024-04-28 23:02:21"; - ResourceLimitGroup updated = new ResourceLimitGroup( - NAME_ONE, - resourceLimitGroupOne.getUUID(), - List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.13)), - MONITOR, - TIMESTAMP_ONE, - updatedTime - ); - ClusterState newClusterState = resourceLimitGroupPersistenceService.updateResourceLimitGroupInClusterState( - updated, - clusterState - ); - Map updatedSandboxesMap = newClusterState.getMetadata().resourceLimitGroups(); - assertEquals(2, updatedSandboxesMap.size()); - assertTrue(updatedSandboxesMap.containsKey(NAME_ONE)); - assertTrue(updatedSandboxesMap.containsKey(NAME_TWO)); - compareResourceLimitGroups(List.of(updated), List.of(updatedSandboxesMap.get(NAME_ONE))); - assertInflightValuesAreZero(resourceLimitGroupPersistenceService); - } - - public void testCreateResourceLimitGroup() { - List setup = prepareSandboxPersistenceService(new ArrayList<>()); - ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService1 = (ResourceLimitGroupPersistenceService) setup.get(0); - ClusterState clusterState = (ClusterState) setup.get(1); - ClusterState newClusterState = resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState( - resourceLimitGroupOne, - clusterState - ); - Map updatedGroupsMap = newClusterState.getMetadata().resourceLimitGroups(); - assertEquals(1, updatedGroupsMap.size()); - assertTrue(updatedGroupsMap.containsKey(NAME_ONE)); - compareResourceLimitGroups(List.of(resourceLimitGroupOne), List.of(updatedGroupsMap.get(NAME_ONE))); - assertInflightValuesAreZero(resourceLimitGroupPersistenceService); - } - - public void testCreateAnotherResourceLimitGroup() { - List setup = prepareSandboxPersistenceService(List.of(resourceLimitGroupOne)); - ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService1 = (ResourceLimitGroupPersistenceService) setup.get(0); - ClusterState clusterState = (ClusterState) setup.get(1); - ClusterState newClusterState = resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState( - resourceLimitGroupTwo, - clusterState - ); - Map updatedGroupsMap = newClusterState.getMetadata().resourceLimitGroups(); - assertEquals(2, updatedGroupsMap.size()); - compareResourceLimitGroups(resourceLimitGroupList, new ArrayList<>(updatedGroupsMap.values())); - assertInflightValuesAreZero(resourceLimitGroupPersistenceService); - } - - public void testCreateResourceLimitGroupDuplicateName() { - List setup = prepareSandboxPersistenceService(List.of(resourceLimitGroupOne)); - ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService1 = (ResourceLimitGroupPersistenceService) setup.get(0); - ClusterState clusterState = (ClusterState) setup.get(1); - ResourceLimitGroup toCreate = new ResourceLimitGroup( - NAME_ONE, - "W5iIqHyhgi4K1qIAAAAIHw==", - List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.3)), - MONITOR, - null, - null - ); - assertThrows( - RuntimeException.class, - () -> resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState(toCreate, clusterState) - ); - } - - public void testCreateResourceLimitGroupOverflowAllocation() { - List setup = prepareSandboxPersistenceService(List.of(resourceLimitGroupTwo)); - ResourceLimitGroup toCreate = new ResourceLimitGroup( - NAME_TWO, - null, - List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.5)), - MONITOR, - null, - null - ); - ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService1 = (ResourceLimitGroupPersistenceService) setup.get(0); - ClusterState clusterState = (ClusterState) setup.get(1); - assertThrows( - RuntimeException.class, - () -> resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState(toCreate, clusterState) - ); - } - - public void testCreateResourceLimitGroupOverflowCount() { - ResourceLimitGroup toCreate = new ResourceLimitGroup( - NAME_NONE_EXISTED, - null, - List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.5)), - MONITOR, - null, - null - ); - Metadata metadata = Metadata.builder().resourceLimitGroups(resourceLimitGroupMap).build(); - Settings settings = Settings.builder().put(SANDBOX_MAX_SETTING_NAME, 2).build(); - ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - ClusterService clusterService = new ClusterService(settings, clusterSettings, mock(ThreadPool.class)); - ClusterState clusterState = ClusterState.builder(new ClusterName("_name")).metadata(metadata).build(); - ResourceLimitGroupPersistenceService resourceLimitGroupPersistenceService1 = new ResourceLimitGroupPersistenceService( - clusterService, - settings, - clusterSettings - ); - assertThrows( - RuntimeException.class, - () -> resourceLimitGroupPersistenceService1.saveResourceLimitGroupInClusterState(toCreate, clusterState) - ); - } -} diff --git a/server/src/main/java/org/opensearch/cluster/ClusterModule.java b/server/src/main/java/org/opensearch/cluster/ClusterModule.java index 67714d420b0ba..5457a63ce4b76 100644 --- a/server/src/main/java/org/opensearch/cluster/ClusterModule.java +++ b/server/src/main/java/org/opensearch/cluster/ClusterModule.java @@ -48,8 +48,8 @@ import org.opensearch.cluster.metadata.MetadataIndexTemplateService; import org.opensearch.cluster.metadata.MetadataMappingService; import org.opensearch.cluster.metadata.MetadataUpdateSettingsService; +import org.opensearch.cluster.metadata.QueryGroupMetadata; import org.opensearch.cluster.metadata.RepositoriesMetadata; -import org.opensearch.cluster.metadata.ResourceLimitGroupMetadata; import org.opensearch.cluster.metadata.ViewMetadata; import org.opensearch.cluster.metadata.WeightedRoutingMetadata; import org.opensearch.cluster.routing.DelayedAllocationService; @@ -214,12 +214,8 @@ public static List getNamedWriteables() { DecommissionAttributeMetadata::new, DecommissionAttributeMetadata::readDiffFrom ); - registerMetadataCustom( - entries, - ResourceLimitGroupMetadata.TYPE, - ResourceLimitGroupMetadata::new, - ResourceLimitGroupMetadata::readDiffFrom - ); + + registerMetadataCustom(entries, QueryGroupMetadata.TYPE, QueryGroupMetadata::new, QueryGroupMetadata::readDiffFrom); // Task Status (not Diffable) entries.add(new Entry(Task.Status.class, PersistentTasksNodeService.Status.NAME, PersistentTasksNodeService.Status::new)); return entries; diff --git a/server/src/main/java/org/opensearch/cluster/metadata/Metadata.java b/server/src/main/java/org/opensearch/cluster/metadata/Metadata.java index d9aa19842ef38..b17ee2391c6be 100644 --- a/server/src/main/java/org/opensearch/cluster/metadata/Metadata.java +++ b/server/src/main/java/org/opensearch/cluster/metadata/Metadata.java @@ -835,10 +835,10 @@ public Map views() { return Optional.ofNullable((ViewMetadata) this.custom(ViewMetadata.TYPE)).map(ViewMetadata::views).orElse(Collections.emptyMap()); } - public Map resourceLimitGroups() { - return Optional.ofNullable((ResourceLimitGroupMetadata) this.custom(ResourceLimitGroupMetadata.TYPE)) - .map(ResourceLimitGroupMetadata::resourceLimitGroups) - .orElse(Collections.emptyMap()); + public Set queryGroups() { + return Optional.ofNullable((QueryGroupMetadata) this.custom(QueryGroupMetadata.TYPE)) + .map(QueryGroupMetadata::queryGroups) + .orElse(Collections.emptySet()); } public DecommissionAttributeMetadata decommissionAttributeMetadata() { @@ -1335,34 +1335,32 @@ public Builder removeDataStream(String name) { return this; } - public Builder resourceLimitGroups(final Map resourceLimitGroups) { - this.customs.put(ResourceLimitGroupMetadata.TYPE, new ResourceLimitGroupMetadata(resourceLimitGroups)); + public Builder queryGroups(final Set queryGroups) { + this.customs.put(QueryGroupMetadata.TYPE, new QueryGroupMetadata(queryGroups)); return this; } - public ResourceLimitGroup getResourceLimitGroup(final String resourceLimitGroupName) { - return getResourceLimitGroups().get(resourceLimitGroupName); - } - - public Builder put(final ResourceLimitGroup resourceLimitGroup) { - Objects.requireNonNull(resourceLimitGroup, "resourceLimitGroup should not be null"); - Map existing = new HashMap<>(getResourceLimitGroups()); - existing.put(resourceLimitGroup.getName(), resourceLimitGroup); - return resourceLimitGroups(existing); + public Builder put(final QueryGroup queryGroup) { + Objects.requireNonNull(queryGroup, "queryGroup should not be null"); + Set existing = getQueryGroups(); + HashSet updatedGroups = new HashSet<>(existing); + updatedGroups.add(queryGroup); + return queryGroups(updatedGroups); } - public Builder removeResourceLimitGroup(final String resourceLimitGroupName) { - Objects.requireNonNull(resourceLimitGroupName, "resourceLimitGroup should not be null"); - Map existing = new HashMap<>(getResourceLimitGroups()); - existing.remove(resourceLimitGroupName); - return resourceLimitGroups(existing); + public Builder remove(final QueryGroup queryGroup) { + Objects.requireNonNull(queryGroup, "queryGroup should not be null"); + Set existing = getQueryGroups(); + HashSet updatedGroups = new HashSet<>(existing); + updatedGroups.remove(queryGroup); + return queryGroups(updatedGroups); } - private Map getResourceLimitGroups() { - return Optional.ofNullable(this.customs.get(ResourceLimitGroupMetadata.TYPE)) - .map(o -> (ResourceLimitGroupMetadata) o) - .map(ResourceLimitGroupMetadata::resourceLimitGroups) - .orElse(Collections.emptyMap()); + public Set getQueryGroups() { + return Optional.ofNullable(this.customs.get(QueryGroupMetadata.TYPE)) + .map(o -> (QueryGroupMetadata) o) + .map(QueryGroupMetadata::queryGroups) + .orElse(Collections.emptySet()); } private Map getViews() { @@ -1761,8 +1759,8 @@ static void validateDataStreams(SortedMap indicesLooku for (DataStream ds : dsMetadata.dataStreams().values()) { String prefix = DataStream.BACKING_INDEX_PREFIX + ds.getName() + "-"; Set conflicts = indicesLookup.subMap(prefix, DataStream.BACKING_INDEX_PREFIX + ds.getName() + ".") // '.' is the - // char after - // '-' + // char after + // '-' .keySet() .stream() .filter(s -> NUMBER_PATTERN.matcher(s.substring(prefix.length())).matches()) diff --git a/server/src/main/java/org/opensearch/cluster/metadata/QueryGroup.java b/server/src/main/java/org/opensearch/cluster/metadata/QueryGroup.java new file mode 100644 index 0000000000000..509666a3e6c05 --- /dev/null +++ b/server/src/main/java/org/opensearch/cluster/metadata/QueryGroup.java @@ -0,0 +1,315 @@ +/* + * 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.cluster.metadata; + +import org.opensearch.cluster.AbstractDiffable; +import org.opensearch.cluster.Diff; +import org.opensearch.common.annotation.ExperimentalApi; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.ToXContentObject; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.core.xcontent.XContentParser; +import org.joda.time.Instant; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; + +/** + * Class to define the ResourceLimitGroup schema + * { + * "fafjafjkaf9ag8a9ga9g7ag0aagaga" : { + * "jvm": 0.4, + * "mode": "enforced", + * "name": "analytics", + * "updatedAt": 4513232415 + * } + * } + */ +@ExperimentalApi +public class QueryGroup extends AbstractDiffable implements ToXContentObject { + + public static final int MAX_CHARS_ALLOWED_IN_NAME = 50; + private final String name; + private final String _id; + private final QueryGroupMode mode; + // It is an epoch in millis + private final long updatedAtInMillis; + private final Map resourceLimits; + + // list of resources that are allowed to be present in the ResourceLimitGroup schema + public static final List ALLOWED_RESOURCES = List.of("jvm"); + + public QueryGroup(String name, String _id, QueryGroupMode mode, Map resourceLimits, long updatedAt) { + Objects.requireNonNull(name, "ResourceLimitGroup.name can't be null"); + Objects.requireNonNull(resourceLimits, "ResourceLimitGroup.resourceLimits can't be null"); + Objects.requireNonNull(mode, "ResourceLimitGroup.mode can't be null"); + Objects.requireNonNull(_id, "ResourceLimitGroup._id can't be null"); + + if (name.length() > MAX_CHARS_ALLOWED_IN_NAME) { + throw new IllegalArgumentException("ResourceLimitGroup.name shouldn't be more than 50 chars long"); + } + + if (resourceLimits.isEmpty()) { + throw new IllegalArgumentException("ResourceLimitGroup.resourceLimits should at least have 1 resource limit"); + } + validateResourceLimits(resourceLimits); + if (!isValid(updatedAt)) { + throw new IllegalArgumentException("ResourceLimitGroup.updatedAtInMillis is not a valid epoch"); + } + + this.name = name; + this._id = _id; + this.mode = mode; + this.resourceLimits = resourceLimits; + this.updatedAtInMillis = updatedAt; + } + + private static boolean isValid(long updatedAt) { + long minValidTimestamp = Instant.ofEpochMilli(0L).getMillis(); + + // Use Instant.now() to get the current time in seconds since epoch + long currentSeconds = Instant.now().getMillis(); + + // Check if the timestamp is within a reasonable range + return minValidTimestamp <= updatedAt && updatedAt <= currentSeconds; + } + + public QueryGroup(StreamInput in) throws IOException { + this(in.readString(), in.readString(), QueryGroupMode.fromName(in.readString()), in.readMap(), in.readLong()); + } + + /** + * Write this into the {@linkplain StreamOutput}. + * + * @param out + */ + @Override + public void writeTo(StreamOutput out) throws IOException { + writeToOutputStream(out, name, _id, mode, resourceLimits, updatedAtInMillis); + } + + public static void writeToOutputStream( + StreamOutput out, + String name, + String _id, + QueryGroupMode mode, + Map resourceLimits, + long updatedAtInMillis + ) throws IOException { + out.writeString(name); + out.writeString(_id); + out.writeString(mode.getName()); + out.writeMap(resourceLimits); + out.writeLong(updatedAtInMillis); + } + + private void validateResourceLimits(Map resourceLimits) { + for (Map.Entry resource : resourceLimits.entrySet()) { + String resourceName = resource.getKey(); + Double threshold = (Double) resource.getValue(); + Objects.requireNonNull(resourceName, "resourceName can't be null"); + Objects.requireNonNull(threshold, "resource value can't be null"); + + if (Double.compare(threshold, 1.0) > 0) { + throw new IllegalArgumentException("resource value should be less than 1.0"); + } + + if (!ALLOWED_RESOURCES.contains(resourceName.toLowerCase(Locale.ROOT))) { + throw new IllegalArgumentException( + "resource has to be valid, valid resources " + ALLOWED_RESOURCES.stream().reduce((x, e) -> x + ", " + e).get() + ); + } + } + } + + /** + * @param builder + * @param params + * @return + * @throws IOException + */ + @Override + public XContentBuilder toXContent(final XContentBuilder builder, final Params params) throws IOException { + builder.startObject(); + builder.startObject(this._id); + builder.field("name", name); + builder.field("mode", mode.getName()); + builder.field("updatedAt", updatedAtInMillis); + builder.mapContents(resourceLimits); + builder.endObject(); + builder.endObject(); + return builder; + } + + public static QueryGroup fromXContent(final XContentParser parser) throws IOException { + if (parser.currentToken() == null) { // fresh parser? move to the first token + parser.nextToken(); + } + if (parser.currentToken() == XContentParser.Token.START_OBJECT) { + parser.nextToken(); // move to field name + } + if (parser.currentToken() != XContentParser.Token.FIELD_NAME) { // on a start object move to next token + throw new IllegalArgumentException("Expected FIELD_NAME token but found [" + parser.currentName() + "]"); + } + + Builder builder = builder()._id(parser.currentName()); + + XContentParser.Token token = parser.nextToken(); + + if (token != XContentParser.Token.START_OBJECT) { + throw new IllegalArgumentException("Expected START_OBJECT token but found [" + parser.currentName() + "]"); + } + + String fieldName = ""; + // Map to hold resources + final Map resourceLimits_ = new HashMap<>(); + while ((token = parser.nextToken()) != null) { + if (token == XContentParser.Token.FIELD_NAME) { + fieldName = parser.currentName(); + } else if (token.isValue()) { + if (fieldName.equals("name")) { + builder.name(parser.text()); + } else if (fieldName.equals("mode")) { + builder.mode(parser.text()); + } else if (fieldName.equals("updatedAt")) { + builder.updatedAt(parser.longValue()); + } else if (ALLOWED_RESOURCES.contains(fieldName)) { + resourceLimits_.put(fieldName, parser.doubleValue()); + } else { + throw new IllegalArgumentException("unrecognised [field=" + fieldName + " in ResourceLimitGroup"); + } + } + } + builder.resourceLimits(resourceLimits_); + return builder.build(); + } + + public static Diff readDiff(final StreamInput in) throws IOException { + return readDiffFrom(QueryGroup::new, in); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + QueryGroup that = (QueryGroup) o; + return Objects.equals(name, that.name) && Objects.equals(resourceLimits, that.resourceLimits); + } + + @Override + public int hashCode() { + return Objects.hash(name, resourceLimits); + } + + public String getName() { + return name; + } + + public QueryGroupMode getMode() { + return mode; + } + + public Map getResourceLimits() { + return resourceLimits; + } + + public String get_id() { + return _id; + } + + public long getUpdatedAtInMillis() { + return updatedAtInMillis; + } + + /** + * builder method for this {@link QueryGroup} + * @return + */ + public static Builder builder() { + return new Builder(); + } + + /** + * This enum models the different sandbox modes + */ + @ExperimentalApi + public enum QueryGroupMode { + SOFT("soft"), + ENFORCED("enforced"), + MONITOR("monitor"); + + private final String name; + + QueryGroupMode(String mode) { + this.name = mode; + } + + public String getName() { + return name; + } + + public static QueryGroupMode fromName(String s) { + for (QueryGroupMode mode : values()) { + if (mode.getName().equalsIgnoreCase(s)) return mode; + + } + throw new IllegalArgumentException("Invalid value for ResourceLimitGroupMode: " + s); + } + + } + + /** + * Builder class for {@link QueryGroup} + */ + @ExperimentalApi + public static class Builder { + private String name; + private String _id; + private QueryGroupMode mode; + private long updatedAt; + private Map resourceLimits; + + private Builder() {} + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder _id(String _id) { + this._id = _id; + return this; + } + + public Builder mode(String mode) { + this.mode = QueryGroupMode.fromName(mode); + return this; + } + + public Builder updatedAt(long updatedAt) { + this.updatedAt = updatedAt; + return this; + } + + public Builder resourceLimits(Map resourceLimits) { + this.resourceLimits = resourceLimits; + return this; + } + + public QueryGroup build() { + return new QueryGroup(name, _id, mode, resourceLimits, updatedAt); + } + + } +} diff --git a/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroupMetadata.java b/server/src/main/java/org/opensearch/cluster/metadata/QueryGroupMetadata.java similarity index 52% rename from server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroupMetadata.java rename to server/src/main/java/org/opensearch/cluster/metadata/QueryGroupMetadata.java index 3107bd8f44136..073432e6aa15a 100644 --- a/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroupMetadata.java +++ b/server/src/main/java/org/opensearch/cluster/metadata/QueryGroupMetadata.java @@ -25,49 +25,52 @@ import java.io.IOException; import java.util.EnumSet; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Objects; +import java.util.Set; import static org.opensearch.cluster.metadata.Metadata.ALL_CONTEXTS; /** - * {@link ResourceLimitGroupMetadata} is a custom {@link Metadata} implementation for Resource Limit Group - * - * @opensearch.internal + * This class holds the QueryGroupMetadata + * sample schema + * { + * "queryGroups": { + * "_id": { + * {@link QueryGroup} + * }, + * ... + * } + * } */ @ExperimentalApi -public class ResourceLimitGroupMetadata implements Metadata.Custom { - public static final String TYPE = "resourceLimitGroup"; - private static final ParseField RESOURCE_LIMIT_GROUP_FIELD = new ParseField("resourceLimitGroups"); +public class QueryGroupMetadata implements Metadata.Custom { + public static final String TYPE = "queryGroup"; + private static final ParseField QUERY_GROUP_FIELD = new ParseField("queryGroups"); @SuppressWarnings("unchecked") - static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( - "resourceLimitGroupParser", - args -> new ResourceLimitGroupMetadata((Map) args[0]) + static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( + "queryGroupParser", + args -> new QueryGroupMetadata((Set) args[0]) ); static { - PARSER.declareObject(ConstructingObjectParser.constructorArg(), (p, c) -> { - Map resourceLimitGroupMap = new HashMap<>(); - while (p.nextToken() != XContentParser.Token.END_OBJECT) { - resourceLimitGroupMap.put(p.currentName(), ResourceLimitGroup.fromXContent(p)); - } - return resourceLimitGroupMap; - }, RESOURCE_LIMIT_GROUP_FIELD); + PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), (p, c) -> QueryGroup.fromXContent(p), QUERY_GROUP_FIELD); } - private final Map resourceLimitGroups; + private final Set queryGroups; - public ResourceLimitGroupMetadata(Map resourceLimitGroups) { - this.resourceLimitGroups = resourceLimitGroups; + public QueryGroupMetadata(Set queryGroups) { + this.queryGroups = queryGroups; } - public ResourceLimitGroupMetadata(StreamInput in) throws IOException { - this.resourceLimitGroups = in.readMap(StreamInput::readString, ResourceLimitGroup::new); + public QueryGroupMetadata(StreamInput in) throws IOException { + this.queryGroups = in.readSet(QueryGroup::new); } - public Map resourceLimitGroups() { - return this.resourceLimitGroups; + public Set queryGroups() { + return this.queryGroups; } /** @@ -93,7 +96,7 @@ public Version getMinimalSupportedVersion() { */ @Override public void writeTo(StreamOutput out) throws IOException { - out.writeMap(resourceLimitGroups, StreamOutput::writeString, (stream, val) -> val.writeTo(stream)); + out.writeCollection(queryGroups); } /** @@ -104,15 +107,11 @@ public void writeTo(StreamOutput out) throws IOException { */ @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject(RESOURCE_LIMIT_GROUP_FIELD.getPreferredName()); - for (Map.Entry entry : resourceLimitGroups.entrySet()) { - builder.field(entry.getKey(), entry.getValue()); - } - builder.endObject(); + builder.field(QUERY_GROUP_FIELD.getPreferredName(), queryGroups); return builder; } - public static ResourceLimitGroupMetadata fromXContent(XContentParser parser) throws IOException { + public static QueryGroupMetadata fromXContent(XContentParser parser) throws IOException { return PARSER.parse(parser, null); } @@ -123,44 +122,71 @@ public static ResourceLimitGroupMetadata fromXContent(XContentParser parser) thr */ @Override public Diff diff(final Metadata.Custom previousState) { - return new ResourceLimitGroupMetadataDiff((ResourceLimitGroupMetadata) previousState, this); + return new QueryGroupMetadataDiff((QueryGroupMetadata) previousState, this); } + /** + * @param in + * @return the metadata diff for {@link QueryGroupMetadata} objects + * @throws IOException + */ public static NamedDiff readDiffFrom(StreamInput in) throws IOException { - return new ResourceLimitGroupMetadataDiff(in); + return new QueryGroupMetadataDiff(in); } - /** - * @return - */ @Override public EnumSet context() { return ALL_CONTEXTS; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + QueryGroupMetadata that = (QueryGroupMetadata) o; + return Objects.equals(queryGroups, that.queryGroups); + } + + @Override + public int hashCode() { + return Objects.hash(queryGroups); + } + + @Override + public String toString() { + return Strings.toString(MediaTypeRegistry.JSON, this); + } + /** - * ResourceLimitGroupMetadataDiff + * QueryGroupMetadataDiff */ - static class ResourceLimitGroupMetadataDiff implements NamedDiff { - final Diff> dataStreanDiff; + static class QueryGroupMetadataDiff implements NamedDiff { + final Diff> dataStreamDiff; - ResourceLimitGroupMetadataDiff(final ResourceLimitGroupMetadata before, final ResourceLimitGroupMetadata after) { - dataStreanDiff = DiffableUtils.diff( - before.resourceLimitGroups, - after.resourceLimitGroups, + QueryGroupMetadataDiff(final QueryGroupMetadata before, final QueryGroupMetadata after) { + dataStreamDiff = DiffableUtils.diff( + toMap(before.queryGroups), + toMap(after.queryGroups), DiffableUtils.getStringKeySerializer() ); } - ResourceLimitGroupMetadataDiff(final StreamInput in) throws IOException { - this.dataStreanDiff = DiffableUtils.readJdkMapDiff( + QueryGroupMetadataDiff(final StreamInput in) throws IOException { + this.dataStreamDiff = DiffableUtils.readJdkMapDiff( in, DiffableUtils.getStringKeySerializer(), - ResourceLimitGroup::new, - ResourceLimitGroup::readDiff + QueryGroup::new, + QueryGroup::readDiff ); } + private Map toMap(Set queryGroups) { + final Map queryGroupMap = new HashMap<>(); + + queryGroups.forEach(queryGroup -> queryGroupMap.put(queryGroup.getName(), queryGroup)); + return queryGroupMap; + } + /** * Returns the name of the writeable object */ @@ -176,7 +202,7 @@ public String getWriteableName() { */ @Override public void writeTo(StreamOutput out) throws IOException { - dataStreanDiff.writeTo(out); + dataStreamDiff.writeTo(out); } /** @@ -186,25 +212,7 @@ public void writeTo(StreamOutput out) throws IOException { */ @Override public Metadata.Custom apply(Metadata.Custom part) { - return new ResourceLimitGroupMetadata(dataStreanDiff.apply(((ResourceLimitGroupMetadata) part).resourceLimitGroups)); + return new QueryGroupMetadata(new HashSet<>(dataStreamDiff.apply(toMap(((QueryGroupMetadata) part).queryGroups)).values())); } } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ResourceLimitGroupMetadata that = (ResourceLimitGroupMetadata) o; - return Objects.equals(resourceLimitGroups, that.resourceLimitGroups); - } - - @Override - public int hashCode() { - return Objects.hash(resourceLimitGroups); - } - - @Override - public String toString() { - return Strings.toString(MediaTypeRegistry.JSON, this); - } } diff --git a/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java b/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java deleted file mode 100644 index c750ec54316f3..0000000000000 --- a/server/src/main/java/org/opensearch/cluster/metadata/ResourceLimitGroup.java +++ /dev/null @@ -1,364 +0,0 @@ -/* - * 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.cluster.metadata; - -import org.opensearch.cluster.AbstractDiffable; -import org.opensearch.cluster.Diff; -import org.opensearch.common.UUIDs; -import org.opensearch.common.annotation.ExperimentalApi; -import org.opensearch.core.ParseField; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.common.io.stream.Writeable; -import org.opensearch.core.xcontent.ConstructingObjectParser; -import org.opensearch.core.xcontent.ToXContentObject; -import org.opensearch.core.xcontent.XContentBuilder; -import org.opensearch.core.xcontent.XContentParser; - -import java.io.IOException; -import java.time.Instant; -import java.time.ZoneId; -import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.Locale; -import java.util.Objects; - -/** - * Class to define the ResourceLimitGroup schema - * { - * "uuid": "" - * "name": "analytics", - * "resourceLimits": [ - * { - * "resourceName": "jvm", - * "value": 0.4 - * } - * ], - * "enforcement": "monitor" - * } - */ -@ExperimentalApi -public class ResourceLimitGroup extends AbstractDiffable implements ToXContentObject { - - private final String name; - private final String uuid; - private final List resourceLimits; - private final String enforcement; - private final String createdAt; - private final String updatedAt; - - private static final List ALLOWED_RESOURCES = List.of("jvm"); - private static final List ALLOWED_ENFORCEMENTS = List.of("monitor"); - - public static final ParseField NAME_FIELD = new ParseField("name"); - public static final ParseField RESOURCE_LIMITS_FIELD = new ParseField("resourceLimits"); - public static final ParseField ENFORCEMENT_FIELD = new ParseField("enforcement"); - public static final ParseField UPDATED_TIMESTAMP_FIELD = new ParseField("updatedAt"); - - @SuppressWarnings("unchecked") - private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( - "ResourceLimitGroupParser", - args -> { - Instant currentTimestamp = Instant.now(); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd' 'HH:mm:ss", Locale.getDefault()) - .withZone(ZoneId.of("UTC")); - String formattedTimestamp = formatter.format(currentTimestamp); - return new ResourceLimitGroup( - (String) args[0], - UUIDs.randomBase64UUID(), - (List) args[1], - (String) args[2], - formattedTimestamp, - formattedTimestamp - ); - } - ); - - static { - PARSER.declareString(ConstructingObjectParser.constructorArg(), NAME_FIELD); - PARSER.declareObjectArray( - ConstructingObjectParser.constructorArg(), - (p, c) -> ResourceLimit.fromXContent(p), - RESOURCE_LIMITS_FIELD - ); - PARSER.declareString(ConstructingObjectParser.constructorArg(), ENFORCEMENT_FIELD); - } - - private static final ConstructingObjectParser PARSER_OPTIONAL_FIELDS = new ConstructingObjectParser<>( - "ResourceLimitGroupParser", - args -> { - Instant currentTimestamp = Instant.now(); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd' 'HH:mm:ss", Locale.getDefault()) - .withZone(ZoneId.of("UTC")); - String formattedTimestamp = formatter.format(currentTimestamp); - return new ResourceLimitGroup(null, null, (List) args[0], (String) args[1], null, formattedTimestamp); - } - ); - - static { - PARSER_OPTIONAL_FIELDS.declareObjectArray( - ConstructingObjectParser.optionalConstructorArg(), - (p, c) -> ResourceLimit.fromXContent(p), - RESOURCE_LIMITS_FIELD - ); - PARSER_OPTIONAL_FIELDS.declareString(ConstructingObjectParser.optionalConstructorArg(), ENFORCEMENT_FIELD); - } - - public ResourceLimitGroup( - String name, - String uuid, - List resourceLimits, - String enforcement, - String createdAt, - String updatedAt - ) { - isValidResourceLimitGroup(name, resourceLimits, enforcement); - this.name = name; - this.uuid = uuid; - this.resourceLimits = resourceLimits; - this.enforcement = enforcement; - this.createdAt = createdAt; - this.updatedAt = updatedAt; - } - - public ResourceLimitGroup(StreamInput in) throws IOException { - this(in.readString(), in.readString(), in.readList(ResourceLimit::new), in.readString(), in.readString(), in.readString()); - } - - private void isValidResourceLimitGroup(String name, List resourceLimits, String enforcement) { - if (name != null) { - if (name.isEmpty()) { - throw new IllegalArgumentException("Resource Limit Group name cannot be empty"); - } - if (name.startsWith("-") || name.startsWith("_")) { - throw new IllegalArgumentException("Resource Limit Group name cannot start with '_' or '-'."); - } - if (!name.toLowerCase(Locale.ROOT).equals(name)) { - throw new IllegalArgumentException("Resource Limit Group name must be lowercase"); - } - if (name.matches(".*[ ,:\"*+/\\\\|?#><].*")) { - throw new IllegalArgumentException( - "Resource Limit Group names can't contain spaces, commas, quotes, slashes, :, *, +, |, ?, #, >, or <" - ); - } - } - if (resourceLimits != null && resourceLimits.isEmpty()) { - throw new IllegalArgumentException("Resource limit cannot be empty."); - } - if (enforcement != null) { - if (!ALLOWED_ENFORCEMENTS.contains(enforcement)) { - throw new IllegalArgumentException( - "enforcement has to be valid, valid enforcements are: " - + ALLOWED_ENFORCEMENTS.stream().reduce((x, e) -> x + ", " + e).get() - ); - } - } - } - - /** - * Class to hold the system resource limits; - * sample Schema - * - */ - @ExperimentalApi - public static class ResourceLimit implements Writeable, ToXContentObject { - private final String resourceName; - private Double value; - - static final ParseField RESOURCE_NAME_FIELD = new ParseField("resourceName"); - static final ParseField RESOURCE_VALUE_FIELD = new ParseField("value"); - - public static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( - "ResourceLimitParser", - args -> new ResourceLimit((String) args[0], (Double) args[1]) - ); - - static { - PARSER.declareString(ConstructingObjectParser.constructorArg(), RESOURCE_NAME_FIELD); - PARSER.declareDouble(ConstructingObjectParser.constructorArg(), RESOURCE_VALUE_FIELD); - } - - public ResourceLimit(String resourceName, Double value) { - Objects.requireNonNull(resourceName, "resourceName can't be null"); - Objects.requireNonNull(value, "resource value can't be null"); - isValidResourceLimit(resourceName, value); - this.resourceName = resourceName; - this.value = value; - } - - public ResourceLimit(StreamInput in) throws IOException { - this(in.readString(), in.readDouble()); - } - - private static void isValidResourceLimit(String resourceName, double value) { - if (value < 0 || value > 1) { - throw new IllegalArgumentException("Resource limit value should be between 0 and 1."); - } - String str = String.valueOf(value); - if (str.contains(".") && str.split("\\.")[1].length() > 2) { - throw new IllegalArgumentException("Resource limit value should have at most two digits after the decimal point"); - } - if (!ALLOWED_RESOURCES.contains(resourceName.toLowerCase(Locale.ROOT))) { - throw new IllegalArgumentException( - "resource has to be valid, valid resources are: " + ALLOWED_RESOURCES.stream().reduce((x, e) -> x + ", " + e).get() - ); - } - } - - /** - * Write this into the {@linkplain StreamOutput}. - * - * @param out - */ - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeString(resourceName); - out.writeDouble(value); - } - - /** - * @param builder - * @param params - * @return - * @throws IOException - */ - @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject(); - builder.field(RESOURCE_NAME_FIELD.getPreferredName(), resourceName); - builder.field(RESOURCE_VALUE_FIELD.getPreferredName(), value); - builder.endObject(); - return builder; - } - - public static ResourceLimit fromXContent(final XContentParser parser) throws IOException { - return PARSER.parse(parser, null); - } - - public String getResourceName() { - return resourceName; - } - - public Double getValue() { - return value; - } - - public void setValue(Double value) { - this.value = value; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ResourceLimit that = (ResourceLimit) o; - return Objects.equals(resourceName, that.resourceName) && Objects.equals(value, that.value); - } - - @Override - public int hashCode() { - return Objects.hash(resourceName, value); - } - } - - /** - * Write this into the {@linkplain StreamOutput}. - * - * @param out - */ - @Override - public void writeTo(StreamOutput out) throws IOException { - writeToOutputStream(out, name, uuid, resourceLimits, enforcement, createdAt, updatedAt); - } - - public static void writeToOutputStream( - StreamOutput out, - String name, - String uuid, - List resourceLimits, - String enforcement, - String createdAt, - String updatedAt - ) throws IOException { - out.writeString(name); - out.writeString(uuid); - out.writeList(resourceLimits); - out.writeString(enforcement); - out.writeString(createdAt); - out.writeString(updatedAt); - } - - /** - * @param builder - * @param params - * @return - * @throws IOException - */ - @Override - public XContentBuilder toXContent(final XContentBuilder builder, final Params params) throws IOException { - builder.startObject(); - builder.field(NAME_FIELD.getPreferredName(), name); - builder.field(RESOURCE_LIMITS_FIELD.getPreferredName(), resourceLimits); - builder.field(ENFORCEMENT_FIELD.getPreferredName(), enforcement); - builder.field(UPDATED_TIMESTAMP_FIELD.getPreferredName(), updatedAt); - builder.endObject(); - return builder; - } - - public static ResourceLimitGroup fromXContent(final XContentParser parser) throws IOException { - return PARSER.parse(parser, null); - } - - public static ResourceLimitGroup fromXContentOptionalFields(final XContentParser parser) throws IOException { - return PARSER_OPTIONAL_FIELDS.parse(parser, null); - } - - public static Diff readDiff(final StreamInput in) throws IOException { - return readDiffFrom(ResourceLimitGroup::new, in); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ResourceLimitGroup that = (ResourceLimitGroup) o; - return Objects.equals(name, that.name) - && Objects.equals(resourceLimits, that.resourceLimits) - && Objects.equals(enforcement, that.enforcement); - } - - @Override - public int hashCode() { - return Objects.hash(name, resourceLimits, enforcement); - } - - public String getName() { - return name; - } - - public List getResourceLimits() { - return resourceLimits; - } - - public String getEnforcement() { - return enforcement; - } - - public String getUUID() { - return uuid; - } - - public String getCreatedAt() { - return createdAt; - } - - public String getUpdatedAt() { - return updatedAt; - } -} diff --git a/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java b/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java index e297f3e3c5d2f..7ab6bd389b15f 100644 --- a/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java +++ b/server/src/main/java/org/opensearch/common/settings/ClusterSettings.java @@ -156,7 +156,7 @@ import org.opensearch.search.backpressure.settings.SearchShardTaskSettings; import org.opensearch.search.backpressure.settings.SearchTaskSettings; import org.opensearch.search.fetch.subphase.highlight.FastVectorHighlighter; -import org.opensearch.search.resource_limit_group.ResourceLimitGroupServiceSettings; +import org.opensearch.search.query_group.QueryGroupServiceSettings; import org.opensearch.snapshots.InternalSnapshotsInfoService; import org.opensearch.snapshots.SnapshotsService; import org.opensearch.tasks.TaskCancellationMonitoringSettings; @@ -320,7 +320,7 @@ public void apply(Settings value, Settings current, Settings previous) { DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_INCLUDE_RELOCATIONS_SETTING, DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_REROUTE_INTERVAL_SETTING, SameShardAllocationDecider.CLUSTER_ROUTING_ALLOCATION_SAME_HOST_SETTING, - ResourceLimitGroupServiceSettings.MAX_RESOURCE_LIMIT_GROUP_COUNT, + QueryGroupServiceSettings.MAX_QUERY_GROUP_COUNT, ShardStateAction.FOLLOW_UP_REROUTE_PRIORITY_SETTING, InternalClusterInfoService.INTERNAL_CLUSTER_INFO_UPDATE_INTERVAL_SETTING, InternalClusterInfoService.INTERNAL_CLUSTER_INFO_TIMEOUT_SETTING, @@ -744,9 +744,9 @@ public void apply(Settings value, Settings current, Settings previous) { RemoteStoreSettings.CLUSTER_REMOTE_MAX_TRANSLOG_READERS, // Resource Limit Group settings - ResourceLimitGroupServiceSettings.MAX_RESOURCE_LIMIT_GROUP_COUNT, - ResourceLimitGroupServiceSettings.NODE_LEVEL_REJECTION_THRESHOLD, - ResourceLimitGroupServiceSettings.NODE_LEVEL_CANCELLATION_THRESHOLD + QueryGroupServiceSettings.MAX_QUERY_GROUP_COUNT, + QueryGroupServiceSettings.NODE_LEVEL_REJECTION_THRESHOLD, + QueryGroupServiceSettings.NODE_LEVEL_CANCELLATION_THRESHOLD ) ) ); diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupPruner.java b/server/src/main/java/org/opensearch/search/query_group/QueryGroupPruner.java similarity index 53% rename from server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupPruner.java rename to server/src/main/java/org/opensearch/search/query_group/QueryGroupPruner.java index 50b532eeadeb8..c46324adef639 100644 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupPruner.java +++ b/server/src/main/java/org/opensearch/search/query_group/QueryGroupPruner.java @@ -6,15 +6,15 @@ * compatible open source license. */ -package org.opensearch.search.resource_limit_group; +package org.opensearch.search.query_group; /** - * This interface is used to identify and completely remove deleted resourceLimitGroups which has been marked as deleted + * This interface is used to identify and completely remove deleted QueryGroups which has been marked as deleted * previously but had the tasks running at the time of deletion request */ -public interface ResourceLimitGroupPruner { +public interface QueryGroupPruner { /** - * remove the deleted resourceLimitGroups from the system once all the tasks in those resourceLimitGroups are completed/cancelled + * remove the deleted QueryGroups from the system once all the tasks in those QueryGroups are completed/cancelled */ - void pruneResourceLimitGroup(); + void pruneQueryGroup(); } diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupService.java b/server/src/main/java/org/opensearch/search/query_group/QueryGroupService.java similarity index 53% rename from server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupService.java rename to server/src/main/java/org/opensearch/search/query_group/QueryGroupService.java index 97c9aac64a9a2..d274c1561f1a9 100644 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupService.java +++ b/server/src/main/java/org/opensearch/search/query_group/QueryGroupService.java @@ -6,52 +6,52 @@ * compatible open source license. */ -package org.opensearch.search.resource_limit_group; +package org.opensearch.search.query_group; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.opensearch.common.inject.Inject; import org.opensearch.common.lifecycle.AbstractLifecycleComponent; -import org.opensearch.search.resource_limit_group.cancellation.ResourceLimitGroupRequestCanceller; -import org.opensearch.search.resource_limit_group.tracker.ResourceLimitGroupResourceUsageTracker; +import org.opensearch.search.query_group.cancellation.QueryGroupRequestCanceller; +import org.opensearch.search.query_group.tracker.QueryGroupResourceUsageTracker; import org.opensearch.threadpool.Scheduler; import org.opensearch.threadpool.ThreadPool; import java.io.IOException; /** - * Main service which will run periodically to track and cancel resource constraint violating tasks in resourceLimitGroups + * Main service which will run periodically to track and cancel resource constraint violating tasks in QueryGroup */ -public class ResourceLimitGroupService extends AbstractLifecycleComponent { - private static final Logger logger = LogManager.getLogger(ResourceLimitGroupService.class); +public class QueryGroupService extends AbstractLifecycleComponent { + private static final Logger logger = LogManager.getLogger(QueryGroupService.class); - private final ResourceLimitGroupResourceUsageTracker requestTracker; - private final ResourceLimitGroupRequestCanceller requestCanceller; - private final ResourceLimitGroupPruner resourceLimitGroupPruner; + private final QueryGroupResourceUsageTracker requestTracker; + private final QueryGroupRequestCanceller requestCanceller; + private final QueryGroupPruner queryGroupPruner; private volatile Scheduler.Cancellable scheduledFuture; - private final ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings; + private final QueryGroupServiceSettings queryGroupServiceSettings; private final ThreadPool threadPool; /** * Guice managed constructor * @param requestTrackerService * @param requestCanceller - * @param resourceLimitGroupPruner - * @param resourceLimitGroupServiceSettings + * @param queryGroupPruner + * @param queryGroupServiceSettings * @param threadPool */ @Inject - public ResourceLimitGroupService( - ResourceLimitGroupResourceUsageTracker requestTrackerService, - ResourceLimitGroupRequestCanceller requestCanceller, - ResourceLimitGroupPruner resourceLimitGroupPruner, - ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings, + public QueryGroupService( + QueryGroupResourceUsageTracker requestTrackerService, + QueryGroupRequestCanceller requestCanceller, + QueryGroupPruner queryGroupPruner, + QueryGroupServiceSettings queryGroupServiceSettings, ThreadPool threadPool ) { this.requestTracker = requestTrackerService; this.requestCanceller = requestCanceller; - this.resourceLimitGroupPruner = resourceLimitGroupPruner; - this.resourceLimitGroupServiceSettings = resourceLimitGroupServiceSettings; + this.queryGroupPruner = queryGroupPruner; + this.queryGroupServiceSettings = queryGroupServiceSettings; this.threadPool = threadPool; } @@ -59,9 +59,9 @@ public ResourceLimitGroupService( * run at regular interval */ private void doRun() { - requestTracker.updateResourceLimitGroupsResourceUsage(); + requestTracker.updateQueryGroupsResourceUsage(); requestCanceller.cancelViolatingTasks(); - resourceLimitGroupPruner.pruneResourceLimitGroup(); + queryGroupPruner.pruneQueryGroup(); } /** @@ -75,7 +75,7 @@ protected void doStart() { } catch (Exception e) { logger.debug("Exception occurred in Resource Limit Group service", e); } - }, resourceLimitGroupServiceSettings.getRunIntervalMillis(), ThreadPool.Names.GENERIC); + }, queryGroupServiceSettings.getRunIntervalMillis(), ThreadPool.Names.GENERIC); } @Override diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettings.java b/server/src/main/java/org/opensearch/search/query_group/QueryGroupServiceSettings.java similarity index 72% rename from server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettings.java rename to server/src/main/java/org/opensearch/search/query_group/QueryGroupServiceSettings.java index 9f792390fd8ff..db54737b3c458 100644 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettings.java +++ b/server/src/main/java/org/opensearch/search/query_group/QueryGroupServiceSettings.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.search.resource_limit_group; +package org.opensearch.search.query_group; import org.opensearch.common.settings.ClusterSettings; import org.opensearch.common.settings.Setting; @@ -14,48 +14,48 @@ import org.opensearch.common.unit.TimeValue; /** - * Main class to declare the query ResourceLimitGrouping feature related settings + * Main class to declare the QueryGroup feature related settings */ -public class ResourceLimitGroupServiceSettings { +public class QueryGroupServiceSettings { private static final Long DEFAULT_RUN_INTERVAL_MILLIS = 1000l; private static final Double DEFAULT_NODE_LEVEL_REJECTION_THRESHOLD = 0.8; private static final Double DEFAULT_NODE_LEVEL_CANCELLATION_THRESHOLD = 0.9; /** - * default max ResourceLimitGroup count on any node at any given point in time + * default max queryGroup count on any node at any given point in time */ - public static final int DEFAULT_MAX_RESOURCE_LIMIT_GROUP_COUNT_VALUE = 100; + public static final int DEFAULT_MAX_QUERY_GROUP_COUNT_VALUE = 100; - public static final String RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME = "node.resource_limit_group.max_count"; + public static final String QUERY_GROUP_COUNT_SETTING_NAME = "node.query_group.max_count"; public static final double NODE_LEVEL_CANCELLATION_THRESHOLD_MAX_VALUE = 0.95; public static final double NODE_LEVEL_REJECTION_THRESHOLD_MAX_VALUE = 0.90; private TimeValue runIntervalMillis; private Double nodeLevelJvmCancellationThreshold; private Double nodeLevelJvmRejectionThreshold; - private volatile int maxResourceLimitGroupCount; + private volatile int maxQueryGroupCount; /** - * max ResourceLimitGroup count setting + * max QueryGroup count setting */ - public static final Setting MAX_RESOURCE_LIMIT_GROUP_COUNT = Setting.intSetting( - RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME, - DEFAULT_MAX_RESOURCE_LIMIT_GROUP_COUNT_VALUE, + public static final Setting MAX_QUERY_GROUP_COUNT = Setting.intSetting( + QUERY_GROUP_COUNT_SETTING_NAME, + DEFAULT_MAX_QUERY_GROUP_COUNT_VALUE, 0, (newVal) -> { if (newVal > 100 || newVal < 1) throw new IllegalArgumentException( - RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME + " should be in range [1-100]" + QUERY_GROUP_COUNT_SETTING_NAME + " should be in range [1-100]" ); }, Setting.Property.Dynamic, Setting.Property.NodeScope ); /** - * Setting name for default ResourceLimitGroup count + * Setting name for default QueryGroup count */ - public static final String SERVICE_RUN_INTERVAL_MILLIS_SETTING_NAME = "resource_limit_group.service.run_interval_millis"; + public static final String SERVICE_RUN_INTERVAL_MILLIS_SETTING_NAME = "query_group.service.run_interval_millis"; /** * Setting to control the run interval of QSB service */ - private static final Setting RESOURCE_LIMIT_GROUP_RUN_INTERVAL_SETTING = Setting.longSetting( + private static final Setting QUERY_GROUP_RUN_INTERVAL_SETTING = Setting.longSetting( SERVICE_RUN_INTERVAL_MILLIS_SETTING_NAME, DEFAULT_RUN_INTERVAL_MILLIS, 1, @@ -66,7 +66,7 @@ public class ResourceLimitGroupServiceSettings { /** * Setting name for node level rejection threshold for QSB */ - public static final String NODE_REJECTION_THRESHOLD_SETTING_NAME = "resource_limit_group.node.rejection_threshold"; + public static final String NODE_REJECTION_THRESHOLD_SETTING_NAME = "query_group.node.rejection_threshold"; /** * Setting to control the rejection threshold */ @@ -79,7 +79,7 @@ public class ResourceLimitGroupServiceSettings { /** * Setting name for node level cancellation threshold */ - public static final String NODE_CANCELLATION_THRESHOLD_SETTING_NAME = "resource_limit_group.node.cancellation_threshold"; + public static final String NODE_CANCELLATION_THRESHOLD_SETTING_NAME = "query_group.node.cancellation_threshold"; /** * Setting name for node level cancellation threshold */ @@ -91,19 +91,19 @@ public class ResourceLimitGroupServiceSettings { ); /** - * ResourceLimitGroup service settings constructor + * QueryGroup service settings constructor * @param settings * @param clusterSettings */ - public ResourceLimitGroupServiceSettings(Settings settings, ClusterSettings clusterSettings) { - runIntervalMillis = new TimeValue(RESOURCE_LIMIT_GROUP_RUN_INTERVAL_SETTING.get(settings)); + public QueryGroupServiceSettings(Settings settings, ClusterSettings clusterSettings) { + runIntervalMillis = new TimeValue(QUERY_GROUP_RUN_INTERVAL_SETTING.get(settings)); nodeLevelJvmCancellationThreshold = NODE_LEVEL_CANCELLATION_THRESHOLD.get(settings); nodeLevelJvmRejectionThreshold = NODE_LEVEL_REJECTION_THRESHOLD.get(settings); - maxResourceLimitGroupCount = MAX_RESOURCE_LIMIT_GROUP_COUNT.get(settings); + maxQueryGroupCount = MAX_QUERY_GROUP_COUNT.get(settings); ensureRejectionThresholdIsLessThanCancellation(nodeLevelJvmRejectionThreshold, nodeLevelJvmCancellationThreshold); - clusterSettings.addSettingsUpdateConsumer(MAX_RESOURCE_LIMIT_GROUP_COUNT, this::setMaxResourceLimitGroupCount); + clusterSettings.addSettingsUpdateConsumer(MAX_QUERY_GROUP_COUNT, this::setMaxQueryGroupCount); clusterSettings.addSettingsUpdateConsumer(NODE_LEVEL_CANCELLATION_THRESHOLD, this::setNodeLevelJvmCancellationThreshold); clusterSettings.addSettingsUpdateConsumer(NODE_LEVEL_REJECTION_THRESHOLD, this::setNodeLevelJvmRejectionThreshold); } @@ -117,14 +117,14 @@ public TimeValue getRunIntervalMillis() { } /** - * Method to set the new ResourceLimitGroup count - * @param newMaxResourceLimitGroupCount is the new maxResourceLimitGroupCount per node + * Method to set the new QueryGroup count + * @param newMaxQueryGroupCount is the new maxQueryGroupCount per node */ - public void setMaxResourceLimitGroupCount(int newMaxResourceLimitGroupCount) { - if (newMaxResourceLimitGroupCount < 0) { - throw new IllegalArgumentException("node.ResourceLimitGroup.max_count can't be negative"); + public void setMaxQueryGroupCount(int newMaxQueryGroupCount) { + if (newMaxQueryGroupCount < 0) { + throw new IllegalArgumentException("node.QueryGroup.max_count can't be negative"); } - this.maxResourceLimitGroupCount = newMaxResourceLimitGroupCount; + this.maxQueryGroupCount = newMaxQueryGroupCount; } /** @@ -189,10 +189,10 @@ private void ensureRejectionThresholdIsLessThanCancellation( } /** - * Method to get the current ResourceLimitGroup count - * @return the current max ResourceLimitGroup count + * Method to get the current QueryGroup count + * @return the current max QueryGroup count */ - public int getMaxResourceLimitGroupCount() { - return maxResourceLimitGroupCount; + public int getMaxQueryGroupCount() { + return maxQueryGroupCount; } } diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/cancellation/ResourceLimitGroupRequestCanceller.java b/server/src/main/java/org/opensearch/search/query_group/cancellation/QueryGroupRequestCanceller.java similarity index 61% rename from server/src/main/java/org/opensearch/search/resource_limit_group/cancellation/ResourceLimitGroupRequestCanceller.java rename to server/src/main/java/org/opensearch/search/query_group/cancellation/QueryGroupRequestCanceller.java index 77be6104c9600..e33d771d33673 100644 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/cancellation/ResourceLimitGroupRequestCanceller.java +++ b/server/src/main/java/org/opensearch/search/query_group/cancellation/QueryGroupRequestCanceller.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.search.resource_limit_group.cancellation; +package org.opensearch.search.query_group.cancellation; /** - * This interface is used to identify and cancel the violating tasks in a resourceLimitGroup + * This interface is used to identify and cancel the violating tasks in a QueryGroup */ -public interface ResourceLimitGroupRequestCanceller { +public interface QueryGroupRequestCanceller { /** - * Cancels the tasks from conteded resourceLimitGroups + * Cancels the tasks from conteded QueryGroups */ void cancelViolatingTasks(); } diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/cancellation/package-info.java b/server/src/main/java/org/opensearch/search/query_group/cancellation/package-info.java similarity index 79% rename from server/src/main/java/org/opensearch/search/resource_limit_group/cancellation/package-info.java rename to server/src/main/java/org/opensearch/search/query_group/cancellation/package-info.java index 01502e42e9dfc..0e9fe853df60a 100644 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/cancellation/package-info.java +++ b/server/src/main/java/org/opensearch/search/query_group/cancellation/package-info.java @@ -9,4 +9,4 @@ /** * Package for cancellation related abstracts */ -package org.opensearch.search.resource_limit_group.cancellation; +package org.opensearch.search.query_group.cancellation; diff --git a/server/src/main/java/org/opensearch/search/query_group/module/QueryGroupModule.java b/server/src/main/java/org/opensearch/search/query_group/module/QueryGroupModule.java new file mode 100644 index 0000000000000..d39ffd7419f97 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/query_group/module/QueryGroupModule.java @@ -0,0 +1,33 @@ +/* + * 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.search.query_group.module; + +import org.opensearch.common.inject.AbstractModule; +import org.opensearch.search.query_group.QueryGroupPruner; +import org.opensearch.search.query_group.cancellation.QueryGroupRequestCanceller; +import org.opensearch.search.query_group.tracker.QueryGroupResourceUsageTracker; +import org.opensearch.search.query_group.tracker.QueryGroupResourceUsageTrackerService; + +/** + * Module class for resource usage limiting related artifacts + */ +public class QueryGroupModule extends AbstractModule { + + /** + * Default constructor + */ + public QueryGroupModule() {} + + @Override + protected void configure() { + bind(QueryGroupResourceUsageTracker.class).to(QueryGroupResourceUsageTrackerService.class).asEagerSingleton(); + bind(QueryGroupRequestCanceller.class).to(QueryGroupResourceUsageTrackerService.class).asEagerSingleton(); + bind(QueryGroupPruner.class).to(QueryGroupResourceUsageTrackerService.class).asEagerSingleton(); + } +} diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/module/package-info.java b/server/src/main/java/org/opensearch/search/query_group/module/package-info.java similarity index 79% rename from server/src/main/java/org/opensearch/search/resource_limit_group/module/package-info.java rename to server/src/main/java/org/opensearch/search/query_group/module/package-info.java index b547a83cd5a42..6f341d6941317 100644 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/module/package-info.java +++ b/server/src/main/java/org/opensearch/search/query_group/module/package-info.java @@ -10,4 +10,4 @@ * Guice Module */ -package org.opensearch.search.resource_limit_group.module; +package org.opensearch.search.query_group.module; diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/package-info.java b/server/src/main/java/org/opensearch/search/query_group/package-info.java similarity index 82% rename from server/src/main/java/org/opensearch/search/resource_limit_group/package-info.java rename to server/src/main/java/org/opensearch/search/query_group/package-info.java index 04e807374c1ff..e7b8443799e83 100644 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/package-info.java +++ b/server/src/main/java/org/opensearch/search/query_group/package-info.java @@ -9,4 +9,4 @@ /** * Query Sandboxing related artifacts */ -package org.opensearch.search.resource_limit_group; +package org.opensearch.search.query_group; diff --git a/server/src/main/java/org/opensearch/search/query_group/tracker/QueryGroupResourceUsageTracker.java b/server/src/main/java/org/opensearch/search/query_group/tracker/QueryGroupResourceUsageTracker.java new file mode 100644 index 0000000000000..957a716c1ef89 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/query_group/tracker/QueryGroupResourceUsageTracker.java @@ -0,0 +1,19 @@ +/* + * 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.search.query_group.tracker; + +/** + * This interface is mainly for tracking the QueryGroup level resource usages + */ +public interface QueryGroupResourceUsageTracker { + /** + * updates the current resource usage of QueryGroups + */ + public void updateQueryGroupsResourceUsage(); +} diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitsGroupResourceUsageTrackerService.java b/server/src/main/java/org/opensearch/search/query_group/tracker/QueryGroupResourceUsageTrackerService.java similarity index 79% rename from server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitsGroupResourceUsageTrackerService.java rename to server/src/main/java/org/opensearch/search/query_group/tracker/QueryGroupResourceUsageTrackerService.java index 5e14b6935c564..812a1de686850 100644 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitsGroupResourceUsageTrackerService.java +++ b/server/src/main/java/org/opensearch/search/query_group/tracker/QueryGroupResourceUsageTrackerService.java @@ -6,12 +6,13 @@ * compatible open source license. */ -package org.opensearch.search.resource_limit_group.tracker; +package org.opensearch.search.query_group.tracker; import org.opensearch.common.inject.Inject; import org.opensearch.core.tasks.resourcetracker.TaskResourceUsage; -import org.opensearch.search.resource_limit_group.ResourceLimitGroupPruner; -import org.opensearch.search.resource_limit_group.cancellation.ResourceLimitGroupRequestCanceller; +import org.opensearch.search.query_group.QueryGroupPruner; +import org.opensearch.search.query_group.QueryGroupService; +import org.opensearch.search.query_group.cancellation.QueryGroupRequestCanceller; import org.opensearch.tasks.Task; import org.opensearch.tasks.TaskCancellation; import org.opensearch.tasks.TaskManager; @@ -24,14 +25,14 @@ import java.util.stream.Collectors; /** - * This class tracks requests per resourceLimitGroups + * This class tracks requests per QueryGroups */ -public class ResourceLimitsGroupResourceUsageTrackerService +public class QueryGroupResourceUsageTrackerService implements TaskManager.TaskEventListeners, - ResourceLimitGroupResourceUsageTracker, - ResourceLimitGroupRequestCanceller, - ResourceLimitGroupPruner { + QueryGroupResourceUsageTracker, + QueryGroupRequestCanceller, + QueryGroupPruner { private static final String CPU = "CPU"; private static final String JVM_ALLOCATIONS = "JVM_Allocations"; @@ -39,32 +40,29 @@ public class ResourceLimitsGroupResourceUsageTrackerService private static final long totalAvailableJvmMemory = Runtime.getRuntime().totalMemory(); private final LongSupplier timeNanosSupplier; /** - * ResourceLimitGroup ids which are marked for deletion in between the - * {@link org.opensearch.search.resource_limit_group.ResourceLimitGroupService} runs + * QueryGroup ids which are marked for deletion in between the + * {@link QueryGroupService} runs */ - private List toDeleteResourceLimitGroups; - private List activeResourceLimitGroups; + private List toDeleteQueryGroups; + private List activeQueryGroups; private final TaskManager taskManager; private final TaskResourceTrackingService taskResourceTrackingService; /** - * ResourceLimitsGroupResourceUsageTrackerService constructor + * QueryGroupResourceUsageTrackerService constructor * @param taskManager * @param taskResourceTrackingService */ @Inject - public ResourceLimitsGroupResourceUsageTrackerService( - TaskManager taskManager, - TaskResourceTrackingService taskResourceTrackingService - ) { + public QueryGroupResourceUsageTrackerService(TaskManager taskManager, TaskResourceTrackingService taskResourceTrackingService) { this.taskManager = taskManager; this.taskResourceTrackingService = taskResourceTrackingService; - toDeleteResourceLimitGroups = Collections.synchronizedList(new ArrayList<>()); + toDeleteQueryGroups = Collections.synchronizedList(new ArrayList<>()); this.timeNanosSupplier = System::nanoTime; } @Override - public void updateResourceLimitGroupsResourceUsage() { + public void updateQueryGroupsResourceUsage() { } @@ -110,8 +108,8 @@ public double getAbsoluteJvmAllocationsUsageInPercent() { /** * filter out the deleted Resource Limit Groups which still has unfinished tasks */ - public void pruneResourceLimitGroup() { - toDeleteResourceLimitGroups = toDeleteResourceLimitGroups.stream().filter(this::hasUnfinishedTasks).collect(Collectors.toList()); + public void pruneQueryGroup() { + toDeleteQueryGroups = toDeleteQueryGroups.stream().filter(this::hasUnfinishedTasks).collect(Collectors.toList()); } private boolean hasUnfinishedTasks(String sandboxId) { @@ -158,7 +156,7 @@ private List getCancellableTasks() { public void deleteSandbox(String sandboxId) { if (hasUnfinishedTasks(sandboxId)) { - toDeleteResourceLimitGroups.add(sandboxId); + toDeleteQueryGroups.add(sandboxId); } // remove this sandbox from the active sandboxes } diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/package-info.java b/server/src/main/java/org/opensearch/search/query_group/tracker/package-info.java similarity index 81% rename from server/src/main/java/org/opensearch/search/resource_limit_group/tracker/package-info.java rename to server/src/main/java/org/opensearch/search/query_group/tracker/package-info.java index 64d8911f8a1a7..e4e85965da439 100644 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/package-info.java +++ b/server/src/main/java/org/opensearch/search/query_group/tracker/package-info.java @@ -9,4 +9,4 @@ /** * ResourceLimitGroup resource tracking artifacts */ -package org.opensearch.search.resource_limit_group.tracker; +package org.opensearch.search.query_group.tracker; diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/module/ResourceLimitGroupModule.java b/server/src/main/java/org/opensearch/search/resource_limit_group/module/ResourceLimitGroupModule.java deleted file mode 100644 index fb2d607e4f774..0000000000000 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/module/ResourceLimitGroupModule.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.search.resource_limit_group.module; - -import org.opensearch.common.inject.AbstractModule; -import org.opensearch.search.resource_limit_group.ResourceLimitGroupPruner; -import org.opensearch.search.resource_limit_group.cancellation.ResourceLimitGroupRequestCanceller; -import org.opensearch.search.resource_limit_group.tracker.ResourceLimitGroupResourceUsageTracker; -import org.opensearch.search.resource_limit_group.tracker.ResourceLimitsGroupResourceUsageTrackerService; - -/** - * Module class for resource usage limiting related artifacts - */ -public class ResourceLimitGroupModule extends AbstractModule { - - /** - * Default constructor - */ - public ResourceLimitGroupModule() {} - - @Override - protected void configure() { - bind(ResourceLimitGroupResourceUsageTracker.class).to(ResourceLimitsGroupResourceUsageTrackerService.class).asEagerSingleton(); - bind(ResourceLimitGroupRequestCanceller.class).to(ResourceLimitsGroupResourceUsageTrackerService.class).asEagerSingleton(); - bind(ResourceLimitGroupPruner.class).to(ResourceLimitsGroupResourceUsageTrackerService.class).asEagerSingleton(); - } -} diff --git a/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitGroupResourceUsageTracker.java b/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitGroupResourceUsageTracker.java deleted file mode 100644 index dccf5d4552bca..0000000000000 --- a/server/src/main/java/org/opensearch/search/resource_limit_group/tracker/ResourceLimitGroupResourceUsageTracker.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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.search.resource_limit_group.tracker; - -/** - * This interface is mainly for tracking the resourceLimitGroup level resource usages - */ -public interface ResourceLimitGroupResourceUsageTracker { - /** - * updates the current resource usage of resourceLimitGroups - */ - public void updateResourceLimitGroupsResourceUsage(); -} diff --git a/server/src/test/java/org/opensearch/cluster/metadata/QueryGroupMetadataTests.java b/server/src/test/java/org/opensearch/cluster/metadata/QueryGroupMetadataTests.java new file mode 100644 index 0000000000000..3dcaa7ee31b4d --- /dev/null +++ b/server/src/test/java/org/opensearch/cluster/metadata/QueryGroupMetadataTests.java @@ -0,0 +1,43 @@ +/* + * 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.cluster.metadata; + +import org.opensearch.core.common.io.stream.NamedWriteableRegistry; +import org.opensearch.test.AbstractNamedWriteableTestCase; + +import java.util.Collections; +import java.util.Set; + +import static org.opensearch.cluster.metadata.QueryGroupTests.createRandomResourceLimitGroup; + +public class QueryGroupMetadataTests extends AbstractNamedWriteableTestCase { + + @Override + protected NamedWriteableRegistry getNamedWriteableRegistry() { + return new NamedWriteableRegistry( + Collections.singletonList( + new NamedWriteableRegistry.Entry(QueryGroupMetadata.class, QueryGroupMetadata.TYPE, QueryGroupMetadata::new) + ) + ); + } + + @Override + protected Class categoryClass() { + return QueryGroupMetadata.class; + } + + @Override + protected QueryGroupMetadata createTestInstance() { + return new QueryGroupMetadata(getRandomResourceLimitGroups()); + } + + private Set getRandomResourceLimitGroups() { + return Set.of(createRandomResourceLimitGroup(), createRandomResourceLimitGroup()); + } +} diff --git a/server/src/test/java/org/opensearch/cluster/metadata/QueryGroupTests.java b/server/src/test/java/org/opensearch/cluster/metadata/QueryGroupTests.java new file mode 100644 index 0000000000000..2e7dc2812e431 --- /dev/null +++ b/server/src/test/java/org/opensearch/cluster/metadata/QueryGroupTests.java @@ -0,0 +1,144 @@ +/* + * 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.cluster.metadata; + +import org.opensearch.core.common.io.stream.Writeable; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.test.AbstractSerializingTestCase; +import org.joda.time.Instant; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class QueryGroupTests extends AbstractSerializingTestCase { + + private static final List allowedModes = List.of( + QueryGroup.QueryGroupMode.SOFT, + QueryGroup.QueryGroupMode.ENFORCED, + QueryGroup.QueryGroupMode.MONITOR + ); + + static QueryGroup createRandomResourceLimitGroup() { + String name = randomAlphaOfLength(10); + Map resourceLimit = new HashMap<>(); + resourceLimit.put("jvm", randomDoubleBetween(0.0, 0.80, false)); + return new QueryGroup(name, "random", randomMode(), resourceLimit, Instant.now().getMillis()); + } + + private static QueryGroup.QueryGroupMode randomMode() { + return allowedModes.get(randomIntBetween(0, allowedModes.size() - 1)); + } + + /** + * Parses to a new instance using the provided {@link XContentParser} + * + * @param parser + */ + @Override + protected QueryGroup doParseInstance(XContentParser parser) throws IOException { + return QueryGroup.fromXContent(parser); + } + + /** + * Returns a {@link Writeable.Reader} that can be used to de-serialize the instance + */ + @Override + protected Writeable.Reader instanceReader() { + return QueryGroup::new; + } + + /** + * Creates a random test instance to use in the tests. This method will be + * called multiple times during test execution and should return a different + * random instance each time it is called. + */ + @Override + protected QueryGroup createTestInstance() { + return createRandomResourceLimitGroup(); + } + + public void testNullName() { + assertThrows( + NullPointerException.class, + () -> new QueryGroup(null, "_id", randomMode(), Collections.emptyMap(), Instant.now().getMillis()) + ); + } + + public void testNullId() { + assertThrows( + NullPointerException.class, + () -> new QueryGroup("Dummy", null, randomMode(), Collections.emptyMap(), Instant.now().getMillis()) + ); + } + + public void testNullResourceLimits() { + assertThrows(NullPointerException.class, () -> new QueryGroup("analytics", "_id", randomMode(), null, Instant.now().getMillis())); + } + + public void testEmptyResourceLimits() { + assertThrows( + IllegalArgumentException.class, + () -> new QueryGroup("analytics", "_id", randomMode(), Collections.emptyMap(), Instant.now().getMillis()) + ); + } + + public void testIllegalResourceLimitGroupMode() { + assertThrows( + NullPointerException.class, + () -> new QueryGroup("analytics", "_id", null, Map.of("jvm", (Object) 0.4), Instant.now().getMillis()) + ); + } + + public void testInvalidResourceLimitWhenInvalidSystemResourceNameIsGiven() { + assertThrows( + IllegalArgumentException.class, + () -> new QueryGroup( + "analytics", + "_id", + randomMode(), + Map.of("RequestRate", (Object) randomDoubleBetween(0.01, 0.8, false)), + Instant.now().getMillis() + ) + ); + } + + public void testInvalidResourceLimitWhenInvalidSystemResourceValueIsGiven() { + assertThrows( + IllegalArgumentException.class, + () -> new QueryGroup( + "analytics", + "_id", + randomMode(), + Map.of("RequestRate", (Object) randomDoubleBetween(1.1, 1.8, false)), + Instant.now().getMillis() + ) + ); + } + + public void testValidResourceLimitGroup() { + QueryGroup queryGroup = new QueryGroup( + "analytics", + "_id", + randomMode(), + Map.of("jvm", randomDoubleBetween(0.01, 0.8, false)), + Instant.ofEpochMilli(1717187289).getMillis() + ); + + assertNotNull(queryGroup.getName()); + assertEquals("analytics", queryGroup.getName()); + assertNotNull(queryGroup.getResourceLimits()); + assertFalse(queryGroup.getResourceLimits().isEmpty()); + assertEquals(1, queryGroup.getResourceLimits().size()); + assertTrue(allowedModes.contains(queryGroup.getMode())); + assertEquals(1717187289, queryGroup.getUpdatedAtInMillis()); + } +} diff --git a/server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettingsTests.java b/server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettingsTests.java deleted file mode 100644 index cc31caccc42f2..0000000000000 --- a/server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupServiceSettingsTests.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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.search.resource_limit_group; - -import org.opensearch.common.settings.ClusterSettings; -import org.opensearch.common.settings.Settings; -import org.opensearch.test.OpenSearchTestCase; - -import static org.opensearch.search.resource_limit_group.ResourceLimitGroupServiceSettings.NODE_CANCELLATION_THRESHOLD_SETTING_NAME; -import static org.opensearch.search.resource_limit_group.ResourceLimitGroupServiceSettings.NODE_REJECTION_THRESHOLD_SETTING_NAME; -import static org.opensearch.search.resource_limit_group.ResourceLimitGroupServiceSettings.RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME; - -public class ResourceLimitGroupServiceSettingsTests extends OpenSearchTestCase { - - /** - * Tests the valid value of {@code node.sandbox.max_count} - */ - public void testValidMaxSandboxCountSetting() { - Settings settings = Settings.builder().put(RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME, 100).build(); - ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); - assertEquals(100, resourceLimitGroupServiceSettings.getMaxResourceLimitGroupCount()); - } - - /** - * test the invalid value of {@code node.sandbox.max_count} - */ - public void testInValidMaxSandboxCountSetting() { - Settings settings = Settings.builder().put(RESOURCE_LIMIT_GROUP_COUNT_SETTING_NAME, -100).build(); - ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - assertThrows(IllegalArgumentException.class, () -> new ResourceLimitGroupServiceSettings(settings, cs)); - } - - /** - * Tests the valid value for {@code query_sandbox.node.rejection_threshold} - */ - public void testValidNodeLevelRejectionThreshold() { - Settings settings = Settings.builder().put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.80).build(); - ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); - assertEquals(0.80, resourceLimitGroupServiceSettings.getNodeLevelJvmRejectionThreshold(), 1e-9); - } - - /** - * Tests the invalid value for {@code query_sandbox.node.rejection_threshold} - * When the value is set more than {@literal 0.90} - */ - public void testInValidNodeLevelRejectionThresholdCase1() { - Settings settings = Settings.builder().put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.80).build(); - ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); - assertThrows(IllegalArgumentException.class, () -> resourceLimitGroupServiceSettings.setNodeLevelJvmRejectionThreshold(0.95)); - } - - /** - * Tests the invalid value for {@code query_sandbox.node.rejection_threshold} - * When the value is set more than {@code query_sandbox.node.cancellation_threshold} - */ - public void testInValidNodeLevelRejectionThresholdCase2() { - Settings settings = Settings.builder() - .put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.70) - .put(NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80) - .build(); - ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); - assertThrows(IllegalArgumentException.class, () -> resourceLimitGroupServiceSettings.setNodeLevelJvmRejectionThreshold(0.85)); - } - - /** - * Tests the invalid value for {@code query_sandbox.node.rejection_threshold} - * When the value is set more than {@code query_sandbox.node.cancellation_threshold} accidentally during - * new feature development. This test is to ensure that {@link ResourceLimitGroupServiceSettings} holds the - * invariant {@code nodeLevelRejectionThreshold < nodeLevelCancellationThreshold} - */ - public void testInValidInstantiationOfQuerySandboxServiceSettings() { - Settings settings = Settings.builder() - .put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.80) - .put(NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.70) - .build(); - ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - - assertThrows(IllegalArgumentException.class, () -> new ResourceLimitGroupServiceSettings(settings, cs)); - } - - /** - * Tests the valid value for {@code query_sandbox.node.cancellation_threshold} - */ - public void testValidNodeLevelCancellationThreshold() { - Settings settings = Settings.builder().put(NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80).build(); - ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); - assertEquals(0.80, resourceLimitGroupServiceSettings.getNodeLevelJvmRejectionThreshold(), 1e-9); - } - - /** - * Tests the invalid value for {@code query_sandbox.node.cancellation_threshold} - * When the value is set more than {@literal 0.95} - */ - public void testInValidNodeLevelCancellationThresholdCase1() { - Settings settings = Settings.builder().put(NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80).build(); - ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); - assertThrows(IllegalArgumentException.class, () -> resourceLimitGroupServiceSettings.setNodeLevelJvmRejectionThreshold(0.96)); - } - - /** - * Tests the invalid value for {@code query_sandbox.node.cancellation_threshold} - * When the value is set less than {@code query_sandbox.node.rejection_threshold} - */ - public void testInValidNodeLevelCancellationThresholdCase2() { - Settings settings = Settings.builder() - .put(NODE_REJECTION_THRESHOLD_SETTING_NAME, 0.70) - .put(NODE_CANCELLATION_THRESHOLD_SETTING_NAME, 0.80) - .build(); - ClusterSettings cs = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - ResourceLimitGroupServiceSettings resourceLimitGroupServiceSettings = new ResourceLimitGroupServiceSettings(settings, cs); - assertThrows(IllegalArgumentException.class, () -> resourceLimitGroupServiceSettings.setNodeLevelJvmRejectionThreshold(0.85)); - } - -} diff --git a/server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupTests.java b/server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupTests.java deleted file mode 100644 index 78f95aa35d145..0000000000000 --- a/server/src/test/java/org/opensearch/search/resource_limit_group/ResourceLimitGroupTests.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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.search.resource_limit_group; - -import org.opensearch.cluster.metadata.ResourceLimitGroup; -import org.opensearch.cluster.metadata.ResourceLimitGroup.ResourceLimit; -import org.opensearch.common.io.stream.BytesStreamOutput; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.test.OpenSearchTestCase; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -public class ResourceLimitGroupTests extends OpenSearchTestCase { - - public static final String JVM = "jvm"; - public static final String NAME_ONE = "resource_limit_group_one"; - public static final String UUID_ONE = "AgfUO5Ja9yfsYlONlYi3TQ=="; - public static final String TIMESTAMP_ONE = "2024-04-26 23:02:21"; - public static final String MONITOR = "monitor"; - public static final ResourceLimitGroup resourceLimitGroupOne = new ResourceLimitGroup( - NAME_ONE, - UUID_ONE, - List.of(new ResourceLimitGroup.ResourceLimit("jvm", 0.3)), - MONITOR, - TIMESTAMP_ONE, - TIMESTAMP_ONE - ); - - public static void compareResourceLimits( - List limitsOne, - List limitsTwo - ) { - assertEquals(limitsOne.size(), limitsTwo.size()); - Map resourceLimitMapOne = limitsOne.stream() - .collect(Collectors.toMap(ResourceLimitGroup.ResourceLimit::getResourceName, ResourceLimitGroup.ResourceLimit::getValue)); - Map resourceLimitMapTwo = limitsTwo.stream() - .collect(Collectors.toMap(ResourceLimitGroup.ResourceLimit::getResourceName, ResourceLimitGroup.ResourceLimit::getValue)); - for (String resourceName : resourceLimitMapOne.keySet()) { - assertTrue(resourceLimitMapTwo.containsKey(resourceName)); - assertEquals(resourceLimitMapOne.get(resourceName), resourceLimitMapTwo.get(resourceName)); - } - } - - public static void compareResourceLimitGroups(List listOne, List listTwo) { - assertEquals(listOne.size(), listTwo.size()); - for (ResourceLimitGroup groupOne : listOne) { - String groupOneName = groupOne.getName(); - List groupTwoList = listTwo.stream() - .filter(sb -> sb.getName().equals(groupOneName)) - .collect(Collectors.toList()); - assertEquals(1, groupTwoList.size()); - ResourceLimitGroup groupTwo = groupTwoList.get(0); - assertEquals(groupOne.getName(), groupTwo.getName()); - compareResourceLimits(groupOne.getResourceLimits(), groupTwo.getResourceLimits()); - assertEquals(groupOne.getEnforcement(), groupTwo.getEnforcement()); - } - } - - public void testSerializationResourceLimitGroup() throws IOException { - BytesStreamOutput out = new BytesStreamOutput(); - resourceLimitGroupOne.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - ResourceLimitGroup otherGroup = new ResourceLimitGroup(streamInput); - compareResourceLimitGroups(List.of(resourceLimitGroupOne), List.of(otherGroup)); - } - - public void testInvalidName() { - assertThrows( - IllegalArgumentException.class, - () -> new ResourceLimitGroup("", null, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR, null, null) - ); - assertThrows( - IllegalArgumentException.class, - () -> new ResourceLimitGroup("-test", null, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR, null, null) - ); - assertThrows( - IllegalArgumentException.class, - () -> new ResourceLimitGroup("_test", null, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR, null, null) - ); - assertThrows( - IllegalArgumentException.class, - () -> new ResourceLimitGroup(":test", null, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR, null, null) - ); - assertThrows( - IllegalArgumentException.class, - () -> new ResourceLimitGroup("te*st", null, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR, null, null) - ); - assertThrows( - IllegalArgumentException.class, - () -> new ResourceLimitGroup("test?", null, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR, null, null) - ); - assertThrows( - IllegalArgumentException.class, - () -> new ResourceLimitGroup("Test", null, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), MONITOR, null, null) - ); - } - - public void testInvalidResourceLimitList() { - assertThrows(IllegalArgumentException.class, () -> new ResourceLimitGroup("Test", null, new ArrayList<>(), MONITOR, null, null)); - assertThrows( - IllegalArgumentException.class, - () -> new ResourceLimitGroup( - "Test", - null, - List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3), new ResourceLimitGroup.ResourceLimit(JVM, 0.4)), - MONITOR, - null, - null - ) - ); - } - - public void testInvalidEnforcement() { - assertThrows( - IllegalArgumentException.class, - () -> new ResourceLimitGroup(NAME_ONE, null, List.of(new ResourceLimitGroup.ResourceLimit(JVM, 0.3)), "random", null, null) - ); - } - - public void testInvalidResourceLimit() { - assertThrows(IllegalArgumentException.class, () -> new ResourceLimit(JVM, -3.0)); - assertThrows(IllegalArgumentException.class, () -> new ResourceLimit(JVM, 12.0)); - assertThrows(IllegalArgumentException.class, () -> new ResourceLimit(JVM, 0.345)); - assertThrows(IllegalArgumentException.class, () -> new ResourceLimit("cpu", 0.3)); - } -} From d490c15ec50e62d3bc2af507721b71985e2d99ed Mon Sep 17 00:00:00 2001 From: Ruirui Zhang Date: Wed, 19 Jun 2024 11:40:47 -0700 Subject: [PATCH 13/15] modify based on commit Signed-off-by: Ruirui Zhang --- CHANGELOG-3.0.md | 2 +- .../build.gradle | 4 +- .../plugin/wlm}/CreateQueryGroupAction.java | 4 +- .../plugin/wlm}/CreateQueryGroupRequest.java | 13 +- .../plugin/wlm}/CreateQueryGroupResponse.java | 17 +- .../plugin/wlm}/DeleteQueryGroupAction.java | 6 +- .../plugin/wlm}/DeleteQueryGroupRequest.java | 2 +- .../plugin/wlm}/DeleteQueryGroupResponse.java | 15 +- .../plugin/wlm}/GetQueryGroupAction.java | 4 +- .../plugin/wlm}/GetQueryGroupRequest.java | 2 +- .../plugin/wlm}/GetQueryGroupResponse.java | 15 +- .../wlm}/TransportCreateQueryGroupAction.java | 4 +- .../wlm}/TransportDeleteQueryGroupAction.java | 4 +- .../wlm}/TransportGetQueryGroupAction.java | 4 +- .../wlm}/TransportUpdateQueryGroupAction.java | 4 +- .../plugin/wlm}/UpdateQueryGroupAction.java | 4 +- .../plugin/wlm}/UpdateQueryGroupRequest.java | 33 ++-- .../plugin/wlm}/UpdateQueryGroupResponse.java | 14 +- .../plugin/wlm/WorkloadManagementPlugin.java} | 18 +- .../wlm/WorkloadManagementPluginModule.java} | 14 +- .../opensearch/plugin/wlm}/package-info.java | 2 +- .../wlm}/rest/RestCreateQueryGroupAction.java | 8 +- .../wlm}/rest/RestDeleteQueryGroupAction.java | 8 +- .../wlm}/rest/RestGetQueryGroupAction.java | 8 +- .../wlm}/rest/RestUpdateQueryGroupAction.java | 8 +- .../plugin/wlm}/rest/package-info.java | 2 +- .../plugin/wlm}/service/Persistable.java | 12 +- .../service/QueryGroupPersistenceService.java | 32 +--- .../plugin/wlm}/service/package-info.java | 2 +- .../wlm}/CreateQueryGroupRequestTests.java | 14 +- .../wlm}/CreateQueryGroupResponseTests.java | 5 +- .../wlm}/DeleteQueryGroupRequestTests.java | 2 +- .../wlm}/DeleteQueryGroupResponseTests.java | 15 +- .../wlm}/GetQueryGroupRequestTests.java | 2 +- .../wlm}/GetQueryGroupResponseTests.java | 9 +- .../plugin/wlm}/QueryGroupTestUtils.java | 4 +- .../wlm}/UpdateQueryGroupRequestTests.java | 12 +- .../wlm}/UpdateQueryGroupResponseTests.java | 5 +- .../QueryGroupPersistenceServiceTests.java | 34 ++-- .../cluster/metadata/QueryGroup.java | 22 +-- .../search/query_group/QueryGroupPruner.java | 20 -- .../search/query_group/QueryGroupService.java | 90 --------- .../QueryGroupRequestCanceller.java | 19 -- .../cancellation/package-info.java | 12 -- .../query_group/module/QueryGroupModule.java | 33 ---- .../query_group/module/package-info.java | 13 -- .../QueryGroupResourceUsageTracker.java | 19 -- ...QueryGroupResourceUsageTrackerService.java | 171 ------------------ .../query_group/tracker/package-info.java | 12 -- .../metadata/QueryGroupMetadataTests.java | 8 +- .../cluster/metadata/QueryGroupTests.java | 8 +- 51 files changed, 201 insertions(+), 593 deletions(-) rename plugins/{query-group => workload-management}/build.gradle (73%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/CreateQueryGroupAction.java (92%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/CreateQueryGroupRequest.java (96%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/CreateQueryGroupResponse.java (85%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/DeleteQueryGroupAction.java (92%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/DeleteQueryGroupRequest.java (98%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/DeleteQueryGroupResponse.java (90%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/GetQueryGroupAction.java (93%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/GetQueryGroupRequest.java (98%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/GetQueryGroupResponse.java (91%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/TransportCreateQueryGroupAction.java (96%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/TransportDeleteQueryGroupAction.java (95%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/TransportGetQueryGroupAction.java (95%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/TransportUpdateQueryGroupAction.java (95%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/UpdateQueryGroupAction.java (92%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/UpdateQueryGroupRequest.java (88%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/UpdateQueryGroupResponse.java (90%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg/QueryGroupPlugin.java => workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPlugin.java} (81%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg/QueryGroupPluginModule.java => workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPluginModule.java} (59%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/package-info.java (87%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/rest/RestCreateQueryGroupAction.java (93%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/rest/RestDeleteQueryGroupAction.java (91%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/rest/RestGetQueryGroupAction.java (91%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/rest/RestUpdateQueryGroupAction.java (93%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/rest/package-info.java (87%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/service/Persistable.java (78%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/service/QueryGroupPersistenceService.java (94%) rename plugins/{query-group/src/main/java/org/opensearch/plugin/qg => workload-management/src/main/java/org/opensearch/plugin/wlm}/service/package-info.java (86%) rename plugins/{query-group/src/test/java/org/opensearch/plugin/qg => workload-management/src/test/java/org/opensearch/plugin/wlm}/CreateQueryGroupRequestTests.java (88%) rename plugins/{query-group/src/test/java/org/opensearch/plugin/qg => workload-management/src/test/java/org/opensearch/plugin/wlm}/CreateQueryGroupResponseTests.java (89%) rename plugins/{query-group/src/test/java/org/opensearch/plugin/qg => workload-management/src/test/java/org/opensearch/plugin/wlm}/DeleteQueryGroupRequestTests.java (97%) rename plugins/{query-group/src/test/java/org/opensearch/plugin/qg => workload-management/src/test/java/org/opensearch/plugin/wlm}/DeleteQueryGroupResponseTests.java (85%) rename plugins/{query-group/src/test/java/org/opensearch/plugin/qg => workload-management/src/test/java/org/opensearch/plugin/wlm}/GetQueryGroupRequestTests.java (97%) rename plugins/{query-group/src/test/java/org/opensearch/plugin/qg => workload-management/src/test/java/org/opensearch/plugin/wlm}/GetQueryGroupResponseTests.java (93%) rename plugins/{query-group/src/test/java/org/opensearch/plugin/qg => workload-management/src/test/java/org/opensearch/plugin/wlm}/QueryGroupTestUtils.java (98%) rename plugins/{query-group/src/test/java/org/opensearch/plugin/qg => workload-management/src/test/java/org/opensearch/plugin/wlm}/UpdateQueryGroupRequestTests.java (92%) rename plugins/{query-group/src/test/java/org/opensearch/plugin/qg => workload-management/src/test/java/org/opensearch/plugin/wlm}/UpdateQueryGroupResponseTests.java (89%) rename plugins/{query-group/src/test/java/org/opensearch/plugin/qg => workload-management/src/test/java/org/opensearch/plugin/wlm}/service/QueryGroupPersistenceServiceTests.java (89%) delete mode 100644 server/src/main/java/org/opensearch/search/query_group/QueryGroupPruner.java delete mode 100644 server/src/main/java/org/opensearch/search/query_group/QueryGroupService.java delete mode 100644 server/src/main/java/org/opensearch/search/query_group/cancellation/QueryGroupRequestCanceller.java delete mode 100644 server/src/main/java/org/opensearch/search/query_group/cancellation/package-info.java delete mode 100644 server/src/main/java/org/opensearch/search/query_group/module/QueryGroupModule.java delete mode 100644 server/src/main/java/org/opensearch/search/query_group/module/package-info.java delete mode 100644 server/src/main/java/org/opensearch/search/query_group/tracker/QueryGroupResourceUsageTracker.java delete mode 100644 server/src/main/java/org/opensearch/search/query_group/tracker/QueryGroupResourceUsageTrackerService.java delete mode 100644 server/src/main/java/org/opensearch/search/query_group/tracker/package-info.java diff --git a/CHANGELOG-3.0.md b/CHANGELOG-3.0.md index 1f5942af52742..e6d89b2930ff8 100644 --- a/CHANGELOG-3.0.md +++ b/CHANGELOG-3.0.md @@ -24,7 +24,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Add task completion count in search backpressure stats API ([#10028](https://github.com/opensearch-project/OpenSearch/pull/10028/)) - Deprecate CamelCase `PathHierarchy` tokenizer name in favor to lowercase `path_hierarchy` ([#10894](https://github.com/opensearch-project/OpenSearch/pull/10894)) - Breaking change: Do not request "search_pipelines" metrics by default in NodesInfoRequest ([#12497](https://github.com/opensearch-project/OpenSearch/pull/12497)) -- [Query Sandbox] Add Resource Limit Group CRUD APIs ([#13315](https://github.com/opensearch-project/OpenSearch/pull/13315)) +- [QueryGroup] Add QueryGroup CRUD APIs ([#13315](https://github.com/opensearch-project/OpenSearch/pull/13315)) ### Deprecated diff --git a/plugins/query-group/build.gradle b/plugins/workload-management/build.gradle similarity index 73% rename from plugins/query-group/build.gradle rename to plugins/workload-management/build.gradle index a90f895966786..e91ef90005c74 100644 --- a/plugins/query-group/build.gradle +++ b/plugins/workload-management/build.gradle @@ -10,8 +10,8 @@ */ opensearchplugin { - description 'OpenSearch QueryGroup Plugin.' - classname 'org.opensearch.plugin.qg.QueryGroupPlugin' + description 'OpenSearch Workload Management Plugin.' + classname 'org.opensearch.plugin.wlm.WorkloadManagementPlugin' } dependencies { diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/CreateQueryGroupAction.java similarity index 92% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupAction.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/CreateQueryGroupAction.java index fc0c143a8f218..068f7822fd437 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupAction.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/CreateQueryGroupAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.action.ActionType; @@ -25,7 +25,7 @@ public class CreateQueryGroupAction extends ActionType /** * Name for CreateQueryGroupAction */ - public static final String NAME = "cluster:admin/opensearch/query_group/_create"; + public static final String NAME = "cluster:admin/opensearch/query_group/wlm/_create"; /** * Default constructor diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupRequest.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/CreateQueryGroupRequest.java similarity index 96% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupRequest.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/CreateQueryGroupRequest.java index 33a17593cf625..675e471e38581 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupRequest.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/CreateQueryGroupRequest.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.action.ActionRequest; import org.opensearch.action.ActionRequestValidationException; @@ -123,6 +123,7 @@ private void verifyCreateQueryGroupRequest( Objects.requireNonNull(updatedAtInMillis, "QueryGroup.updatedAtInMillis can't be null"); validateName(name); + validateMode(mode); validateResourceLimits(resourceLimits); validateUpdatedAtInMillis(updatedAtInMillis); } @@ -146,6 +147,16 @@ public static void validateName(String name) { } } + /** + * Verification for CreateQueryGroupRequest.mode + * @param mode - mode to be verified + */ + public static void validateMode(QueryGroupMode mode) { + if (!mode.getName().equals("monitor")) { + throw new IllegalArgumentException("QueryGroup.mode must be monitor"); + } + } + /** * Verification for CreateQueryGroupRequest.resourceLimits * @param resourceLimits - resourceLimits to be verified diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupResponse.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/CreateQueryGroupResponse.java similarity index 85% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupResponse.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/CreateQueryGroupResponse.java index b431706960e42..5e70084f0f0e1 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/CreateQueryGroupResponse.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/CreateQueryGroupResponse.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.core.action.ActionResponse; @@ -30,17 +30,12 @@ public class CreateQueryGroupResponse extends ActionResponse implements ToXConte /** * Constructor for CreateQueryGroupResponse + * @param queryGroup - The QueryGroup to be created + * @param restStatus - The resStatus for the response */ - public CreateQueryGroupResponse() { - this.queryGroup = null; - } - - /** - * Constructor for CreateQueryGroupResponse - * @param queryGroup - The resource limit group to be created - */ - public CreateQueryGroupResponse(final QueryGroup queryGroup) { + public CreateQueryGroupResponse(final QueryGroup queryGroup, RestStatus restStatus) { this.queryGroup = queryGroup; + this.restStatus = restStatus; } /** @@ -49,11 +44,13 @@ public CreateQueryGroupResponse(final QueryGroup queryGroup) { */ public CreateQueryGroupResponse(StreamInput in) throws IOException { queryGroup = new QueryGroup(in); + restStatus = RestStatus.readFrom(in); } @Override public void writeTo(StreamOutput out) throws IOException { queryGroup.writeTo(out); + RestStatus.writeTo(out, restStatus); } @Override diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupAction.java similarity index 92% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupAction.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupAction.java index 2d5acc49c7cf3..207f8ae8ee5c1 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupAction.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.action.ActionType; @@ -18,7 +18,7 @@ public class DeleteQueryGroupAction extends ActionType { /** - /** + /** * An instance of DeleteQueryGroupAction */ public static final DeleteQueryGroupAction INSTANCE = new DeleteQueryGroupAction(); @@ -26,7 +26,7 @@ public class DeleteQueryGroupAction extends ActionType /** * Name for DeleteQueryGroupAction */ - public static final String NAME = "cluster:admin/opensearch/query_group/_delete"; + public static final String NAME = "cluster:admin/opensearch/query_group/wlm/_delete"; /** * Default constructor diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupRequest.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupRequest.java similarity index 98% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupRequest.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupRequest.java index eb35bb3a2c80e..3d05a33bc1808 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupRequest.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupRequest.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.action.ActionRequest; import org.opensearch.action.ActionRequestValidationException; diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupResponse.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupResponse.java similarity index 90% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupResponse.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupResponse.java index 37e97a490908e..0c1258df338a9 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/DeleteQueryGroupResponse.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupResponse.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.core.action.ActionResponse; @@ -29,19 +29,14 @@ public class DeleteQueryGroupResponse extends ActionResponse implements ToXConte private final List queryGroups; private RestStatus restStatus; - /** - * Constructor for DeleteQueryGroupResponse - */ - public DeleteQueryGroupResponse() { - this.queryGroups = null; - } - /** * Constructor for DeleteQueryGroupResponse * @param queryGroups - The QueryGroup list to be fetched + * @param restStatus - The rest status for this response */ - public DeleteQueryGroupResponse(final List queryGroups) { + public DeleteQueryGroupResponse(final List queryGroups, RestStatus restStatus) { this.queryGroups = queryGroups; + this.restStatus = restStatus; } /** @@ -50,11 +45,13 @@ public DeleteQueryGroupResponse(final List queryGroups) { */ public DeleteQueryGroupResponse(StreamInput in) throws IOException { this.queryGroups = in.readList(QueryGroup::new); + this.restStatus = RestStatus.readFrom(in); } @Override public void writeTo(StreamOutput out) throws IOException { out.writeList(queryGroups); + RestStatus.writeTo(out, restStatus); } @Override diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupAction.java similarity index 93% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupAction.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupAction.java index 8da51a4f13be7..1c507ded8337a 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupAction.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.action.ActionType; @@ -26,7 +26,7 @@ public class GetQueryGroupAction extends ActionType { /** * Name for GetQueryGroupAction */ - public static final String NAME = "cluster:admin/opensearch/query_group/_get"; + public static final String NAME = "cluster:admin/opensearch/query_group/wlm/_get"; /** * Default constructor diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupRequest.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupRequest.java similarity index 98% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupRequest.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupRequest.java index f49cd3b3a9922..62df9c9ac2fbb 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupRequest.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupRequest.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.action.ActionRequest; import org.opensearch.action.ActionRequestValidationException; diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupResponse.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupResponse.java similarity index 91% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupResponse.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupResponse.java index 452da52d9861f..e68a1a7f58184 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/GetQueryGroupResponse.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupResponse.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.core.action.ActionResponse; @@ -29,19 +29,14 @@ public class GetQueryGroupResponse extends ActionResponse implements ToXContent, private final List queryGroups; private RestStatus restStatus; - /** - * Constructor for GetQueryGroupResponse - */ - public GetQueryGroupResponse() { - this.queryGroups = null; - } - /** * Constructor for GetQueryGroupResponse * @param queryGroups - The QueryGroup list to be fetched + * @param restStatus - The rest status of the request */ - public GetQueryGroupResponse(final List queryGroups) { + public GetQueryGroupResponse(final List queryGroups, RestStatus restStatus) { this.queryGroups = queryGroups; + this.restStatus = restStatus; } /** @@ -50,11 +45,13 @@ public GetQueryGroupResponse(final List queryGroups) { */ public GetQueryGroupResponse(StreamInput in) throws IOException { this.queryGroups = in.readList(QueryGroup::new); + restStatus = RestStatus.readFrom(in); } @Override public void writeTo(StreamOutput out) throws IOException { out.writeList(queryGroups); + RestStatus.writeTo(out, restStatus); } @Override diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportCreateQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportCreateQueryGroupAction.java similarity index 96% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportCreateQueryGroupAction.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportCreateQueryGroupAction.java index a146dcbaa671e..1454ad6a0865c 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportCreateQueryGroupAction.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportCreateQueryGroupAction.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.common.inject.Inject; import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.qg.service.Persistable; +import org.opensearch.plugin.wlm.service.Persistable; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportService; diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportDeleteQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportDeleteQueryGroupAction.java similarity index 95% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportDeleteQueryGroupAction.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportDeleteQueryGroupAction.java index c0237fd832c98..41bb84a7aea7f 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportDeleteQueryGroupAction.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportDeleteQueryGroupAction.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.common.inject.Inject; import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.qg.service.Persistable; +import org.opensearch.plugin.wlm.service.Persistable; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportService; diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportGetQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportGetQueryGroupAction.java similarity index 95% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportGetQueryGroupAction.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportGetQueryGroupAction.java index 11725891b5980..8c353faddc122 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportGetQueryGroupAction.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportGetQueryGroupAction.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.common.inject.Inject; import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.qg.service.Persistable; +import org.opensearch.plugin.wlm.service.Persistable; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportService; diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportUpdateQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportUpdateQueryGroupAction.java similarity index 95% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportUpdateQueryGroupAction.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportUpdateQueryGroupAction.java index 5cc0bd01ac418..0e560718ced62 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/TransportUpdateQueryGroupAction.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportUpdateQueryGroupAction.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.common.inject.Inject; import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.qg.service.Persistable; +import org.opensearch.plugin.wlm.service.Persistable; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportService; diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupAction.java similarity index 92% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupAction.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupAction.java index f68e9b52ea160..b9f00e1ba70a8 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupAction.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.action.ActionType; @@ -25,7 +25,7 @@ public class UpdateQueryGroupAction extends ActionType /** * Name for UpdateQueryGroupAction */ - public static final String NAME = "cluster:admin/opensearch/query_group/_update"; + public static final String NAME = "cluster:admin/opensearch/query_group/wlm/_update"; /** * Default constructor diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupRequest.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupRequest.java similarity index 88% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupRequest.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupRequest.java index e447f2054b4d5..c29cdc524e899 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupRequest.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupRequest.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.action.ActionRequest; import org.opensearch.action.ActionRequestValidationException; @@ -25,8 +25,9 @@ import java.util.Objects; import static org.opensearch.cluster.metadata.QueryGroup.ALLOWED_RESOURCES; -import static org.opensearch.plugin.qg.CreateQueryGroupRequest.validateName; -import static org.opensearch.plugin.qg.CreateQueryGroupRequest.validateUpdatedAtInMillis; +import static org.opensearch.plugin.wlm.CreateQueryGroupRequest.validateName; +import static org.opensearch.plugin.wlm.CreateQueryGroupRequest.validateMode; +import static org.opensearch.plugin.wlm.CreateQueryGroupRequest.validateUpdatedAtInMillis; /** * A request for update QueryGroup @@ -46,14 +47,14 @@ public UpdateQueryGroupRequest() {} /** * Constructor for UpdateQueryGroupRequest - * @param resourceLimitGroup - A {@link QueryGroup} object + * @param queryGroup - A {@link QueryGroup} object */ - public UpdateQueryGroupRequest(QueryGroup resourceLimitGroup) { - this.name = resourceLimitGroup.getName(); - this.mode = resourceLimitGroup.getMode(); - this.resourceLimits = resourceLimitGroup.getResourceLimits(); - this.updatedAtInMillis = resourceLimitGroup.getUpdatedAtInMillis(); - verifyUpdateQueryGroupRequest(name, resourceLimits, updatedAtInMillis); + public UpdateQueryGroupRequest(QueryGroup queryGroup) { + this.name = queryGroup.getName(); + this.mode = queryGroup.getMode(); + this.resourceLimits = queryGroup.getResourceLimits(); + this.updatedAtInMillis = queryGroup.getUpdatedAtInMillis(); + verifyUpdateQueryGroupRequest(name, mode, resourceLimits, updatedAtInMillis); } /** @@ -68,7 +69,7 @@ public UpdateQueryGroupRequest(String name, QueryGroupMode mode, Map resourceLimits, long updatedAtInMillis) { + private void verifyUpdateQueryGroupRequest( + String name, + QueryGroupMode mode, + Map resourceLimits, + long updatedAtInMillis + ) { Objects.requireNonNull(name, "QueryGroup.name can't be null"); Objects.requireNonNull(resourceLimits, "QueryGroup.resourceLimits can't be null"); Objects.requireNonNull(updatedAtInMillis, "QueryGroup.updatedAtInMillis can't be null"); validateName(name); + validateMode(mode); validateResourceLimits(resourceLimits); validateUpdatedAtInMillis(updatedAtInMillis); } diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupResponse.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupResponse.java similarity index 90% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupResponse.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupResponse.java index 07387b9756f80..761a5cc187147 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/UpdateQueryGroupResponse.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupResponse.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.core.action.ActionResponse; @@ -28,19 +28,13 @@ public class UpdateQueryGroupResponse extends ActionResponse implements ToXConte private final QueryGroup queryGroup; private RestStatus restStatus; - /** - * Constructor for UpdateQueryGroupResponse - */ - public UpdateQueryGroupResponse() { - this.queryGroup = null; - } - /** * Constructor for UpdateQueryGroupResponse * @param queryGroup - The QueryGroup to be updated */ - public UpdateQueryGroupResponse(final QueryGroup queryGroup) { + public UpdateQueryGroupResponse(final QueryGroup queryGroup, RestStatus restStatus) { this.queryGroup = queryGroup; + this.restStatus = restStatus; } /** @@ -49,11 +43,13 @@ public UpdateQueryGroupResponse(final QueryGroup queryGroup) { */ public UpdateQueryGroupResponse(StreamInput in) throws IOException { queryGroup = new QueryGroup(in); + restStatus = RestStatus.readFrom(in); } @Override public void writeTo(StreamOutput out) throws IOException { queryGroup.writeTo(out); + RestStatus.writeTo(out, restStatus); } @Override diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/QueryGroupPlugin.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPlugin.java similarity index 81% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/QueryGroupPlugin.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPlugin.java index 78295b26da93a..e08027a741ac5 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/QueryGroupPlugin.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPlugin.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.action.ActionRequest; import org.opensearch.cluster.metadata.IndexNameExpressionResolver; @@ -17,10 +17,10 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.settings.SettingsFilter; import org.opensearch.core.action.ActionResponse; -import org.opensearch.plugin.qg.rest.RestCreateQueryGroupAction; -import org.opensearch.plugin.qg.rest.RestDeleteQueryGroupAction; -import org.opensearch.plugin.qg.rest.RestGetQueryGroupAction; -import org.opensearch.plugin.qg.rest.RestUpdateQueryGroupAction; +import org.opensearch.plugin.wlm.rest.RestCreateQueryGroupAction; +import org.opensearch.plugin.wlm.rest.RestDeleteQueryGroupAction; +import org.opensearch.plugin.wlm.rest.RestGetQueryGroupAction; +import org.opensearch.plugin.wlm.rest.RestUpdateQueryGroupAction; import org.opensearch.plugins.ActionPlugin; import org.opensearch.plugins.Plugin; import org.opensearch.rest.RestController; @@ -31,14 +31,14 @@ import java.util.function.Supplier; /** - * Plugin class for QueryGroup + * Plugin class for WorkloadManagement */ -public class QueryGroupPlugin extends Plugin implements ActionPlugin { +public class WorkloadManagementPlugin extends Plugin implements ActionPlugin { /** * Default constructor */ - public QueryGroupPlugin() {} + public WorkloadManagementPlugin() {} @Override public List> getActions() { @@ -70,6 +70,6 @@ public List getRestHandlers( @Override public Collection createGuiceModules() { - return List.of(new QueryGroupPluginModule()); + return List.of(new WorkloadManagementPluginModule()); } } diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/QueryGroupPluginModule.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPluginModule.java similarity index 59% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/QueryGroupPluginModule.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPluginModule.java index 379ca9372fe60..58208af293f14 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/QueryGroupPluginModule.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPluginModule.java @@ -6,23 +6,23 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.common.inject.AbstractModule; import org.opensearch.common.inject.TypeLiteral; -import org.opensearch.plugin.qg.service.Persistable; -import org.opensearch.plugin.qg.service.QueryGroupPersistenceService; +import org.opensearch.plugin.wlm.service.Persistable; +import org.opensearch.plugin.wlm.service.QueryGroupPersistenceService; /** - * Guice Module to manage QueryGroup related objects + * Guice Module to manage WorkloadManagement related objects */ -public class QueryGroupPluginModule extends AbstractModule { +public class WorkloadManagementPluginModule extends AbstractModule { /** - * Constructor for QueryGroupPluginModule + * Constructor for WorkloadManagementPluginModule */ - public QueryGroupPluginModule() {} + public WorkloadManagementPluginModule() {} @Override protected void configure() { diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/package-info.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/package-info.java similarity index 87% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/package-info.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/package-info.java index 11b69d6964ffc..73027f70bb294 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/package-info.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/package-info.java @@ -9,4 +9,4 @@ /** * Base Package of CRUD API of QueryGroup */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestCreateQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestCreateQueryGroupAction.java similarity index 93% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestCreateQueryGroupAction.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestCreateQueryGroupAction.java index 5256eded7861e..48de27d4fc02a 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestCreateQueryGroupAction.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestCreateQueryGroupAction.java @@ -6,15 +6,15 @@ * compatible open source license. */ -package org.opensearch.plugin.qg.rest; +package org.opensearch.plugin.wlm.rest; import org.opensearch.client.node.NodeClient; import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; import org.opensearch.core.xcontent.XContentParser; -import org.opensearch.plugin.qg.CreateQueryGroupAction; -import org.opensearch.plugin.qg.CreateQueryGroupRequest; -import org.opensearch.plugin.qg.CreateQueryGroupResponse; +import org.opensearch.plugin.wlm.CreateQueryGroupAction; +import org.opensearch.plugin.wlm.CreateQueryGroupRequest; +import org.opensearch.plugin.wlm.CreateQueryGroupResponse; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.RestChannel; diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestDeleteQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestDeleteQueryGroupAction.java similarity index 91% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestDeleteQueryGroupAction.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestDeleteQueryGroupAction.java index a5a775e120714..e577defdfea13 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestDeleteQueryGroupAction.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestDeleteQueryGroupAction.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.plugin.qg.rest; +package org.opensearch.plugin.wlm.rest; import org.opensearch.client.node.NodeClient; import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.plugin.qg.DeleteQueryGroupAction; -import org.opensearch.plugin.qg.DeleteQueryGroupRequest; -import org.opensearch.plugin.qg.DeleteQueryGroupResponse; +import org.opensearch.plugin.wlm.DeleteQueryGroupAction; +import org.opensearch.plugin.wlm.DeleteQueryGroupRequest; +import org.opensearch.plugin.wlm.DeleteQueryGroupResponse; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.RestChannel; diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestGetQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestGetQueryGroupAction.java similarity index 91% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestGetQueryGroupAction.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestGetQueryGroupAction.java index 9a216c07605c3..1e1b3f4eff72e 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestGetQueryGroupAction.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestGetQueryGroupAction.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.plugin.qg.rest; +package org.opensearch.plugin.wlm.rest; import org.opensearch.client.node.NodeClient; import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.plugin.qg.GetQueryGroupAction; -import org.opensearch.plugin.qg.GetQueryGroupRequest; -import org.opensearch.plugin.qg.GetQueryGroupResponse; +import org.opensearch.plugin.wlm.GetQueryGroupAction; +import org.opensearch.plugin.wlm.GetQueryGroupRequest; +import org.opensearch.plugin.wlm.GetQueryGroupResponse; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.RestChannel; diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestUpdateQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestUpdateQueryGroupAction.java similarity index 93% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestUpdateQueryGroupAction.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestUpdateQueryGroupAction.java index 7cec01987e875..a369f9fe9edea 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/RestUpdateQueryGroupAction.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestUpdateQueryGroupAction.java @@ -6,15 +6,15 @@ * compatible open source license. */ -package org.opensearch.plugin.qg.rest; +package org.opensearch.plugin.wlm.rest; import org.opensearch.client.node.NodeClient; import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; import org.opensearch.core.xcontent.XContentParser; -import org.opensearch.plugin.qg.UpdateQueryGroupAction; -import org.opensearch.plugin.qg.UpdateQueryGroupRequest; -import org.opensearch.plugin.qg.UpdateQueryGroupResponse; +import org.opensearch.plugin.wlm.UpdateQueryGroupAction; +import org.opensearch.plugin.wlm.UpdateQueryGroupRequest; +import org.opensearch.plugin.wlm.UpdateQueryGroupResponse; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.RestChannel; diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/package-info.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/package-info.java similarity index 87% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/package-info.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/package-info.java index 630b03b1d82f1..6d1853f04ce58 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/rest/package-info.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/package-info.java @@ -9,4 +9,4 @@ /** * Package for the rest classes for QueryGroup CRUD operations */ -package org.opensearch.plugin.qg.rest; +package org.opensearch.plugin.wlm.rest; diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/Persistable.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/Persistable.java similarity index 78% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/Persistable.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/Persistable.java index b973190f5122c..dc2cb5de2f9cd 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/Persistable.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/Persistable.java @@ -6,14 +6,14 @@ * compatible open source license. */ -package org.opensearch.plugin.qg.service; +package org.opensearch.plugin.wlm.service; import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.qg.CreateQueryGroupResponse; -import org.opensearch.plugin.qg.DeleteQueryGroupResponse; -import org.opensearch.plugin.qg.GetQueryGroupResponse; -import org.opensearch.plugin.qg.UpdateQueryGroupRequest; -import org.opensearch.plugin.qg.UpdateQueryGroupResponse; +import org.opensearch.plugin.wlm.CreateQueryGroupResponse; +import org.opensearch.plugin.wlm.DeleteQueryGroupResponse; +import org.opensearch.plugin.wlm.GetQueryGroupResponse; +import org.opensearch.plugin.wlm.UpdateQueryGroupRequest; +import org.opensearch.plugin.wlm.UpdateQueryGroupResponse; /** * This interface defines the key APIs for implementing QueruGroup persistence diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/QueryGroupPersistenceService.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceService.java similarity index 94% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/QueryGroupPersistenceService.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceService.java index 776721cc4fe77..f88aad0a8f8f5 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/QueryGroupPersistenceService.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceService.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg.service; +package org.opensearch.plugin.wlm.service; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -23,11 +23,11 @@ import org.opensearch.common.settings.Settings; import org.opensearch.core.action.ActionListener; import org.opensearch.core.rest.RestStatus; -import org.opensearch.plugin.qg.CreateQueryGroupResponse; -import org.opensearch.plugin.qg.DeleteQueryGroupResponse; -import org.opensearch.plugin.qg.GetQueryGroupResponse; -import org.opensearch.plugin.qg.UpdateQueryGroupRequest; -import org.opensearch.plugin.qg.UpdateQueryGroupResponse; +import org.opensearch.plugin.wlm.CreateQueryGroupResponse; +import org.opensearch.plugin.wlm.DeleteQueryGroupResponse; +import org.opensearch.plugin.wlm.GetQueryGroupResponse; +import org.opensearch.plugin.wlm.UpdateQueryGroupRequest; +import org.opensearch.plugin.wlm.UpdateQueryGroupResponse; import java.util.ArrayList; import java.util.HashMap; @@ -110,13 +110,10 @@ public void get(String name, ActionListener listener) { if (resultGroups.isEmpty() && name != null && !name.isEmpty()) { logger.warn("No QueryGroup exists with the provided name: {}", name); Exception e = new RuntimeException("No QueryGroup exists with the provided name: " + name); - GetQueryGroupResponse response = new GetQueryGroupResponse(); - response.setRestStatus(RestStatus.NOT_FOUND); listener.onFailure(e); return; } - GetQueryGroupResponse response = new GetQueryGroupResponse(resultGroups); - response.setRestStatus(RestStatus.OK); + GetQueryGroupResponse response = new GetQueryGroupResponse(resultGroups, RestStatus.OK); listener.onResponse(response); } @@ -146,8 +143,6 @@ public void onFailure(String source, Exception e) { restoreInflightValues(queryGroup.getResourceLimits()); inflightCreateQueryGroupRequestCount.decrementAndGet(); logger.warn("failed to save QueryGroup object due to error: {}, for source: {}", e.getMessage(), source); - CreateQueryGroupResponse response = new CreateQueryGroupResponse(); - response.setRestStatus(RestStatus.FAILED_DEPENDENCY); listener.onFailure(e); } @@ -155,8 +150,7 @@ public void onFailure(String source, Exception e) { public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { restoreInflightValues(queryGroup.getResourceLimits()); inflightCreateQueryGroupRequestCount.decrementAndGet(); - CreateQueryGroupResponse response = new CreateQueryGroupResponse(queryGroup); - response.setRestStatus(RestStatus.OK); + CreateQueryGroupResponse response = new CreateQueryGroupResponse(queryGroup, RestStatus.OK); listener.onResponse(response); } }); @@ -263,8 +257,6 @@ public ThrottlingKey getClusterManagerThrottlingKey() { public void onFailure(String source, Exception e) { restoreInflightValues(toUpdateGroup.getResourceLimits()); logger.warn("Failed to update QueryGroup due to error: {}, for source: {}", e.getMessage(), source); - UpdateQueryGroupResponse response = new UpdateQueryGroupResponse(); - response.setRestStatus(RestStatus.FAILED_DEPENDENCY); listener.onFailure(e); } @@ -279,8 +271,7 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS .findFirst(); assert findUpdatedGroup.isPresent(); QueryGroup updatedGroup = findUpdatedGroup.get(); - UpdateQueryGroupResponse response = new UpdateQueryGroupResponse(updatedGroup); - response.setRestStatus(RestStatus.OK); + UpdateQueryGroupResponse response = new UpdateQueryGroupResponse(updatedGroup, RestStatus.OK); listener.onResponse(response); } }); @@ -362,8 +353,6 @@ public ThrottlingKey getClusterManagerThrottlingKey() { @Override public void onFailure(String source, Exception e) { logger.warn("Failed to delete QueryGroup due to error: {}, for source: {}", e.getMessage(), source); - DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(); - response.setRestStatus(RestStatus.NOT_FOUND); listener.onFailure(e); } @@ -377,8 +366,7 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS deletedGroups.add(group); } } - DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(deletedGroups); - response.setRestStatus(RestStatus.OK); + DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(deletedGroups, RestStatus.OK); listener.onResponse(response); } }); diff --git a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/package-info.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/package-info.java similarity index 86% rename from plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/package-info.java rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/package-info.java index 3bb6e35d7b78e..ecfc94568888a 100644 --- a/plugins/query-group/src/main/java/org/opensearch/plugin/qg/service/package-info.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/package-info.java @@ -9,4 +9,4 @@ /** * Package for the service classes for QueryGroup CRUD operations */ -package org.opensearch.plugin.qg.service; +package org.opensearch.plugin.wlm.service; diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/CreateQueryGroupRequestTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/CreateQueryGroupRequestTests.java similarity index 88% rename from plugins/query-group/src/test/java/org/opensearch/plugin/qg/CreateQueryGroupRequestTests.java rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/CreateQueryGroupRequestTests.java index d45a49b0bc4bc..09fce8d911d96 100644 --- a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/CreateQueryGroupRequestTests.java +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/CreateQueryGroupRequestTests.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.cluster.metadata.QueryGroup.QueryGroupMode; import org.opensearch.common.io.stream.BytesStreamOutput; @@ -17,12 +17,12 @@ import java.util.HashMap; import java.util.Map; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.MONITOR; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.NAME_ONE; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.TIMESTAMP_ONE; -import static org.opensearch.plugin.qg.QueryGroupTestUtils._ID_ONE; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.compareResourceLimits; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupOne; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.MONITOR; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.NAME_ONE; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.TIMESTAMP_ONE; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils._ID_ONE; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.compareResourceLimits; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupOne; public class CreateQueryGroupRequestTests extends OpenSearchTestCase { diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/CreateQueryGroupResponseTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/CreateQueryGroupResponseTests.java similarity index 89% rename from plugins/query-group/src/test/java/org/opensearch/plugin/qg/CreateQueryGroupResponseTests.java rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/CreateQueryGroupResponseTests.java index 905e5b8648ed5..c5d570427faa5 100644 --- a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/CreateQueryGroupResponseTests.java +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/CreateQueryGroupResponseTests.java @@ -6,11 +6,12 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.rest.RestStatus; import org.opensearch.test.OpenSearchTestCase; import java.io.IOException; @@ -19,7 +20,7 @@ public class CreateQueryGroupResponseTests extends OpenSearchTestCase { public void testSerialization() throws IOException { - CreateQueryGroupResponse response = new CreateQueryGroupResponse(QueryGroupTestUtils.queryGroupOne); + CreateQueryGroupResponse response = new CreateQueryGroupResponse(QueryGroupTestUtils.queryGroupOne, RestStatus.OK); BytesStreamOutput out = new BytesStreamOutput(); response.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/DeleteQueryGroupRequestTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/DeleteQueryGroupRequestTests.java similarity index 97% rename from plugins/query-group/src/test/java/org/opensearch/plugin/qg/DeleteQueryGroupRequestTests.java rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/DeleteQueryGroupRequestTests.java index de0ced93a2eaf..ae78f2bae9d2f 100644 --- a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/DeleteQueryGroupRequestTests.java +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/DeleteQueryGroupRequestTests.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.core.common.io.stream.StreamInput; diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/DeleteQueryGroupResponseTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/DeleteQueryGroupResponseTests.java similarity index 85% rename from plugins/query-group/src/test/java/org/opensearch/plugin/qg/DeleteQueryGroupResponseTests.java rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/DeleteQueryGroupResponseTests.java index 682dca443fc89..af3cb7ea356ea 100644 --- a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/DeleteQueryGroupResponseTests.java +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/DeleteQueryGroupResponseTests.java @@ -6,26 +6,27 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.rest.RestStatus; import org.opensearch.test.OpenSearchTestCase; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.compareQueryGroups; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupList; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupOne; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.compareQueryGroups; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupList; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupOne; public class DeleteQueryGroupResponseTests extends OpenSearchTestCase { public void testSerializationSingleQueryGroup() throws IOException { List list = List.of(queryGroupOne); - DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(list); + DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(list, RestStatus.OK); assertEquals(response.getQueryGroups(), list); BytesStreamOutput out = new BytesStreamOutput(); @@ -38,7 +39,7 @@ public void testSerializationSingleQueryGroup() throws IOException { } public void testSerializationMultipleQueryGroup() throws IOException { - DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(queryGroupList()); + DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(queryGroupList(), RestStatus.OK); assertEquals(response.getQueryGroups(), queryGroupList()); BytesStreamOutput out = new BytesStreamOutput(); @@ -53,7 +54,7 @@ public void testSerializationMultipleQueryGroup() throws IOException { public void testSerializationNull() throws IOException { List list = new ArrayList<>(); - DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(list); + DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(list, RestStatus.OK); assertEquals(response.getQueryGroups(), list); BytesStreamOutput out = new BytesStreamOutput(); diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/GetQueryGroupRequestTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/GetQueryGroupRequestTests.java similarity index 97% rename from plugins/query-group/src/test/java/org/opensearch/plugin/qg/GetQueryGroupRequestTests.java rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/GetQueryGroupRequestTests.java index 555c56abfa254..a3f3083cce1e9 100644 --- a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/GetQueryGroupRequestTests.java +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/GetQueryGroupRequestTests.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.core.common.io.stream.StreamInput; diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/GetQueryGroupResponseTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/GetQueryGroupResponseTests.java similarity index 93% rename from plugins/query-group/src/test/java/org/opensearch/plugin/qg/GetQueryGroupResponseTests.java rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/GetQueryGroupResponseTests.java index ca7035e3cdbb4..f9332df71a9b7 100644 --- a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/GetQueryGroupResponseTests.java +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/GetQueryGroupResponseTests.java @@ -6,11 +6,12 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.rest.RestStatus; import org.opensearch.test.OpenSearchTestCase; import java.io.IOException; @@ -22,7 +23,7 @@ public class GetQueryGroupResponseTests extends OpenSearchTestCase { public void testSerializationSingleQueryGroup() throws IOException { List list = new ArrayList<>(); list.add(QueryGroupTestUtils.queryGroupOne); - GetQueryGroupResponse response = new GetQueryGroupResponse(list); + GetQueryGroupResponse response = new GetQueryGroupResponse(list, RestStatus.OK); assertEquals(response.getQueryGroups(), list); BytesStreamOutput out = new BytesStreamOutput(); @@ -35,7 +36,7 @@ public void testSerializationSingleQueryGroup() throws IOException { } public void testSerializationMultipleQueryGroup() throws IOException { - GetQueryGroupResponse response = new GetQueryGroupResponse(QueryGroupTestUtils.queryGroupList()); + GetQueryGroupResponse response = new GetQueryGroupResponse(QueryGroupTestUtils.queryGroupList(), RestStatus.OK); assertEquals(response.getQueryGroups(), QueryGroupTestUtils.queryGroupList()); BytesStreamOutput out = new BytesStreamOutput(); @@ -50,7 +51,7 @@ public void testSerializationMultipleQueryGroup() throws IOException { public void testSerializationNull() throws IOException { List list = new ArrayList<>(); - GetQueryGroupResponse response = new GetQueryGroupResponse(list); + GetQueryGroupResponse response = new GetQueryGroupResponse(list, RestStatus.OK); assertEquals(response.getQueryGroups(), list); BytesStreamOutput out = new BytesStreamOutput(); diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/QueryGroupTestUtils.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/QueryGroupTestUtils.java similarity index 98% rename from plugins/query-group/src/test/java/org/opensearch/plugin/qg/QueryGroupTestUtils.java rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/QueryGroupTestUtils.java index dd4ab97f34a0f..f40fe929d9fd6 100644 --- a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/QueryGroupTestUtils.java +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/QueryGroupTestUtils.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.cluster.ClusterName; import org.opensearch.cluster.ClusterState; @@ -15,7 +15,7 @@ import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.settings.ClusterSettings; import org.opensearch.common.settings.Settings; -import org.opensearch.plugin.qg.service.QueryGroupPersistenceService; +import org.opensearch.plugin.wlm.service.QueryGroupPersistenceService; import org.opensearch.threadpool.ThreadPool; import java.util.HashSet; diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/UpdateQueryGroupRequestTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/UpdateQueryGroupRequestTests.java similarity index 92% rename from plugins/query-group/src/test/java/org/opensearch/plugin/qg/UpdateQueryGroupRequestTests.java rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/UpdateQueryGroupRequestTests.java index c505694be4011..888a7c632d9cb 100644 --- a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/UpdateQueryGroupRequestTests.java +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/UpdateQueryGroupRequestTests.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.common.io.stream.BytesStreamOutput; @@ -17,11 +17,11 @@ import java.util.HashMap; import java.util.Map; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.MONITOR; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.NAME_ONE; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.TIMESTAMP_ONE; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.compareResourceLimits; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupOne; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.MONITOR; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.NAME_ONE; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.TIMESTAMP_ONE; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.compareResourceLimits; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupOne; public class UpdateQueryGroupRequestTests extends OpenSearchTestCase { diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/UpdateQueryGroupResponseTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/UpdateQueryGroupResponseTests.java similarity index 89% rename from plugins/query-group/src/test/java/org/opensearch/plugin/qg/UpdateQueryGroupResponseTests.java rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/UpdateQueryGroupResponseTests.java index dfe3a590951b3..6e744427629fd 100644 --- a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/UpdateQueryGroupResponseTests.java +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/UpdateQueryGroupResponseTests.java @@ -6,11 +6,12 @@ * compatible open source license. */ -package org.opensearch.plugin.qg; +package org.opensearch.plugin.wlm; import org.opensearch.cluster.metadata.QueryGroup; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.rest.RestStatus; import org.opensearch.test.OpenSearchTestCase; import java.io.IOException; @@ -19,7 +20,7 @@ public class UpdateQueryGroupResponseTests extends OpenSearchTestCase { public void testSerialization() throws IOException { - UpdateQueryGroupResponse response = new UpdateQueryGroupResponse(QueryGroupTestUtils.queryGroupOne); + UpdateQueryGroupResponse response = new UpdateQueryGroupResponse(QueryGroupTestUtils.queryGroupOne, RestStatus.OK); BytesStreamOutput out = new BytesStreamOutput(); response.writeTo(out); StreamInput streamInput = out.bytes().streamInput(); diff --git a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/service/QueryGroupPersistenceServiceTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceServiceTests.java similarity index 89% rename from plugins/query-group/src/test/java/org/opensearch/plugin/qg/service/QueryGroupPersistenceServiceTests.java rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceServiceTests.java index ffa22bb1b4542..1e6ef3f114d3f 100644 --- a/plugins/query-group/src/test/java/org/opensearch/plugin/qg/service/QueryGroupPersistenceServiceTests.java +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceServiceTests.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugin.qg.service; +package org.opensearch.plugin.wlm.service; import org.opensearch.cluster.ClusterName; import org.opensearch.cluster.ClusterState; @@ -16,7 +16,7 @@ import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.settings.ClusterSettings; import org.opensearch.common.settings.Settings; -import org.opensearch.plugin.qg.UpdateQueryGroupRequest; +import org.opensearch.plugin.wlm.UpdateQueryGroupRequest; import org.opensearch.test.OpenSearchTestCase; import org.opensearch.threadpool.ThreadPool; @@ -29,21 +29,21 @@ import java.util.stream.Collectors; import static org.opensearch.cluster.metadata.QueryGroup.builder; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.MONITOR; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.NAME_NONE_EXISTED; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.NAME_ONE; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.NAME_TWO; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.SANDBOX_MAX_SETTING_NAME; -import static org.opensearch.plugin.qg.QueryGroupTestUtils._ID_ONE; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.assertInflightValuesAreZero; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.clusterState; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.compareQueryGroups; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.prepareSandboxPersistenceService; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupList; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupMap; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupOne; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupPersistenceService; -import static org.opensearch.plugin.qg.QueryGroupTestUtils.queryGroupTwo; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.MONITOR; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.NAME_NONE_EXISTED; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.NAME_ONE; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.NAME_TWO; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.SANDBOX_MAX_SETTING_NAME; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils._ID_ONE; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.assertInflightValuesAreZero; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.clusterState; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.compareQueryGroups; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.prepareSandboxPersistenceService; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupList; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupMap; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupOne; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupPersistenceService; +import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupTwo; import static org.mockito.Mockito.mock; public class QueryGroupPersistenceServiceTests extends OpenSearchTestCase { diff --git a/server/src/main/java/org/opensearch/cluster/metadata/QueryGroup.java b/server/src/main/java/org/opensearch/cluster/metadata/QueryGroup.java index 509666a3e6c05..87a6fc897e9c0 100644 --- a/server/src/main/java/org/opensearch/cluster/metadata/QueryGroup.java +++ b/server/src/main/java/org/opensearch/cluster/metadata/QueryGroup.java @@ -26,7 +26,7 @@ import java.util.Objects; /** - * Class to define the ResourceLimitGroup schema + * Class to define the QueryGroup schema * { * "fafjafjkaf9ag8a9ga9g7ag0aagaga" : { * "jvm": 0.4, @@ -47,25 +47,25 @@ public class QueryGroup extends AbstractDiffable implements ToXConte private final long updatedAtInMillis; private final Map resourceLimits; - // list of resources that are allowed to be present in the ResourceLimitGroup schema + // list of resources that are allowed to be present in the QueryGroup schema public static final List ALLOWED_RESOURCES = List.of("jvm"); public QueryGroup(String name, String _id, QueryGroupMode mode, Map resourceLimits, long updatedAt) { - Objects.requireNonNull(name, "ResourceLimitGroup.name can't be null"); - Objects.requireNonNull(resourceLimits, "ResourceLimitGroup.resourceLimits can't be null"); - Objects.requireNonNull(mode, "ResourceLimitGroup.mode can't be null"); - Objects.requireNonNull(_id, "ResourceLimitGroup._id can't be null"); + Objects.requireNonNull(name, "QueryGroup.name can't be null"); + Objects.requireNonNull(resourceLimits, "QueryGroup.resourceLimits can't be null"); + Objects.requireNonNull(mode, "QueryGroup.mode can't be null"); + Objects.requireNonNull(_id, "QueryGroup._id can't be null"); if (name.length() > MAX_CHARS_ALLOWED_IN_NAME) { - throw new IllegalArgumentException("ResourceLimitGroup.name shouldn't be more than 50 chars long"); + throw new IllegalArgumentException("QueryGroup.name shouldn't be more than 50 chars long"); } if (resourceLimits.isEmpty()) { - throw new IllegalArgumentException("ResourceLimitGroup.resourceLimits should at least have 1 resource limit"); + throw new IllegalArgumentException("QueryGroup.resourceLimits should at least have 1 resource limit"); } validateResourceLimits(resourceLimits); if (!isValid(updatedAt)) { - throw new IllegalArgumentException("ResourceLimitGroup.updatedAtInMillis is not a valid epoch"); + throw new IllegalArgumentException("QueryGroup.updatedAtInMillis is not a valid epoch"); } this.name = name; @@ -187,7 +187,7 @@ public static QueryGroup fromXContent(final XContentParser parser) throws IOExce } else if (ALLOWED_RESOURCES.contains(fieldName)) { resourceLimits_.put(fieldName, parser.doubleValue()); } else { - throw new IllegalArgumentException("unrecognised [field=" + fieldName + " in ResourceLimitGroup"); + throw new IllegalArgumentException("unrecognised [field=" + fieldName + " in QueryGroup"); } } } @@ -264,7 +264,7 @@ public static QueryGroupMode fromName(String s) { if (mode.getName().equalsIgnoreCase(s)) return mode; } - throw new IllegalArgumentException("Invalid value for ResourceLimitGroupMode: " + s); + throw new IllegalArgumentException("Invalid value for QueryGroupMode: " + s); } } diff --git a/server/src/main/java/org/opensearch/search/query_group/QueryGroupPruner.java b/server/src/main/java/org/opensearch/search/query_group/QueryGroupPruner.java deleted file mode 100644 index c46324adef639..0000000000000 --- a/server/src/main/java/org/opensearch/search/query_group/QueryGroupPruner.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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.search.query_group; - -/** - * This interface is used to identify and completely remove deleted QueryGroups which has been marked as deleted - * previously but had the tasks running at the time of deletion request - */ -public interface QueryGroupPruner { - /** - * remove the deleted QueryGroups from the system once all the tasks in those QueryGroups are completed/cancelled - */ - void pruneQueryGroup(); -} diff --git a/server/src/main/java/org/opensearch/search/query_group/QueryGroupService.java b/server/src/main/java/org/opensearch/search/query_group/QueryGroupService.java deleted file mode 100644 index d274c1561f1a9..0000000000000 --- a/server/src/main/java/org/opensearch/search/query_group/QueryGroupService.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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.search.query_group; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.opensearch.common.inject.Inject; -import org.opensearch.common.lifecycle.AbstractLifecycleComponent; -import org.opensearch.search.query_group.cancellation.QueryGroupRequestCanceller; -import org.opensearch.search.query_group.tracker.QueryGroupResourceUsageTracker; -import org.opensearch.threadpool.Scheduler; -import org.opensearch.threadpool.ThreadPool; - -import java.io.IOException; - -/** - * Main service which will run periodically to track and cancel resource constraint violating tasks in QueryGroup - */ -public class QueryGroupService extends AbstractLifecycleComponent { - private static final Logger logger = LogManager.getLogger(QueryGroupService.class); - - private final QueryGroupResourceUsageTracker requestTracker; - private final QueryGroupRequestCanceller requestCanceller; - private final QueryGroupPruner queryGroupPruner; - private volatile Scheduler.Cancellable scheduledFuture; - private final QueryGroupServiceSettings queryGroupServiceSettings; - private final ThreadPool threadPool; - - /** - * Guice managed constructor - * @param requestTrackerService - * @param requestCanceller - * @param queryGroupPruner - * @param queryGroupServiceSettings - * @param threadPool - */ - @Inject - public QueryGroupService( - QueryGroupResourceUsageTracker requestTrackerService, - QueryGroupRequestCanceller requestCanceller, - QueryGroupPruner queryGroupPruner, - QueryGroupServiceSettings queryGroupServiceSettings, - ThreadPool threadPool - ) { - this.requestTracker = requestTrackerService; - this.requestCanceller = requestCanceller; - this.queryGroupPruner = queryGroupPruner; - this.queryGroupServiceSettings = queryGroupServiceSettings; - this.threadPool = threadPool; - } - - /** - * run at regular interval - */ - private void doRun() { - requestTracker.updateQueryGroupsResourceUsage(); - requestCanceller.cancelViolatingTasks(); - queryGroupPruner.pruneQueryGroup(); - } - - /** - * {@link AbstractLifecycleComponent} lifecycle method - */ - @Override - protected void doStart() { - scheduledFuture = threadPool.scheduleWithFixedDelay(() -> { - try { - doRun(); - } catch (Exception e) { - logger.debug("Exception occurred in Resource Limit Group service", e); - } - }, queryGroupServiceSettings.getRunIntervalMillis(), ThreadPool.Names.GENERIC); - } - - @Override - protected void doStop() { - if (scheduledFuture != null) { - scheduledFuture.cancel(); - } - } - - @Override - protected void doClose() throws IOException {} -} diff --git a/server/src/main/java/org/opensearch/search/query_group/cancellation/QueryGroupRequestCanceller.java b/server/src/main/java/org/opensearch/search/query_group/cancellation/QueryGroupRequestCanceller.java deleted file mode 100644 index e33d771d33673..0000000000000 --- a/server/src/main/java/org/opensearch/search/query_group/cancellation/QueryGroupRequestCanceller.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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.search.query_group.cancellation; - -/** - * This interface is used to identify and cancel the violating tasks in a QueryGroup - */ -public interface QueryGroupRequestCanceller { - /** - * Cancels the tasks from conteded QueryGroups - */ - void cancelViolatingTasks(); -} diff --git a/server/src/main/java/org/opensearch/search/query_group/cancellation/package-info.java b/server/src/main/java/org/opensearch/search/query_group/cancellation/package-info.java deleted file mode 100644 index 0e9fe853df60a..0000000000000 --- a/server/src/main/java/org/opensearch/search/query_group/cancellation/package-info.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * 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 for cancellation related abstracts - */ -package org.opensearch.search.query_group.cancellation; diff --git a/server/src/main/java/org/opensearch/search/query_group/module/QueryGroupModule.java b/server/src/main/java/org/opensearch/search/query_group/module/QueryGroupModule.java deleted file mode 100644 index d39ffd7419f97..0000000000000 --- a/server/src/main/java/org/opensearch/search/query_group/module/QueryGroupModule.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.search.query_group.module; - -import org.opensearch.common.inject.AbstractModule; -import org.opensearch.search.query_group.QueryGroupPruner; -import org.opensearch.search.query_group.cancellation.QueryGroupRequestCanceller; -import org.opensearch.search.query_group.tracker.QueryGroupResourceUsageTracker; -import org.opensearch.search.query_group.tracker.QueryGroupResourceUsageTrackerService; - -/** - * Module class for resource usage limiting related artifacts - */ -public class QueryGroupModule extends AbstractModule { - - /** - * Default constructor - */ - public QueryGroupModule() {} - - @Override - protected void configure() { - bind(QueryGroupResourceUsageTracker.class).to(QueryGroupResourceUsageTrackerService.class).asEagerSingleton(); - bind(QueryGroupRequestCanceller.class).to(QueryGroupResourceUsageTrackerService.class).asEagerSingleton(); - bind(QueryGroupPruner.class).to(QueryGroupResourceUsageTrackerService.class).asEagerSingleton(); - } -} diff --git a/server/src/main/java/org/opensearch/search/query_group/module/package-info.java b/server/src/main/java/org/opensearch/search/query_group/module/package-info.java deleted file mode 100644 index 6f341d6941317..0000000000000 --- a/server/src/main/java/org/opensearch/search/query_group/module/package-info.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * 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. - */ - -/** - * Guice Module - */ - -package org.opensearch.search.query_group.module; diff --git a/server/src/main/java/org/opensearch/search/query_group/tracker/QueryGroupResourceUsageTracker.java b/server/src/main/java/org/opensearch/search/query_group/tracker/QueryGroupResourceUsageTracker.java deleted file mode 100644 index 957a716c1ef89..0000000000000 --- a/server/src/main/java/org/opensearch/search/query_group/tracker/QueryGroupResourceUsageTracker.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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.search.query_group.tracker; - -/** - * This interface is mainly for tracking the QueryGroup level resource usages - */ -public interface QueryGroupResourceUsageTracker { - /** - * updates the current resource usage of QueryGroups - */ - public void updateQueryGroupsResourceUsage(); -} diff --git a/server/src/main/java/org/opensearch/search/query_group/tracker/QueryGroupResourceUsageTrackerService.java b/server/src/main/java/org/opensearch/search/query_group/tracker/QueryGroupResourceUsageTrackerService.java deleted file mode 100644 index 812a1de686850..0000000000000 --- a/server/src/main/java/org/opensearch/search/query_group/tracker/QueryGroupResourceUsageTrackerService.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * 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.search.query_group.tracker; - -import org.opensearch.common.inject.Inject; -import org.opensearch.core.tasks.resourcetracker.TaskResourceUsage; -import org.opensearch.search.query_group.QueryGroupPruner; -import org.opensearch.search.query_group.QueryGroupService; -import org.opensearch.search.query_group.cancellation.QueryGroupRequestCanceller; -import org.opensearch.tasks.Task; -import org.opensearch.tasks.TaskCancellation; -import org.opensearch.tasks.TaskManager; -import org.opensearch.tasks.TaskResourceTrackingService; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.function.LongSupplier; -import java.util.stream.Collectors; - -/** - * This class tracks requests per QueryGroups - */ -public class QueryGroupResourceUsageTrackerService - implements - TaskManager.TaskEventListeners, - QueryGroupResourceUsageTracker, - QueryGroupRequestCanceller, - QueryGroupPruner { - - private static final String CPU = "CPU"; - private static final String JVM_ALLOCATIONS = "JVM_Allocations"; - private static final int numberOfAvailableProcessors = Runtime.getRuntime().availableProcessors(); - private static final long totalAvailableJvmMemory = Runtime.getRuntime().totalMemory(); - private final LongSupplier timeNanosSupplier; - /** - * QueryGroup ids which are marked for deletion in between the - * {@link QueryGroupService} runs - */ - private List toDeleteQueryGroups; - private List activeQueryGroups; - private final TaskManager taskManager; - private final TaskResourceTrackingService taskResourceTrackingService; - - /** - * QueryGroupResourceUsageTrackerService constructor - * @param taskManager - * @param taskResourceTrackingService - */ - @Inject - public QueryGroupResourceUsageTrackerService(TaskManager taskManager, TaskResourceTrackingService taskResourceTrackingService) { - this.taskManager = taskManager; - this.taskResourceTrackingService = taskResourceTrackingService; - toDeleteQueryGroups = Collections.synchronizedList(new ArrayList<>()); - this.timeNanosSupplier = System::nanoTime; - } - - @Override - public void updateQueryGroupsResourceUsage() { - - } - - private AbsoluteResourceUsage calculateAbsoluteResourceUsageFor(Task task) { - TaskResourceUsage taskResourceUsage = task.getTotalResourceStats(); - long cpuTimeInNanos = taskResourceUsage.getCpuTimeInNanos(); - long jvmAllocations = taskResourceUsage.getMemoryInBytes(); - long taskElapsedTime = timeNanosSupplier.getAsLong() - task.getStartTimeNanos(); - return new AbsoluteResourceUsage( - (cpuTimeInNanos * 1.0f) / (taskElapsedTime * numberOfAvailableProcessors), - ((jvmAllocations * 1.0f) / totalAvailableJvmMemory) - ); - } - - /** - * Value holder class for resource usage in absolute terms with respect to system/process mem - */ - private static class AbsoluteResourceUsage { - private final double absoluteCpuUsage; - private final double absoluteJvmAllocationsUsage; - - public AbsoluteResourceUsage(double absoluteCpuUsage, double absoluteJvmAllocationsUsage) { - this.absoluteCpuUsage = absoluteCpuUsage; - this.absoluteJvmAllocationsUsage = absoluteJvmAllocationsUsage; - } - - public static AbsoluteResourceUsage merge(AbsoluteResourceUsage a, AbsoluteResourceUsage b) { - return new AbsoluteResourceUsage( - a.absoluteCpuUsage + b.absoluteCpuUsage, - a.absoluteJvmAllocationsUsage + b.absoluteJvmAllocationsUsage - ); - } - - public double getAbsoluteCpuUsageInPercentage() { - return absoluteCpuUsage * 100; - } - - public double getAbsoluteJvmAllocationsUsageInPercent() { - return absoluteJvmAllocationsUsage * 100; - } - } - - /** - * filter out the deleted Resource Limit Groups which still has unfinished tasks - */ - public void pruneQueryGroup() { - toDeleteQueryGroups = toDeleteQueryGroups.stream().filter(this::hasUnfinishedTasks).collect(Collectors.toList()); - } - - private boolean hasUnfinishedTasks(String sandboxId) { - return false; - } - - /** - * method to handle the completed tasks - * @param task represents completed task on the node - */ - @Override - public void onTaskCompleted(Task task) {} - - /** - * This method will select the Resource Limit Groups violating the enforced constraints - * and cancel the tasks from the violating Resource Limit Groups - * Cancellation happens in two scenarios - *
    - *
  1. If the Resource Limit Group is of enforced type and it is breaching its cancellation limit for the threshold
  2. - *
  3. Node is in duress and Resource Limit Groups which are breaching the cancellation thresholds will have cancellations
  4. - *
- */ - @Override - public void cancelViolatingTasks() { - List cancellableTasks = getCancellableTasks(); - for (TaskCancellation taskCancellation : cancellableTasks) { - taskCancellation.cancel(); - } - } - - /** - * - * @return list of cancellable tasks - */ - private List getCancellableTasks() { - // get cancellations from enforced type Resource Limit Groups - List inViolationSandboxes = getBreachingSandboxIds(); - List cancellableTasks = new ArrayList<>(); - for (String sandboxId : inViolationSandboxes) { - cancellableTasks.addAll(getCancellableTasksFrom(sandboxId)); - } - return cancellableTasks; - } - - public void deleteSandbox(String sandboxId) { - if (hasUnfinishedTasks(sandboxId)) { - toDeleteQueryGroups.add(sandboxId); - } - // remove this sandbox from the active sandboxes - } - - private List getBreachingSandboxIds() { - return Collections.emptyList(); - } - - private List getCancellableTasksFrom(String sandboxId) { - return Collections.emptyList(); - } -} diff --git a/server/src/main/java/org/opensearch/search/query_group/tracker/package-info.java b/server/src/main/java/org/opensearch/search/query_group/tracker/package-info.java deleted file mode 100644 index e4e85965da439..0000000000000 --- a/server/src/main/java/org/opensearch/search/query_group/tracker/package-info.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * 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. - */ - -/** - * ResourceLimitGroup resource tracking artifacts - */ -package org.opensearch.search.query_group.tracker; diff --git a/server/src/test/java/org/opensearch/cluster/metadata/QueryGroupMetadataTests.java b/server/src/test/java/org/opensearch/cluster/metadata/QueryGroupMetadataTests.java index 3dcaa7ee31b4d..18cdeb114a012 100644 --- a/server/src/test/java/org/opensearch/cluster/metadata/QueryGroupMetadataTests.java +++ b/server/src/test/java/org/opensearch/cluster/metadata/QueryGroupMetadataTests.java @@ -14,7 +14,7 @@ import java.util.Collections; import java.util.Set; -import static org.opensearch.cluster.metadata.QueryGroupTests.createRandomResourceLimitGroup; +import static org.opensearch.cluster.metadata.QueryGroupTests.createRandomQueryGroup; public class QueryGroupMetadataTests extends AbstractNamedWriteableTestCase { @@ -34,10 +34,10 @@ protected Class categoryClass() { @Override protected QueryGroupMetadata createTestInstance() { - return new QueryGroupMetadata(getRandomResourceLimitGroups()); + return new QueryGroupMetadata(getRandomQueryGroups()); } - private Set getRandomResourceLimitGroups() { - return Set.of(createRandomResourceLimitGroup(), createRandomResourceLimitGroup()); + private Set getRandomQueryGroups() { + return Set.of(createRandomQueryGroup(), createRandomQueryGroup()); } } diff --git a/server/src/test/java/org/opensearch/cluster/metadata/QueryGroupTests.java b/server/src/test/java/org/opensearch/cluster/metadata/QueryGroupTests.java index 2e7dc2812e431..1d900b3c02d27 100644 --- a/server/src/test/java/org/opensearch/cluster/metadata/QueryGroupTests.java +++ b/server/src/test/java/org/opensearch/cluster/metadata/QueryGroupTests.java @@ -27,7 +27,7 @@ public class QueryGroupTests extends AbstractSerializingTestCase { QueryGroup.QueryGroupMode.MONITOR ); - static QueryGroup createRandomResourceLimitGroup() { + static QueryGroup createRandomQueryGroup() { String name = randomAlphaOfLength(10); Map resourceLimit = new HashMap<>(); resourceLimit.put("jvm", randomDoubleBetween(0.0, 0.80, false)); @@ -63,7 +63,7 @@ protected Writeable.Reader instanceReader() { */ @Override protected QueryGroup createTestInstance() { - return createRandomResourceLimitGroup(); + return createRandomQueryGroup(); } public void testNullName() { @@ -91,7 +91,7 @@ public void testEmptyResourceLimits() { ); } - public void testIllegalResourceLimitGroupMode() { + public void testIllegalQueryGroupMode() { assertThrows( NullPointerException.class, () -> new QueryGroup("analytics", "_id", null, Map.of("jvm", (Object) 0.4), Instant.now().getMillis()) @@ -124,7 +124,7 @@ public void testInvalidResourceLimitWhenInvalidSystemResourceValueIsGiven() { ); } - public void testValidResourceLimitGroup() { + public void testValidQueryGroup() { QueryGroup queryGroup = new QueryGroup( "analytics", "_id", From 5b539342fe6b9dfc2830b40bdbbba20af5977e80 Mon Sep 17 00:00:00 2001 From: Ruirui Zhang Date: Wed, 19 Jun 2024 11:45:03 -0700 Subject: [PATCH 14/15] seperate PR to only include create API Signed-off-by: Ruirui Zhang --- .../plugin/wlm/CreateQueryGroupResponse.java | 8 - .../plugin/wlm/DeleteQueryGroupAction.java | 37 --- .../plugin/wlm/DeleteQueryGroupRequest.java | 74 ----- .../plugin/wlm/DeleteQueryGroupResponse.java | 95 ------- .../plugin/wlm/GetQueryGroupAction.java | 37 --- .../plugin/wlm/GetQueryGroupRequest.java | 74 ----- .../plugin/wlm/GetQueryGroupResponse.java | 95 ------- .../wlm/TransportDeleteQueryGroupAction.java | 58 ---- .../wlm/TransportGetQueryGroupAction.java | 58 ---- .../wlm/TransportUpdateQueryGroupAction.java | 57 ---- .../plugin/wlm/UpdateQueryGroupAction.java | 36 --- .../plugin/wlm/UpdateQueryGroupRequest.java | 268 ------------------ .../plugin/wlm/UpdateQueryGroupResponse.java | 87 ------ .../plugin/wlm/WorkloadManagementPlugin.java | 17 +- .../wlm/rest/RestDeleteQueryGroupAction.java | 69 ----- .../wlm/rest/RestGetQueryGroupAction.java | 69 ----- .../wlm/rest/RestUpdateQueryGroupAction.java | 80 ------ .../plugin/wlm/service/Persistable.java | 25 -- .../service/QueryGroupPersistenceService.java | 190 ------------- .../wlm/DeleteQueryGroupRequestTests.java | 38 --- .../wlm/DeleteQueryGroupResponseTests.java | 68 ----- .../plugin/wlm/GetQueryGroupRequestTests.java | 38 --- .../wlm/GetQueryGroupResponseTests.java | 65 ----- .../wlm/UpdateQueryGroupRequestTests.java | 119 -------- .../wlm/UpdateQueryGroupResponseTests.java | 33 --- .../QueryGroupPersistenceServiceTests.java | 119 -------- 26 files changed, 2 insertions(+), 1912 deletions(-) delete mode 100644 plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupAction.java delete mode 100644 plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupRequest.java delete mode 100644 plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupResponse.java delete mode 100644 plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupAction.java delete mode 100644 plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupRequest.java delete mode 100644 plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupResponse.java delete mode 100644 plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportDeleteQueryGroupAction.java delete mode 100644 plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportGetQueryGroupAction.java delete mode 100644 plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportUpdateQueryGroupAction.java delete mode 100644 plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupAction.java delete mode 100644 plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupRequest.java delete mode 100644 plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupResponse.java delete mode 100644 plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestDeleteQueryGroupAction.java delete mode 100644 plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestGetQueryGroupAction.java delete mode 100644 plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestUpdateQueryGroupAction.java delete mode 100644 plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/DeleteQueryGroupRequestTests.java delete mode 100644 plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/DeleteQueryGroupResponseTests.java delete mode 100644 plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/GetQueryGroupRequestTests.java delete mode 100644 plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/GetQueryGroupResponseTests.java delete mode 100644 plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/UpdateQueryGroupRequestTests.java delete mode 100644 plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/UpdateQueryGroupResponseTests.java diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/CreateQueryGroupResponse.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/CreateQueryGroupResponse.java index 5e70084f0f0e1..ea112f95f1097 100644 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/CreateQueryGroupResponse.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/CreateQueryGroupResponse.java @@ -77,12 +77,4 @@ public QueryGroup getQueryGroup() { public RestStatus getRestStatus() { return restStatus; } - - /** - * restStatus setter - * @param restStatus - A {@link RestStatus} object - */ - public void setRestStatus(RestStatus restStatus) { - this.restStatus = restStatus; - } } diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupAction.java deleted file mode 100644 index 207f8ae8ee5c1..0000000000000 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupAction.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.action.ActionType; - -/** - * Rest action to delete QueryGroup - * - * @opensearch.api - */ -public class DeleteQueryGroupAction extends ActionType { - - /** - /** - * An instance of DeleteQueryGroupAction - */ - public static final DeleteQueryGroupAction INSTANCE = new DeleteQueryGroupAction(); - - /** - * Name for DeleteQueryGroupAction - */ - public static final String NAME = "cluster:admin/opensearch/query_group/wlm/_delete"; - - /** - * Default constructor - */ - private DeleteQueryGroupAction() { - super(NAME, DeleteQueryGroupResponse::new); - } -} diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupRequest.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupRequest.java deleted file mode 100644 index 3d05a33bc1808..0000000000000 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupRequest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.action.ActionRequest; -import org.opensearch.action.ActionRequestValidationException; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.common.io.stream.Writeable; - -import java.io.IOException; - -/** - * A request for delete QueryGroup - * - * @opensearch.internal - */ -public class DeleteQueryGroupRequest extends ActionRequest implements Writeable.Reader { - String name; - - /** - * Default constructor for DeleteQueryGroupRequest - * @param name - name for the QueryGroup to get - */ - public DeleteQueryGroupRequest(String name) { - this.name = name; - } - - /** - * Constructor for DeleteQueryGroupRequest - * @param in - A {@link StreamInput} object - */ - public DeleteQueryGroupRequest(StreamInput in) throws IOException { - super(in); - name = in.readOptionalString(); - } - - @Override - public DeleteQueryGroupRequest read(StreamInput in) throws IOException { - return new DeleteQueryGroupRequest(in); - } - - @Override - public ActionRequestValidationException validate() { - return null; - } - - /** - * Name getter - */ - public String getName() { - return name; - } - - /** - * Name setter - * @param name - name to be set - */ - public void setName(String name) { - this.name = name; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeOptionalString(name); - } -} diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupResponse.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupResponse.java deleted file mode 100644 index 0c1258df338a9..0000000000000 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/DeleteQueryGroupResponse.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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.cluster.metadata.QueryGroup; -import org.opensearch.core.action.ActionResponse; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.core.xcontent.ToXContentObject; -import org.opensearch.core.xcontent.XContentBuilder; - -import java.io.IOException; -import java.util.List; - -/** - * Response for the delete API for QueryGroup - * - * @opensearch.internal - */ -public class DeleteQueryGroupResponse extends ActionResponse implements ToXContent, ToXContentObject { - private final List queryGroups; - private RestStatus restStatus; - - /** - * Constructor for DeleteQueryGroupResponse - * @param queryGroups - The QueryGroup list to be fetched - * @param restStatus - The rest status for this response - */ - public DeleteQueryGroupResponse(final List queryGroups, RestStatus restStatus) { - this.queryGroups = queryGroups; - this.restStatus = restStatus; - } - - /** - * Constructor for DeleteQueryGroupResponse - * @param in - A {@link StreamInput} object - */ - public DeleteQueryGroupResponse(StreamInput in) throws IOException { - this.queryGroups = in.readList(QueryGroup::new); - this.restStatus = RestStatus.readFrom(in); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeList(queryGroups); - RestStatus.writeTo(out, restStatus); - } - - @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject(); - builder.startArray("deleted"); - for (QueryGroup group : queryGroups) { - builder.startObject(); - builder.field("name", group.getName()); - builder.field("mode", group.getMode().getName()); - builder.field("updatedAt", group.getUpdatedAtInMillis()); - builder.mapContents(group.getResourceLimits()); - builder.endObject(); - } - builder.endArray(); - builder.endObject(); - return builder; - } - - /** - * queryGroups getter - */ - public List getQueryGroups() { - return queryGroups; - } - - /** - * restStatus getter - */ - public RestStatus getRestStatus() { - return restStatus; - } - - /** - * restStatus setter - * @param restStatus - A {@link RestStatus} object - */ - public void setRestStatus(RestStatus restStatus) { - this.restStatus = restStatus; - } -} diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupAction.java deleted file mode 100644 index 1c507ded8337a..0000000000000 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupAction.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.action.ActionType; - -/** - * Rest action to get QueryGroup - * - * @opensearch.api - */ -public class GetQueryGroupAction extends ActionType { - - /** - /** - * An instance of GetQueryGroupAction - */ - public static final GetQueryGroupAction INSTANCE = new GetQueryGroupAction(); - - /** - * Name for GetQueryGroupAction - */ - public static final String NAME = "cluster:admin/opensearch/query_group/wlm/_get"; - - /** - * Default constructor - */ - private GetQueryGroupAction() { - super(NAME, GetQueryGroupResponse::new); - } -} diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupRequest.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupRequest.java deleted file mode 100644 index 62df9c9ac2fbb..0000000000000 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupRequest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.action.ActionRequest; -import org.opensearch.action.ActionRequestValidationException; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.common.io.stream.Writeable; - -import java.io.IOException; - -/** - * A request for get QueryGroup - * - * @opensearch.internal - */ -public class GetQueryGroupRequest extends ActionRequest implements Writeable.Reader { - String name; - - /** - * Default constructor for GetQueryGroupRequest - * @param name - name for the QueryGroup to get - */ - public GetQueryGroupRequest(String name) { - this.name = name; - } - - /** - * Constructor for GetQueryGroupRequest - * @param in - A {@link StreamInput} object - */ - public GetQueryGroupRequest(StreamInput in) throws IOException { - super(in); - name = in.readOptionalString(); - } - - @Override - public GetQueryGroupRequest read(StreamInput in) throws IOException { - return new GetQueryGroupRequest(in); - } - - @Override - public ActionRequestValidationException validate() { - return null; - } - - /** - * Name getter - */ - public String getName() { - return name; - } - - /** - * Name setter - * @param name - name to be set - */ - public void setName(String name) { - this.name = name; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeOptionalString(name); - } -} diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupResponse.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupResponse.java deleted file mode 100644 index e68a1a7f58184..0000000000000 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/GetQueryGroupResponse.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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.cluster.metadata.QueryGroup; -import org.opensearch.core.action.ActionResponse; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.core.xcontent.ToXContentObject; -import org.opensearch.core.xcontent.XContentBuilder; - -import java.io.IOException; -import java.util.List; - -/** - * Response for the get API for QueryGroup - * - * @opensearch.internal - */ -public class GetQueryGroupResponse extends ActionResponse implements ToXContent, ToXContentObject { - private final List queryGroups; - private RestStatus restStatus; - - /** - * Constructor for GetQueryGroupResponse - * @param queryGroups - The QueryGroup list to be fetched - * @param restStatus - The rest status of the request - */ - public GetQueryGroupResponse(final List queryGroups, RestStatus restStatus) { - this.queryGroups = queryGroups; - this.restStatus = restStatus; - } - - /** - * Constructor for GetQueryGroupResponse - * @param in - A {@link StreamInput} object - */ - public GetQueryGroupResponse(StreamInput in) throws IOException { - this.queryGroups = in.readList(QueryGroup::new); - restStatus = RestStatus.readFrom(in); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeList(queryGroups); - RestStatus.writeTo(out, restStatus); - } - - @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject(); - builder.startArray("query_groups"); - for (QueryGroup group : queryGroups) { - builder.startObject(); - builder.field("name", group.getName()); - builder.field("mode", group.getMode().getName()); - builder.field("updatedAt", group.getUpdatedAtInMillis()); - builder.mapContents(group.getResourceLimits()); - builder.endObject(); - } - builder.endArray(); - builder.endObject(); - return builder; - } - - /** - * queryGroups getter - */ - public List getQueryGroups() { - return queryGroups; - } - - /** - * restStatus getter - */ - public RestStatus getRestStatus() { - return restStatus; - } - - /** - * restStatus setter - * @param restStatus - A {@link RestStatus} object - */ - public void setRestStatus(RestStatus restStatus) { - this.restStatus = restStatus; - } -} diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportDeleteQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportDeleteQueryGroupAction.java deleted file mode 100644 index 41bb84a7aea7f..0000000000000 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportDeleteQueryGroupAction.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.action.support.ActionFilters; -import org.opensearch.action.support.HandledTransportAction; -import org.opensearch.cluster.metadata.QueryGroup; -import org.opensearch.common.inject.Inject; -import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.wlm.service.Persistable; -import org.opensearch.tasks.Task; -import org.opensearch.threadpool.ThreadPool; -import org.opensearch.transport.TransportService; - -/** - * Transport action for delete QueryGroup - * - * @opensearch.internal - */ -public class TransportDeleteQueryGroupAction extends HandledTransportAction { - - private final ThreadPool threadPool; - private final Persistable queryGroupPersistenceService; - - /** - * Constructor for TransportDeleteQueryGroupAction - * - * @param actionName - action name - * @param transportService - a {@link TransportService} object - * @param actionFilters - a {@link ActionFilters} object - * @param threadPool - a {@link ThreadPool} object - * @param queryGroupPersistenceService - a {@link Persistable} object - */ - @Inject - public TransportDeleteQueryGroupAction( - String actionName, - TransportService transportService, - ActionFilters actionFilters, - ThreadPool threadPool, - Persistable queryGroupPersistenceService - ) { - super(DeleteQueryGroupAction.NAME, transportService, actionFilters, DeleteQueryGroupRequest::new); - this.threadPool = threadPool; - this.queryGroupPersistenceService = queryGroupPersistenceService; - } - - @Override - protected void doExecute(Task task, DeleteQueryGroupRequest request, ActionListener listener) { - String name = request.getName(); - threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> queryGroupPersistenceService.delete(name, listener)); - } -} diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportGetQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportGetQueryGroupAction.java deleted file mode 100644 index 8c353faddc122..0000000000000 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportGetQueryGroupAction.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.action.support.ActionFilters; -import org.opensearch.action.support.HandledTransportAction; -import org.opensearch.cluster.metadata.QueryGroup; -import org.opensearch.common.inject.Inject; -import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.wlm.service.Persistable; -import org.opensearch.tasks.Task; -import org.opensearch.threadpool.ThreadPool; -import org.opensearch.transport.TransportService; - -/** - * Transport action for get QueryGroup - * - * @opensearch.internal - */ -public class TransportGetQueryGroupAction extends HandledTransportAction { - - private final ThreadPool threadPool; - private final Persistable queryGroupPersistenceService; - - /** - * Constructor for TransportGetQueryGroupAction - * - * @param actionName - action name - * @param transportService - a {@link TransportService} object - * @param actionFilters - a {@link ActionFilters} object - * @param threadPool - a {@link ThreadPool} object - * @param queryGroupPersistenceService - a {@link Persistable} object - */ - @Inject - public TransportGetQueryGroupAction( - String actionName, - TransportService transportService, - ActionFilters actionFilters, - ThreadPool threadPool, - Persistable queryGroupPersistenceService - ) { - super(GetQueryGroupAction.NAME, transportService, actionFilters, GetQueryGroupRequest::new); - this.threadPool = threadPool; - this.queryGroupPersistenceService = queryGroupPersistenceService; - } - - @Override - protected void doExecute(Task task, GetQueryGroupRequest request, ActionListener listener) { - String name = request.getName(); - threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> queryGroupPersistenceService.get(name, listener)); - } -} diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportUpdateQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportUpdateQueryGroupAction.java deleted file mode 100644 index 0e560718ced62..0000000000000 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/TransportUpdateQueryGroupAction.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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.action.support.ActionFilters; -import org.opensearch.action.support.HandledTransportAction; -import org.opensearch.cluster.metadata.QueryGroup; -import org.opensearch.common.inject.Inject; -import org.opensearch.core.action.ActionListener; -import org.opensearch.plugin.wlm.service.Persistable; -import org.opensearch.tasks.Task; -import org.opensearch.threadpool.ThreadPool; -import org.opensearch.transport.TransportService; - -/** - * Transport action for update QueryGroup - * - * @opensearch.internal - */ -public class TransportUpdateQueryGroupAction extends HandledTransportAction { - - private final ThreadPool threadPool; - private final Persistable queryGroupPersistenceService; - - /** - * Constructor for TransportUpdateQueryGroupAction - * - * @param actionName - action name - * @param transportService - a {@link TransportService} object - * @param actionFilters - a {@link ActionFilters} object - * @param threadPool - a {@link ThreadPool} object - * @param queryGroupPersistenceService - a {@link Persistable} object - */ - @Inject - public TransportUpdateQueryGroupAction( - String actionName, - TransportService transportService, - ActionFilters actionFilters, - ThreadPool threadPool, - Persistable queryGroupPersistenceService - ) { - super(UpdateQueryGroupAction.NAME, transportService, actionFilters, UpdateQueryGroupRequest::new); - this.threadPool = threadPool; - this.queryGroupPersistenceService = queryGroupPersistenceService; - } - - @Override - protected void doExecute(Task task, UpdateQueryGroupRequest request, ActionListener listener) { - threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> queryGroupPersistenceService.update(request, listener)); - } -} diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupAction.java deleted file mode 100644 index b9f00e1ba70a8..0000000000000 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupAction.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.action.ActionType; - -/** - * Rest action to update QueryGroup - * - * @opensearch.api - */ -public class UpdateQueryGroupAction extends ActionType { - - /** - * An instance of UpdateQueryGroupAction - */ - public static final UpdateQueryGroupAction INSTANCE = new UpdateQueryGroupAction(); - - /** - * Name for UpdateQueryGroupAction - */ - public static final String NAME = "cluster:admin/opensearch/query_group/wlm/_update"; - - /** - * Default constructor - */ - private UpdateQueryGroupAction() { - super(NAME, UpdateQueryGroupResponse::new); - } -} diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupRequest.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupRequest.java deleted file mode 100644 index c29cdc524e899..0000000000000 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupRequest.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * 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.action.ActionRequest; -import org.opensearch.action.ActionRequestValidationException; -import org.opensearch.cluster.metadata.QueryGroup; -import org.opensearch.cluster.metadata.QueryGroup.QueryGroupMode; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.common.io.stream.Writeable; -import org.opensearch.core.xcontent.XContentParser; -import org.joda.time.Instant; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; - -import static org.opensearch.cluster.metadata.QueryGroup.ALLOWED_RESOURCES; -import static org.opensearch.plugin.wlm.CreateQueryGroupRequest.validateName; -import static org.opensearch.plugin.wlm.CreateQueryGroupRequest.validateMode; -import static org.opensearch.plugin.wlm.CreateQueryGroupRequest.validateUpdatedAtInMillis; - -/** - * A request for update QueryGroup - * - * @opensearch.internal - */ -public class UpdateQueryGroupRequest extends ActionRequest implements Writeable.Reader { - String name; - Map resourceLimits; - QueryGroupMode mode; - long updatedAtInMillis; - - /** - * Default constructor for UpdateQueryGroupRequest - */ - public UpdateQueryGroupRequest() {} - - /** - * Constructor for UpdateQueryGroupRequest - * @param queryGroup - A {@link QueryGroup} object - */ - public UpdateQueryGroupRequest(QueryGroup queryGroup) { - this.name = queryGroup.getName(); - this.mode = queryGroup.getMode(); - this.resourceLimits = queryGroup.getResourceLimits(); - this.updatedAtInMillis = queryGroup.getUpdatedAtInMillis(); - verifyUpdateQueryGroupRequest(name, mode, resourceLimits, updatedAtInMillis); - } - - /** - * Constructor for UpdateQueryGroupRequest - * @param name - QueryGroup name for UpdateQueryGroupRequest - * @param mode - QueryGroup mode for UpdateQueryGroupRequest - * @param resourceLimits - QueryGroup resourceLimits for UpdateQueryGroupRequest - * @param updatedAtInMillis - QueryGroup updated time in millis for UpdateQueryGroupRequest - */ - public UpdateQueryGroupRequest(String name, QueryGroupMode mode, Map resourceLimits, long updatedAtInMillis) { - this.name = name; - this.mode = mode; - this.resourceLimits = resourceLimits; - this.updatedAtInMillis = updatedAtInMillis; - verifyUpdateQueryGroupRequest(name, mode, resourceLimits, updatedAtInMillis); - } - - /** - * Constructor for UpdateQueryGroupRequest - * @param in - A {@link StreamInput} object - */ - public UpdateQueryGroupRequest(StreamInput in) throws IOException { - super(in); - name = in.readString(); - if (in.readBoolean()) { - resourceLimits = in.readMap(); - } else { - resourceLimits = new HashMap<>(); - } - if (in.readBoolean()) { - mode = QueryGroupMode.fromName(in.readString()); - } - updatedAtInMillis = in.readLong(); - verifyUpdateQueryGroupRequest(name, mode, resourceLimits, updatedAtInMillis); - } - - /** - * Verification for UpdateQueryGroupRequest - * @param name - QueryGroup name for UpdateQueryGroupRequest - * @param resourceLimits - QueryGroup resourceLimits for UpdateQueryGroupRequest - * @param updatedAtInMillis - QueryGroup updated time in millis for UpdateQueryGroupRequest - */ - private void verifyUpdateQueryGroupRequest( - String name, - QueryGroupMode mode, - Map resourceLimits, - long updatedAtInMillis - ) { - Objects.requireNonNull(name, "QueryGroup.name can't be null"); - Objects.requireNonNull(resourceLimits, "QueryGroup.resourceLimits can't be null"); - Objects.requireNonNull(updatedAtInMillis, "QueryGroup.updatedAtInMillis can't be null"); - - validateName(name); - validateMode(mode); - validateResourceLimits(resourceLimits); - validateUpdatedAtInMillis(updatedAtInMillis); - } - - /** - * Verification for resourceLimits - * @param resourceLimits - QueryGroup resourceLimits for UpdateQueryGroupRequest - */ - public static void validateResourceLimits(Map resourceLimits) { - if (resourceLimits == null) return; - for (Map.Entry resource : resourceLimits.entrySet()) { - String resourceName = resource.getKey(); - Double threshold = (Double) resource.getValue(); - Objects.requireNonNull(resourceName, "resourceName can't be null"); - Objects.requireNonNull(threshold, "resource value can't be null"); - - if (threshold < 0 || threshold > 1) { - throw new IllegalArgumentException("Resource value should be between 0 and 1"); - } - String str = String.valueOf(threshold); - if (str.contains(".") && str.split("\\.")[1].length() > 2) { - throw new IllegalArgumentException("Resource value should have at most two digits after the decimal point"); - } - if (!ALLOWED_RESOURCES.contains(resourceName.toLowerCase(Locale.ROOT))) { - throw new IllegalArgumentException( - "resource has to be valid, valid resources are: " + ALLOWED_RESOURCES.stream().reduce((x, e) -> x + ", " + e).get() - ); - } - } - } - - @Override - public UpdateQueryGroupRequest read(StreamInput in) throws IOException { - return new UpdateQueryGroupRequest(in); - } - - /** - * Generate a UpdateQueryGroupRequest from XContent - * @param parser - A {@link XContentParser} object - * @param name - name of the QueryGroup to be updated - */ - public static UpdateQueryGroupRequest fromXContent(XContentParser parser, String name) throws IOException { - while (parser.currentToken() != XContentParser.Token.START_OBJECT) { - parser.nextToken(); - } - - if (parser.currentToken() != XContentParser.Token.START_OBJECT) { - throw new IllegalArgumentException("expected start object but got a " + parser.currentToken()); - } - - XContentParser.Token token; - String fieldName = ""; - QueryGroupMode mode = null; - long updatedAtInMillis = Instant.now().getMillis(); - - // Map to hold resources - final Map resourceLimits_ = new HashMap<>(); - while ((token = parser.nextToken()) != null) { - if (token == XContentParser.Token.FIELD_NAME) { - fieldName = parser.currentName(); - } else if (token.isValue()) { - if (fieldName.equals("mode")) { - mode = QueryGroupMode.fromName(parser.text()); - } else if (ALLOWED_RESOURCES.contains(fieldName)) { - resourceLimits_.put(fieldName, parser.doubleValue()); - } else { - throw new IllegalArgumentException("unrecognised [field=" + fieldName + " in QueryGroup"); - } - } - } - return new UpdateQueryGroupRequest(name, mode, resourceLimits_, updatedAtInMillis); - } - - @Override - public ActionRequestValidationException validate() { - return null; - } - - /** - * name getter - */ - public String getName() { - return name; - } - - /** - * name setter - * @param name - name to be set - */ - public void setName(String name) { - this.name = name; - } - - /** - * ResourceLimits getter - */ - public Map getResourceLimits() { - return resourceLimits; - } - - /** - * ResourceLimits setter - * @param resourceLimits - ResourceLimit to be set - */ - public void setResourceLimits(Map resourceLimits) { - this.resourceLimits = resourceLimits; - } - - /** - * Mode getter - */ - public QueryGroupMode getMode() { - return mode; - } - - /** - * Mode setter - * @param mode - mode to be set - */ - public void setMode(QueryGroupMode mode) { - this.mode = mode; - } - - /** - * updatedAtInMillis getter - */ - public long getUpdatedAtInMillis() { - return updatedAtInMillis; - } - - /** - * updatedAtInMillis setter - * @param updatedAtInMillis - updatedAtInMillis to be set - */ - public void setUpdatedAtInMillis(long updatedAtInMillis) { - this.updatedAtInMillis = updatedAtInMillis; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(name); - if (resourceLimits == null || resourceLimits.isEmpty()) { - out.writeBoolean(false); - } else { - out.writeBoolean(true); - out.writeMap(resourceLimits); - } - if (mode == null) { - out.writeBoolean(false); - } else { - out.writeBoolean(true); - out.writeString(mode.getName()); - } - out.writeLong(updatedAtInMillis); - } -} diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupResponse.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupResponse.java deleted file mode 100644 index 761a5cc187147..0000000000000 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/UpdateQueryGroupResponse.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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.cluster.metadata.QueryGroup; -import org.opensearch.core.action.ActionResponse; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.core.xcontent.ToXContentObject; -import org.opensearch.core.xcontent.XContentBuilder; - -import java.io.IOException; - -/** - * Response for the update API for QueryGroup - * - * @opensearch.internal - */ -public class UpdateQueryGroupResponse extends ActionResponse implements ToXContent, ToXContentObject { - private final QueryGroup queryGroup; - private RestStatus restStatus; - - /** - * Constructor for UpdateQueryGroupResponse - * @param queryGroup - The QueryGroup to be updated - */ - public UpdateQueryGroupResponse(final QueryGroup queryGroup, RestStatus restStatus) { - this.queryGroup = queryGroup; - this.restStatus = restStatus; - } - - /** - * Constructor for UpdateQueryGroupResponse - * @param in - A {@link StreamInput} object - */ - public UpdateQueryGroupResponse(StreamInput in) throws IOException { - queryGroup = new QueryGroup(in); - restStatus = RestStatus.readFrom(in); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - queryGroup.writeTo(out); - RestStatus.writeTo(out, restStatus); - } - - @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject(); - builder.field("name", queryGroup.getName()); - builder.field("mode", queryGroup.getMode().getName()); - builder.field("updatedAt", queryGroup.getUpdatedAtInMillis()); - builder.mapContents(queryGroup.getResourceLimits()); - builder.endObject(); - return builder; - } - - /** - * queryGroup getter - */ - public QueryGroup getQueryGroup() { - return queryGroup; - } - - /** - * restStatus getter - */ - public RestStatus getRestStatus() { - return restStatus; - } - - /** - * restStatus setter - * @param restStatus - A {@link RestStatus} object - */ - public void setRestStatus(RestStatus restStatus) { - this.restStatus = restStatus; - } -} 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 e08027a741ac5..065c2f3229d15 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 @@ -18,9 +18,6 @@ import org.opensearch.common.settings.SettingsFilter; import org.opensearch.core.action.ActionResponse; import org.opensearch.plugin.wlm.rest.RestCreateQueryGroupAction; -import org.opensearch.plugin.wlm.rest.RestDeleteQueryGroupAction; -import org.opensearch.plugin.wlm.rest.RestGetQueryGroupAction; -import org.opensearch.plugin.wlm.rest.RestUpdateQueryGroupAction; import org.opensearch.plugins.ActionPlugin; import org.opensearch.plugins.Plugin; import org.opensearch.rest.RestController; @@ -42,12 +39,7 @@ public WorkloadManagementPlugin() {} @Override public List> getActions() { - return List.of( - new ActionPlugin.ActionHandler<>(CreateQueryGroupAction.INSTANCE, TransportCreateQueryGroupAction.class), - new ActionPlugin.ActionHandler<>(GetQueryGroupAction.INSTANCE, TransportGetQueryGroupAction.class), - new ActionPlugin.ActionHandler<>(UpdateQueryGroupAction.INSTANCE, TransportUpdateQueryGroupAction.class), - new ActionPlugin.ActionHandler<>(DeleteQueryGroupAction.INSTANCE, TransportDeleteQueryGroupAction.class) - ); + return List.of(new ActionPlugin.ActionHandler<>(CreateQueryGroupAction.INSTANCE, TransportCreateQueryGroupAction.class)); } @Override @@ -60,12 +52,7 @@ public List getRestHandlers( IndexNameExpressionResolver indexNameExpressionResolver, Supplier nodesInCluster ) { - return List.of( - new RestCreateQueryGroupAction(), - new RestGetQueryGroupAction(), - new RestUpdateQueryGroupAction(), - new RestDeleteQueryGroupAction() - ); + return List.of(new RestCreateQueryGroupAction()); } @Override diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestDeleteQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestDeleteQueryGroupAction.java deleted file mode 100644 index e577defdfea13..0000000000000 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestDeleteQueryGroupAction.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.client.node.NodeClient; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.plugin.wlm.DeleteQueryGroupAction; -import org.opensearch.plugin.wlm.DeleteQueryGroupRequest; -import org.opensearch.plugin.wlm.DeleteQueryGroupResponse; -import org.opensearch.rest.BaseRestHandler; -import org.opensearch.rest.BytesRestResponse; -import org.opensearch.rest.RestChannel; -import org.opensearch.rest.RestRequest; -import org.opensearch.rest.RestResponse; -import org.opensearch.rest.action.RestResponseListener; - -import java.io.IOException; -import java.util.List; - -import static org.opensearch.rest.RestRequest.Method.DELETE; - -/** - * Rest action to delete a QueryGroup - * - * @opensearch.api - */ -public class RestDeleteQueryGroupAction extends BaseRestHandler { - - /** - * Constructor for RestDeleteQueryGroupAction - */ - public RestDeleteQueryGroupAction() {} - - @Override - public String getName() { - return "delete_query_group"; - } - - /** - * The list of {@link Route}s that this RestHandler is responsible for handling. - */ - @Override - public List routes() { - return List.of(new Route(DELETE, "_query_group/{name}"), new Route(DELETE, "_query_group/")); - } - - @Override - protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { - String name = request.param("name"); - DeleteQueryGroupRequest deleteQueryGroupRequest = new DeleteQueryGroupRequest(name); - return channel -> client.execute(DeleteQueryGroupAction.INSTANCE, deleteQueryGroupRequest, deleteQueryGroupResponse(channel)); - } - - private RestResponseListener deleteQueryGroupResponse(final RestChannel channel) { - return new RestResponseListener<>(channel) { - @Override - public RestResponse buildResponse(final DeleteQueryGroupResponse response) throws Exception { - return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS)); - } - }; - } -} diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestGetQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestGetQueryGroupAction.java deleted file mode 100644 index 1e1b3f4eff72e..0000000000000 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestGetQueryGroupAction.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.client.node.NodeClient; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.plugin.wlm.GetQueryGroupAction; -import org.opensearch.plugin.wlm.GetQueryGroupRequest; -import org.opensearch.plugin.wlm.GetQueryGroupResponse; -import org.opensearch.rest.BaseRestHandler; -import org.opensearch.rest.BytesRestResponse; -import org.opensearch.rest.RestChannel; -import org.opensearch.rest.RestRequest; -import org.opensearch.rest.RestResponse; -import org.opensearch.rest.action.RestResponseListener; - -import java.io.IOException; -import java.util.List; - -import static org.opensearch.rest.RestRequest.Method.GET; - -/** - * Rest action to get a QueryGroup0 - * - * @opensearch.api - */ -public class RestGetQueryGroupAction extends BaseRestHandler { - - /** - * Constructor for RestGetQueryGroupAction - */ - public RestGetQueryGroupAction() {} - - @Override - public String getName() { - return "get_query_group"; - } - - /** - * The list of {@link Route}s that this RestHandler is responsible for handling. - */ - @Override - public List routes() { - return List.of(new Route(GET, "_query_group/{name}"), new Route(GET, "_query_group/")); - } - - @Override - protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { - String name = request.param("name"); - GetQueryGroupRequest getQueryGroupRequest = new GetQueryGroupRequest(name); - return channel -> client.execute(GetQueryGroupAction.INSTANCE, getQueryGroupRequest, getQueryGroupResponse(channel)); - } - - private RestResponseListener getQueryGroupResponse(final RestChannel channel) { - return new RestResponseListener<>(channel) { - @Override - public RestResponse buildResponse(final GetQueryGroupResponse response) throws Exception { - return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS)); - } - }; - } -} diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestUpdateQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestUpdateQueryGroupAction.java deleted file mode 100644 index a369f9fe9edea..0000000000000 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestUpdateQueryGroupAction.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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.client.node.NodeClient; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.core.xcontent.XContentParser; -import org.opensearch.plugin.wlm.UpdateQueryGroupAction; -import org.opensearch.plugin.wlm.UpdateQueryGroupRequest; -import org.opensearch.plugin.wlm.UpdateQueryGroupResponse; -import org.opensearch.rest.BaseRestHandler; -import org.opensearch.rest.BytesRestResponse; -import org.opensearch.rest.RestChannel; -import org.opensearch.rest.RestRequest; -import org.opensearch.rest.RestResponse; -import org.opensearch.rest.action.RestResponseListener; - -import java.io.IOException; -import java.util.List; - -import static org.opensearch.rest.RestRequest.Method.POST; -import static org.opensearch.rest.RestRequest.Method.PUT; - -/** - * Rest action to update a QueryGroup - * - * @opensearch.api - */ -public class RestUpdateQueryGroupAction extends BaseRestHandler { - - /** - * Constructor for RestUpdateQueryGroupAction - */ - public RestUpdateQueryGroupAction() {} - - @Override - public String getName() { - return "update_query_group"; - } - - /** - * The list of {@link Route}s that this RestHandler is responsible for handling. - */ - @Override - public List routes() { - return List.of(new Route(POST, "_query_group/{name}"), new Route(PUT, "_query_group/{name}")); - } - - @Override - protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { - String name = request.param("name"); - UpdateQueryGroupRequest updateQueryGroupRequest = new UpdateQueryGroupRequest(); - request.applyContentParser((parser) -> parseRestRequest(updateQueryGroupRequest, parser, name)); - return channel -> client.execute(UpdateQueryGroupAction.INSTANCE, updateQueryGroupRequest, updateQueryGroupResponse(channel)); - } - - private void parseRestRequest(UpdateQueryGroupRequest request, XContentParser parser, String name) throws IOException { - final UpdateQueryGroupRequest updateQueryGroupRequest = UpdateQueryGroupRequest.fromXContent(parser, name); - request.setName(updateQueryGroupRequest.getName()); - request.setResourceLimits(updateQueryGroupRequest.getResourceLimits()); - request.setMode(updateQueryGroupRequest.getMode()); - request.setUpdatedAtInMillis(updateQueryGroupRequest.getUpdatedAtInMillis()); - } - - private RestResponseListener updateQueryGroupResponse(final RestChannel channel) { - return new RestResponseListener<>(channel) { - @Override - public RestResponse buildResponse(final UpdateQueryGroupResponse response) throws Exception { - return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS)); - } - }; - } -} diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/Persistable.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/Persistable.java index dc2cb5de2f9cd..37a6b4a58bc17 100644 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/Persistable.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/Persistable.java @@ -10,10 +10,6 @@ import org.opensearch.core.action.ActionListener; import org.opensearch.plugin.wlm.CreateQueryGroupResponse; -import org.opensearch.plugin.wlm.DeleteQueryGroupResponse; -import org.opensearch.plugin.wlm.GetQueryGroupResponse; -import org.opensearch.plugin.wlm.UpdateQueryGroupRequest; -import org.opensearch.plugin.wlm.UpdateQueryGroupResponse; /** * This interface defines the key APIs for implementing QueruGroup persistence @@ -26,25 +22,4 @@ public interface Persistable { * @param listener */ void persist(T queryGroup, ActionListener listener); - - /** - * update the QueryGroup in a durable storage - * @param updateQueryGroupRequest - * @param listener - */ - void update(UpdateQueryGroupRequest updateQueryGroupRequest, ActionListener listener); - - /** - * fetch the QueryGroup in a durable storage - * @param name - * @param listener - */ - void get(String name, ActionListener listener); - - /** - * delete the QueryGroup in a durable storage - * @param name - * @param listener - */ - void delete(String name, ActionListener listener); } diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceService.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceService.java index f88aad0a8f8f5..768dfcdd22fa1 100644 --- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceService.java +++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceService.java @@ -14,7 +14,6 @@ import org.opensearch.cluster.ClusterStateUpdateTask; import org.opensearch.cluster.metadata.Metadata; import org.opensearch.cluster.metadata.QueryGroup; -import org.opensearch.cluster.metadata.QueryGroup.QueryGroupMode; import org.opensearch.cluster.service.ClusterManagerTaskThrottler.ThrottlingKey; import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.Priority; @@ -24,14 +23,9 @@ import org.opensearch.core.action.ActionListener; import org.opensearch.core.rest.RestStatus; import org.opensearch.plugin.wlm.CreateQueryGroupResponse; -import org.opensearch.plugin.wlm.DeleteQueryGroupResponse; -import org.opensearch.plugin.wlm.GetQueryGroupResponse; -import org.opensearch.plugin.wlm.UpdateQueryGroupRequest; -import org.opensearch.plugin.wlm.UpdateQueryGroupResponse; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -98,30 +92,6 @@ public void persist(QueryGroup queryGroup, ActionListener listener) { - updateInClusterStateMetadata(updateQueryGroupRequest, listener); - } - - @Override - public void get(String name, ActionListener listener) { - ClusterState currentState = clusterService.state(); - List resultGroups = getFromClusterStateMetadata(name, currentState); - if (resultGroups.isEmpty() && name != null && !name.isEmpty()) { - logger.warn("No QueryGroup exists with the provided name: {}", name); - Exception e = new RuntimeException("No QueryGroup exists with the provided name: " + name); - listener.onFailure(e); - return; - } - GetQueryGroupResponse response = new GetQueryGroupResponse(resultGroups, RestStatus.OK); - listener.onResponse(response); - } - - @Override - public void delete(String name, ActionListener listener) { - deleteInClusterStateMetadata(name, listener); - } - /** * Update cluster state to include the new QueryGroup * @param queryGroup {@link QueryGroup} - the QueryGroup we're currently creating @@ -237,166 +207,6 @@ private double calculateExistingUsage(String resourceName, Set group return existingUsage; } - /** - * Modify cluster state to update the QueryGroup - * @param toUpdateGroup {@link QueryGroup} - the QueryGroup that we want to update - */ - void updateInClusterStateMetadata(UpdateQueryGroupRequest toUpdateGroup, ActionListener listener) { - clusterService.submitStateUpdateTask(SOURCE, new ClusterStateUpdateTask(Priority.URGENT) { - @Override - public ClusterState execute(ClusterState currentState) { - return updateQueryGroupInClusterState(toUpdateGroup, currentState); - } - - @Override - public ThrottlingKey getClusterManagerThrottlingKey() { - return updateQueryGroupThrottlingKey; - } - - @Override - public void onFailure(String source, Exception e) { - restoreInflightValues(toUpdateGroup.getResourceLimits()); - logger.warn("Failed to update QueryGroup due to error: {}, for source: {}", e.getMessage(), source); - listener.onFailure(e); - } - - @Override - public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { - restoreInflightValues(toUpdateGroup.getResourceLimits()); - String name = toUpdateGroup.getName(); - Optional findUpdatedGroup = newState.metadata() - .queryGroups() - .stream() - .filter(group -> group.getName().equals(name)) - .findFirst(); - assert findUpdatedGroup.isPresent(); - QueryGroup updatedGroup = findUpdatedGroup.get(); - UpdateQueryGroupResponse response = new UpdateQueryGroupResponse(updatedGroup, RestStatus.OK); - listener.onResponse(response); - } - }); - } - - /** - * Modify cluster state to update the existing QueryGroup - * @param updateQueryGroupRequest {@link QueryGroup} - the QueryGroup that we want to update - * @param currentState - current cluster state - */ - public ClusterState updateQueryGroupInClusterState(UpdateQueryGroupRequest updateQueryGroupRequest, ClusterState currentState) { - final Metadata metadata = currentState.metadata(); - Set existingGroups = currentState.metadata().queryGroups(); - String name = updateQueryGroupRequest.getName(); - String resourceNameWithThresholdExceeded = ""; - - // check if there's any resource allocation that exceed limit of 1.0 - if (updateQueryGroupRequest.getResourceLimits() != null) { - for (String resourceName : updateQueryGroupRequest.getResourceLimits().keySet()) { - double existingUsage = calculateExistingUsage(resourceName, existingGroups, name); - double newGroupUsage = getResourceLimitValue(resourceName, updateQueryGroupRequest.getResourceLimits()); - inflightResourceLimitValues.computeIfAbsent(resourceName, k -> new DoubleAdder()).add(newGroupUsage); - double totalUsage = existingUsage + inflightResourceLimitValues.get(resourceName).doubleValue(); - if (totalUsage > 1) { - resourceNameWithThresholdExceeded = resourceName; - } - } - } - - Optional findExistingGroup = existingGroups.stream().filter(group -> group.getName().equals(name)).findFirst(); - - if (findExistingGroup.isEmpty()) { - logger.warn("No QueryGroup exists with the provided name: {}", name); - throw new RuntimeException("No QueryGroup exists with the provided name: " + name); - } - if (!resourceNameWithThresholdExceeded.isEmpty()) { - logger.error("Total resource allocation for {} will go above the max limit of 1.0", resourceNameWithThresholdExceeded); - throw new RuntimeException( - "Total resource allocation for " + resourceNameWithThresholdExceeded + " will go above the max limit of 1.0" - ); - } - - // build the QueryGroup with updated fields - QueryGroup existingGroup = findExistingGroup.get(); - String _id = existingGroup.get_id(); - long updatedAtInMillis = updateQueryGroupRequest.getUpdatedAtInMillis(); - Map existingResourceLimits = existingGroup.getResourceLimits(); - Map updatedResourceLimits = new HashMap<>(); - if (existingResourceLimits != null) { - updatedResourceLimits.putAll(existingResourceLimits); - } - if (updateQueryGroupRequest.getResourceLimits() != null) { - updatedResourceLimits.putAll(updateQueryGroupRequest.getResourceLimits()); - } - QueryGroupMode mode = updateQueryGroupRequest.getMode() == null ? existingGroup.getMode() : updateQueryGroupRequest.getMode(); - - QueryGroup updatedGroup = new QueryGroup(name, _id, mode, updatedResourceLimits, updatedAtInMillis); - return ClusterState.builder(currentState) - .metadata(Metadata.builder(metadata).remove(existingGroup).put(updatedGroup).build()) - .build(); - } - - /** - * Modify cluster state to delete the QueryGroup - * @param name - the name for QueryGroup to be deleted - */ - void deleteInClusterStateMetadata(String name, ActionListener listener) { - clusterService.submitStateUpdateTask(SOURCE, new ClusterStateUpdateTask(Priority.URGENT) { - @Override - public ClusterState execute(ClusterState currentState) throws Exception { - return deleteQueryGroupInClusterState(name, currentState); - } - - @Override - public ThrottlingKey getClusterManagerThrottlingKey() { - return deleteQueryGroupThrottlingKey; - } - - @Override - public void onFailure(String source, Exception e) { - logger.warn("Failed to delete QueryGroup due to error: {}, for source: {}", e.getMessage(), source); - listener.onFailure(e); - } - - @Override - public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { - final Set oldGroupsMap = oldState.metadata().queryGroups(); - final Set newGroupsMap = newState.metadata().queryGroups(); - List deletedGroups = new ArrayList<>(); - for (QueryGroup group : oldGroupsMap) { - if (!newGroupsMap.contains(group)) { - deletedGroups.add(group); - } - } - DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(deletedGroups, RestStatus.OK); - listener.onResponse(response); - } - }); - } - - /** - * Modify cluster state to delete the QueryGroup - * @param name - the name for QueryGroup to be deleted - * @param currentClusterState - current cluster state - */ - ClusterState deleteQueryGroupInClusterState(final String name, final ClusterState currentClusterState) { - final Metadata metadata = currentClusterState.metadata(); - final Set previousGroups = metadata.queryGroups(); - - if (name == null || name.isEmpty()) { // delete all - return ClusterState.builder(currentClusterState) - .metadata(Metadata.builder(metadata).queryGroups(new HashSet<>()).build()) - .build(); - } else { - Optional findExistingGroup = previousGroups.stream().filter(group -> group.getName().equals(name)).findFirst(); - if (findExistingGroup.isEmpty()) { - logger.error("The QueryGroup with provided name {} doesn't exist", name); - throw new RuntimeException("No QueryGroup exists with the provided name: " + name); - } - return ClusterState.builder(currentClusterState) - .metadata(Metadata.builder(metadata).remove(findExistingGroup.get()).build()) - .build(); - } - } - List getFromClusterStateMetadata(String name, ClusterState currentState) { Set currentGroups = currentState.getMetadata().queryGroups(); List resultGroups = new ArrayList<>(); diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/DeleteQueryGroupRequestTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/DeleteQueryGroupRequestTests.java deleted file mode 100644 index ae78f2bae9d2f..0000000000000 --- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/DeleteQueryGroupRequestTests.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.io.stream.BytesStreamOutput; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.test.OpenSearchTestCase; - -import java.io.IOException; - -public class DeleteQueryGroupRequestTests extends OpenSearchTestCase { - - public void testSerialization() throws IOException { - DeleteQueryGroupRequest request = new DeleteQueryGroupRequest(QueryGroupTestUtils.NAME_ONE); - assertEquals(QueryGroupTestUtils.NAME_ONE, request.getName()); - BytesStreamOutput out = new BytesStreamOutput(); - request.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - DeleteQueryGroupRequest otherRequest = new DeleteQueryGroupRequest(streamInput); - assertEquals(request.getName(), otherRequest.getName()); - } - - public void testSerializationWithNull() throws IOException { - DeleteQueryGroupRequest request = new DeleteQueryGroupRequest((String) null); - assertNull(request.getName()); - BytesStreamOutput out = new BytesStreamOutput(); - request.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - DeleteQueryGroupRequest otherRequest = new DeleteQueryGroupRequest(streamInput); - assertEquals(request.getName(), otherRequest.getName()); - } -} diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/DeleteQueryGroupResponseTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/DeleteQueryGroupResponseTests.java deleted file mode 100644 index af3cb7ea356ea..0000000000000 --- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/DeleteQueryGroupResponseTests.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.cluster.metadata.QueryGroup; -import org.opensearch.common.io.stream.BytesStreamOutput; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.test.OpenSearchTestCase; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import static org.opensearch.plugin.wlm.QueryGroupTestUtils.compareQueryGroups; -import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupList; -import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupOne; - -public class DeleteQueryGroupResponseTests extends OpenSearchTestCase { - - public void testSerializationSingleQueryGroup() throws IOException { - List list = List.of(queryGroupOne); - DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(list, RestStatus.OK); - assertEquals(response.getQueryGroups(), list); - - BytesStreamOutput out = new BytesStreamOutput(); - response.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - - DeleteQueryGroupResponse otherResponse = new DeleteQueryGroupResponse(streamInput); - assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); - compareQueryGroups(response.getQueryGroups(), otherResponse.getQueryGroups()); - } - - public void testSerializationMultipleQueryGroup() throws IOException { - DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(queryGroupList(), RestStatus.OK); - assertEquals(response.getQueryGroups(), queryGroupList()); - - BytesStreamOutput out = new BytesStreamOutput(); - response.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - - DeleteQueryGroupResponse otherResponse = new DeleteQueryGroupResponse(streamInput); - assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); - assertEquals(2, otherResponse.getQueryGroups().size()); - compareQueryGroups(response.getQueryGroups(), otherResponse.getQueryGroups()); - } - - public void testSerializationNull() throws IOException { - List list = new ArrayList<>(); - DeleteQueryGroupResponse response = new DeleteQueryGroupResponse(list, RestStatus.OK); - assertEquals(response.getQueryGroups(), list); - - BytesStreamOutput out = new BytesStreamOutput(); - response.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - - DeleteQueryGroupResponse otherResponse = new DeleteQueryGroupResponse(streamInput); - assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); - assertEquals(0, otherResponse.getQueryGroups().size()); - } -} diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/GetQueryGroupRequestTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/GetQueryGroupRequestTests.java deleted file mode 100644 index a3f3083cce1e9..0000000000000 --- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/GetQueryGroupRequestTests.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.io.stream.BytesStreamOutput; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.test.OpenSearchTestCase; - -import java.io.IOException; - -public class GetQueryGroupRequestTests extends OpenSearchTestCase { - - public void testSerialization() throws IOException { - GetQueryGroupRequest request = new GetQueryGroupRequest(QueryGroupTestUtils.NAME_ONE); - assertEquals(QueryGroupTestUtils.NAME_ONE, request.getName()); - BytesStreamOutput out = new BytesStreamOutput(); - request.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - GetQueryGroupRequest otherRequest = new GetQueryGroupRequest(streamInput); - assertEquals(request.getName(), otherRequest.getName()); - } - - public void testSerializationWithNull() throws IOException { - GetQueryGroupRequest request = new GetQueryGroupRequest((String) null); - assertNull(request.getName()); - BytesStreamOutput out = new BytesStreamOutput(); - request.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - GetQueryGroupRequest otherRequest = new GetQueryGroupRequest(streamInput); - assertEquals(request.getName(), otherRequest.getName()); - } -} diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/GetQueryGroupResponseTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/GetQueryGroupResponseTests.java deleted file mode 100644 index f9332df71a9b7..0000000000000 --- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/GetQueryGroupResponseTests.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.cluster.metadata.QueryGroup; -import org.opensearch.common.io.stream.BytesStreamOutput; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.test.OpenSearchTestCase; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -public class GetQueryGroupResponseTests extends OpenSearchTestCase { - - public void testSerializationSingleQueryGroup() throws IOException { - List list = new ArrayList<>(); - list.add(QueryGroupTestUtils.queryGroupOne); - GetQueryGroupResponse response = new GetQueryGroupResponse(list, RestStatus.OK); - assertEquals(response.getQueryGroups(), list); - - BytesStreamOutput out = new BytesStreamOutput(); - response.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - - GetQueryGroupResponse otherResponse = new GetQueryGroupResponse(streamInput); - assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); - QueryGroupTestUtils.compareQueryGroups(response.getQueryGroups(), otherResponse.getQueryGroups()); - } - - public void testSerializationMultipleQueryGroup() throws IOException { - GetQueryGroupResponse response = new GetQueryGroupResponse(QueryGroupTestUtils.queryGroupList(), RestStatus.OK); - assertEquals(response.getQueryGroups(), QueryGroupTestUtils.queryGroupList()); - - BytesStreamOutput out = new BytesStreamOutput(); - response.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - - GetQueryGroupResponse otherResponse = new GetQueryGroupResponse(streamInput); - assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); - assertEquals(2, otherResponse.getQueryGroups().size()); - QueryGroupTestUtils.compareQueryGroups(response.getQueryGroups(), otherResponse.getQueryGroups()); - } - - public void testSerializationNull() throws IOException { - List list = new ArrayList<>(); - GetQueryGroupResponse response = new GetQueryGroupResponse(list, RestStatus.OK); - assertEquals(response.getQueryGroups(), list); - - BytesStreamOutput out = new BytesStreamOutput(); - response.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - - GetQueryGroupResponse otherResponse = new GetQueryGroupResponse(streamInput); - assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); - assertEquals(0, otherResponse.getQueryGroups().size()); - } -} diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/UpdateQueryGroupRequestTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/UpdateQueryGroupRequestTests.java deleted file mode 100644 index 888a7c632d9cb..0000000000000 --- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/UpdateQueryGroupRequestTests.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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.cluster.metadata.QueryGroup; -import org.opensearch.common.io.stream.BytesStreamOutput; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.test.OpenSearchTestCase; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import static org.opensearch.plugin.wlm.QueryGroupTestUtils.MONITOR; -import static org.opensearch.plugin.wlm.QueryGroupTestUtils.NAME_ONE; -import static org.opensearch.plugin.wlm.QueryGroupTestUtils.TIMESTAMP_ONE; -import static org.opensearch.plugin.wlm.QueryGroupTestUtils.compareResourceLimits; -import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupOne; - -public class UpdateQueryGroupRequestTests extends OpenSearchTestCase { - - public void testSerialization() throws IOException { - UpdateQueryGroupRequest request = new UpdateQueryGroupRequest(queryGroupOne); - BytesStreamOutput out = new BytesStreamOutput(); - request.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - UpdateQueryGroupRequest otherRequest = new UpdateQueryGroupRequest(streamInput); - assertEquals(request.getName(), otherRequest.getName()); - assertEquals(request.getResourceLimits().size(), otherRequest.getResourceLimits().size()); - assertEquals(request.getMode(), otherRequest.getMode()); - compareResourceLimits(request.getResourceLimits(), otherRequest.getResourceLimits()); - assertEquals(request.getUpdatedAtInMillis(), otherRequest.getUpdatedAtInMillis()); - } - - public void testSerializationOnlyName() throws IOException { - UpdateQueryGroupRequest request = new UpdateQueryGroupRequest(NAME_ONE, null, new HashMap<>(), TIMESTAMP_ONE); - BytesStreamOutput out = new BytesStreamOutput(); - request.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - UpdateQueryGroupRequest otherRequest = new UpdateQueryGroupRequest(streamInput); - assertEquals(request.getName(), otherRequest.getName()); - assertEquals(request.getResourceLimits(), otherRequest.getResourceLimits()); - assertEquals(request.getMode(), otherRequest.getMode()); - assertEquals(request.getUpdatedAtInMillis(), otherRequest.getUpdatedAtInMillis()); - } - - public void testSerializationOnlyResourceLimit() throws IOException { - UpdateQueryGroupRequest request = new UpdateQueryGroupRequest(NAME_ONE, null, Map.of("jvm", 0.4), TIMESTAMP_ONE); - BytesStreamOutput out = new BytesStreamOutput(); - request.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - UpdateQueryGroupRequest otherRequest = new UpdateQueryGroupRequest(streamInput); - assertEquals(request.getName(), otherRequest.getName()); - assertEquals(request.getResourceLimits().size(), otherRequest.getResourceLimits().size()); - compareResourceLimits(request.getResourceLimits(), otherRequest.getResourceLimits()); - assertEquals(request.getMode(), otherRequest.getMode()); - assertEquals(request.getUpdatedAtInMillis(), otherRequest.getUpdatedAtInMillis()); - } - - public void testInvalidName() { - assertThrows( - IllegalArgumentException.class, - () -> new UpdateQueryGroupRequest("", QueryGroup.QueryGroupMode.fromName(MONITOR), Map.of("jvm", 0.3), TIMESTAMP_ONE) - ); - assertThrows( - IllegalArgumentException.class, - () -> new UpdateQueryGroupRequest("-test", QueryGroup.QueryGroupMode.fromName(MONITOR), Map.of("jvm", 0.3), TIMESTAMP_ONE) - ); - assertThrows( - IllegalArgumentException.class, - () -> new UpdateQueryGroupRequest(":test", QueryGroup.QueryGroupMode.fromName(MONITOR), Map.of("jvm", 0.3), TIMESTAMP_ONE) - ); - } - - public void testInvalidResourceLimitList() { - assertThrows( - NullPointerException.class, - () -> new UpdateQueryGroupRequest(NAME_ONE, QueryGroup.QueryGroupMode.fromName(MONITOR), null, TIMESTAMP_ONE) - ); - - assertThrows( - IllegalArgumentException.class, - () -> new UpdateQueryGroupRequest( - NAME_ONE, - QueryGroup.QueryGroupMode.fromName(MONITOR), - Map.of("jvm", 0.3, "jvm", 0.4), - TIMESTAMP_ONE - ) - ); - - assertThrows( - IllegalArgumentException.class, - () -> new UpdateQueryGroupRequest(NAME_ONE, QueryGroup.QueryGroupMode.fromName(MONITOR), Map.of("jvm", -0.3), TIMESTAMP_ONE) - ); - - assertThrows( - IllegalArgumentException.class, - () -> new UpdateQueryGroupRequest(NAME_ONE, QueryGroup.QueryGroupMode.fromName(MONITOR), Map.of("jvm", 12.0), TIMESTAMP_ONE) - ); - - assertThrows( - IllegalArgumentException.class, - () -> new UpdateQueryGroupRequest(NAME_ONE, QueryGroup.QueryGroupMode.fromName(MONITOR), Map.of("cpu", 0.3), TIMESTAMP_ONE) - ); - } - - public void testInvalidEnforcement() { - assertThrows( - IllegalArgumentException.class, - () -> new UpdateQueryGroupRequest(NAME_ONE, QueryGroup.QueryGroupMode.fromName("random"), Map.of("jvm", 0.3), TIMESTAMP_ONE) - ); - } -} diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/UpdateQueryGroupResponseTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/UpdateQueryGroupResponseTests.java deleted file mode 100644 index 6e744427629fd..0000000000000 --- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/UpdateQueryGroupResponseTests.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.cluster.metadata.QueryGroup; -import org.opensearch.common.io.stream.BytesStreamOutput; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.test.OpenSearchTestCase; - -import java.io.IOException; -import java.util.List; - -public class UpdateQueryGroupResponseTests extends OpenSearchTestCase { - - public void testSerialization() throws IOException { - UpdateQueryGroupResponse response = new UpdateQueryGroupResponse(QueryGroupTestUtils.queryGroupOne, RestStatus.OK); - BytesStreamOutput out = new BytesStreamOutput(); - response.writeTo(out); - StreamInput streamInput = out.bytes().streamInput(); - UpdateQueryGroupResponse otherResponse = new UpdateQueryGroupResponse(streamInput); - assertEquals(response.getRestStatus(), otherResponse.getRestStatus()); - QueryGroup responseGroup = response.getQueryGroup(); - QueryGroup otherResponseGroup = otherResponse.getQueryGroup(); - QueryGroupTestUtils.compareQueryGroups(List.of(responseGroup), List.of(otherResponseGroup)); - } -} diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceServiceTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceServiceTests.java index 1e6ef3f114d3f..0f5e20f9b9474 100644 --- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceServiceTests.java +++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceServiceTests.java @@ -12,11 +12,9 @@ import org.opensearch.cluster.ClusterState; import org.opensearch.cluster.metadata.Metadata; import org.opensearch.cluster.metadata.QueryGroup; -import org.opensearch.cluster.metadata.QueryGroup.QueryGroupMode; import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.settings.ClusterSettings; import org.opensearch.common.settings.Settings; -import org.opensearch.plugin.wlm.UpdateQueryGroupRequest; import org.opensearch.test.OpenSearchTestCase; import org.opensearch.threadpool.ThreadPool; @@ -26,7 +24,6 @@ import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.stream.Collectors; import static org.opensearch.cluster.metadata.QueryGroup.builder; import static org.opensearch.plugin.wlm.QueryGroupTestUtils.MONITOR; @@ -34,13 +31,10 @@ import static org.opensearch.plugin.wlm.QueryGroupTestUtils.NAME_ONE; import static org.opensearch.plugin.wlm.QueryGroupTestUtils.NAME_TWO; import static org.opensearch.plugin.wlm.QueryGroupTestUtils.SANDBOX_MAX_SETTING_NAME; -import static org.opensearch.plugin.wlm.QueryGroupTestUtils._ID_ONE; import static org.opensearch.plugin.wlm.QueryGroupTestUtils.assertInflightValuesAreZero; -import static org.opensearch.plugin.wlm.QueryGroupTestUtils.clusterState; import static org.opensearch.plugin.wlm.QueryGroupTestUtils.compareQueryGroups; import static org.opensearch.plugin.wlm.QueryGroupTestUtils.prepareSandboxPersistenceService; import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupList; -import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupMap; import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupOne; import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupPersistenceService; import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupTwo; @@ -48,119 +42,6 @@ public class QueryGroupPersistenceServiceTests extends OpenSearchTestCase { - public void testGetSingleQueryGroup() { - List groups = queryGroupPersistenceService().getFromClusterStateMetadata(NAME_ONE, clusterState()); - assertEquals(1, groups.size()); - QueryGroup queryGroup = groups.get(0); - compareQueryGroups(List.of(queryGroupOne), List.of(queryGroup)); - assertInflightValuesAreZero(queryGroupPersistenceService()); - } - - public void testGetAllQueryGroups() { - assertEquals(2, clusterState().metadata().queryGroups().size()); - List res = queryGroupPersistenceService().getFromClusterStateMetadata(null, clusterState()); - assertEquals(2, res.size()); - Set currentNAME = res.stream().map(QueryGroup::getName).collect(Collectors.toSet()); - assertTrue(currentNAME.contains(NAME_ONE)); - assertTrue(currentNAME.contains(NAME_TWO)); - compareQueryGroups(queryGroupList(), res); - assertInflightValuesAreZero(queryGroupPersistenceService()); - } - - public void testGetZeroQueryGroups() { - Settings settings = Settings.builder().build(); - ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - QueryGroupPersistenceService sandboxPersistenceService = new QueryGroupPersistenceService( - mock(ClusterService.class), - settings, - clusterSettings - ); - List res = sandboxPersistenceService.getFromClusterStateMetadata(NAME_NONE_EXISTED, clusterState()); - assertEquals(0, res.size()); - assertInflightValuesAreZero(queryGroupPersistenceService()); - } - - public void testDeleteSingleQueryGroup() { - ClusterState newClusterState = queryGroupPersistenceService().deleteQueryGroupInClusterState(NAME_TWO, clusterState()); - Set afterDeletionGroups = newClusterState.getMetadata().queryGroups(); - assertEquals(1, afterDeletionGroups.size()); - List oldSandbox = List.of(queryGroupMap.get(NAME_ONE)); - compareQueryGroups(new ArrayList<>(afterDeletionGroups), oldSandbox); - assertInflightValuesAreZero(queryGroupPersistenceService()); - } - - public void testDeleteAllQueryGroups() { - ClusterState newClusterState = queryGroupPersistenceService().deleteQueryGroupInClusterState(null, clusterState()); - Set afterDeletionGroups = newClusterState.getMetadata().queryGroups(); - assertEquals(0, afterDeletionGroups.size()); - assertInflightValuesAreZero(queryGroupPersistenceService()); - } - - public void testDeleteNonExistedQueryGroup() { - assertThrows( - RuntimeException.class, - () -> queryGroupPersistenceService().deleteQueryGroupInClusterState(NAME_NONE_EXISTED, clusterState()) - ); - } - - public void testUpdateQueryGroupAllFields() { - QueryGroup updated = builder().name(NAME_ONE) - ._id(_ID_ONE) - .mode(MONITOR) - .resourceLimits(Map.of("jvm", 0.15)) - .updatedAt(1690934400000L) - .build(); - UpdateQueryGroupRequest updateQueryGroupRequest = new UpdateQueryGroupRequest( - NAME_ONE, - QueryGroupMode.fromName(MONITOR), - Map.of("jvm", 0.15), - 1690934400000L - ); - ClusterState newClusterState = queryGroupPersistenceService().updateQueryGroupInClusterState( - updateQueryGroupRequest, - clusterState() - ); - List updatedSandboxes = new ArrayList<>(newClusterState.getMetadata().queryGroups()); - assertEquals(2, updatedSandboxes.size()); - compareQueryGroups(List.of(queryGroupTwo, updated), updatedSandboxes); - assertInflightValuesAreZero(queryGroupPersistenceService()); - } - - public void testUpdateQueryGroupResourceLimitsOnly() { - QueryGroup updated = builder().name(NAME_ONE) - ._id(_ID_ONE) - .mode(MONITOR) - .resourceLimits(Map.of("jvm", 0.15)) - .updatedAt(1690934400000L) - .build(); - UpdateQueryGroupRequest updateQueryGroupRequest = new UpdateQueryGroupRequest( - NAME_ONE, - QueryGroupMode.fromName(MONITOR), - Map.of("jvm", 0.15), - 1690934400000L - ); - ClusterState newClusterState = queryGroupPersistenceService().updateQueryGroupInClusterState( - updateQueryGroupRequest, - clusterState() - ); - Set updatedSandboxesMap = newClusterState.getMetadata().queryGroups(); - assertEquals(2, updatedSandboxesMap.size()); - Optional findUpdatedGroupOne = newClusterState.metadata() - .queryGroups() - .stream() - .filter(group -> group.getName().equals(NAME_ONE)) - .findFirst(); - Optional findUpdatedGroupTwo = newClusterState.metadata() - .queryGroups() - .stream() - .filter(group -> group.getName().equals(NAME_TWO)) - .findFirst(); - assertTrue(findUpdatedGroupOne.isPresent()); - assertTrue(findUpdatedGroupTwo.isPresent()); - compareQueryGroups(List.of(updated), List.of(findUpdatedGroupOne.get())); - assertInflightValuesAreZero(queryGroupPersistenceService()); - } - public void testCreateQueryGroup() { List setup = prepareSandboxPersistenceService(new ArrayList<>()); QueryGroupPersistenceService queryGroupPersistenceService1 = (QueryGroupPersistenceService) setup.get(0); From cb836d72bda6c1b286b527ca8ecc7f971e12101d Mon Sep 17 00:00:00 2001 From: Ruirui Zhang Date: Wed, 19 Jun 2024 12:11:29 -0700 Subject: [PATCH 15/15] modify CHANGELOG-3.0.md Signed-off-by: Ruirui Zhang --- CHANGELOG-3.0.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG-3.0.md b/CHANGELOG-3.0.md index e6d89b2930ff8..cd899bec28525 100644 --- a/CHANGELOG-3.0.md +++ b/CHANGELOG-3.0.md @@ -25,6 +25,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Deprecate CamelCase `PathHierarchy` tokenizer name in favor to lowercase `path_hierarchy` ([#10894](https://github.com/opensearch-project/OpenSearch/pull/10894)) - Breaking change: Do not request "search_pipelines" metrics by default in NodesInfoRequest ([#12497](https://github.com/opensearch-project/OpenSearch/pull/12497)) - [QueryGroup] Add QueryGroup CRUD APIs ([#13315](https://github.com/opensearch-project/OpenSearch/pull/13315)) +- [QueryGroup] Add QueryGroup Create API ([#14459](https://github.com/opensearch-project/OpenSearch/pull/14459)) ### Deprecated