From 270d409922a5c906ecb5a883606214cfeaf5bb52 Mon Sep 17 00:00:00 2001 From: Kaushal Kumar Date: Mon, 1 Apr 2024 17:05:03 -0700 Subject: [PATCH 1/3] add QSB framework related changes Signed-off-by: Kaushal Kumar --- .../action/search/FetchSearchPhase.java | 3 + .../SearchQueryThenFetchAsyncAction.java | 1 + .../action/search/SearchShardTask.java | 12 +- .../opensearch/action/search/SearchTask.java | 12 +- .../action/search/TransportSearchAction.java | 9 ++ .../common/settings/ClusterSettings.java | 8 +- .../org/opensearch/search/SearchService.java | 5 + .../search/internal/ShardSearchRequest.java | 17 ++ .../search/sandbox/Persistable.java | 23 +++ .../search/sandbox/QuerySandboxService.java | 70 +++++++++ .../sandbox/QuerySandboxServiceSettings.java | 102 ++++++++++++ .../sandbox/RequestAttributeExtractor.java | 27 ++++ .../sandbox/RequestSandboxClassifier.java | 27 ++++ .../sandbox/SandboxResourceTracker.java | 16 ++ .../search/sandbox/SandboxStatsHolder.java | 2 + .../search/sandbox/SandboxStatsReporter.java | 13 ++ .../SandboxedRequestTrackerService.java | 145 ++++++++++++++++++ .../sandbox/matcher/SandboxMatchScorer.java | 18 +++ .../sandbox/matcher/StringMatchScorer.java | 16 ++ .../search/sandbox/matcher/package-info.java | 13 ++ .../org/opensearch/tasks/SandboxableTask.java | 18 +++ 21 files changed, 554 insertions(+), 3 deletions(-) create mode 100644 server/src/main/java/org/opensearch/search/sandbox/Persistable.java 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/RequestAttributeExtractor.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/RequestSandboxClassifier.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/SandboxResourceTracker.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/SandboxStatsHolder.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/SandboxStatsReporter.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/SandboxedRequestTrackerService.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/matcher/SandboxMatchScorer.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/matcher/StringMatchScorer.java create mode 100644 server/src/main/java/org/opensearch/search/sandbox/matcher/package-info.java create mode 100644 server/src/main/java/org/opensearch/tasks/SandboxableTask.java diff --git a/server/src/main/java/org/opensearch/action/search/FetchSearchPhase.java b/server/src/main/java/org/opensearch/action/search/FetchSearchPhase.java index ebb2f33f8f37d..fa5b75d0c6a1a 100644 --- a/server/src/main/java/org/opensearch/action/search/FetchSearchPhase.java +++ b/server/src/main/java/org/opensearch/action/search/FetchSearchPhase.java @@ -194,6 +194,9 @@ private void innerRun() throws Exception { queryResult.getShardSearchRequest(), queryResult.getRescoreDocIds() ); + // set sandboxId in shard level fetch request + assert context.getTask().getSandboxId() != null : "Search task should have the sandboxId"; + fetchSearchRequest.setSandboxId(context.getTask().getSandboxId()); executeFetch(i, searchShardTarget, counter, fetchSearchRequest, queryResult.queryResult(), connection); } } diff --git a/server/src/main/java/org/opensearch/action/search/SearchQueryThenFetchAsyncAction.java b/server/src/main/java/org/opensearch/action/search/SearchQueryThenFetchAsyncAction.java index c26bd5eef8c15..e03b80d8ffa93 100644 --- a/server/src/main/java/org/opensearch/action/search/SearchQueryThenFetchAsyncAction.java +++ b/server/src/main/java/org/opensearch/action/search/SearchQueryThenFetchAsyncAction.java @@ -132,6 +132,7 @@ protected void executePhaseOnShard( if (request != null) { request.setInboundNetworkTime(System.currentTimeMillis()); } + request.setSandboxId(getTask().getSandboxId()); getSearchTransport().sendExecuteQuery(getConnection(shard.getClusterAlias(), shard.getNodeId()), request, getTask(), listener); } 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..f4111f4370874 100644 --- a/server/src/main/java/org/opensearch/action/search/SearchShardTask.java +++ b/server/src/main/java/org/opensearch/action/search/SearchShardTask.java @@ -38,6 +38,7 @@ import org.opensearch.search.fetch.ShardFetchSearchRequest; import org.opensearch.search.internal.ShardSearchRequest; import org.opensearch.tasks.CancellableTask; +import org.opensearch.tasks.SandboxableTask; import org.opensearch.tasks.SearchBackpressureTask; import java.util.Map; @@ -50,9 +51,10 @@ * @opensearch.api */ @PublicApi(since = "1.0.0") -public class SearchShardTask extends CancellableTask implements SearchBackpressureTask { +public class SearchShardTask extends CancellableTask implements SearchBackpressureTask, SandboxableTask { // generating metadata in a lazy way since source can be quite big private final MemoizedSupplier metadataSupplier; + private String sandboxId; public SearchShardTask(long id, String type, String action, String description, TaskId parentTaskId, Map headers) { this(id, type, action, description, parentTaskId, headers, () -> ""); @@ -75,6 +77,14 @@ public String getTaskMetadata() { return metadataSupplier.get(); } + public String getSandboxId() { + return sandboxId; + } + + public void setSandboxId(String sandboxId) { + this.sandboxId = sandboxId; + } + @Override public boolean supportsResourceTracking() { return true; 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..480f36b4b1a1d 100644 --- a/server/src/main/java/org/opensearch/action/search/SearchTask.java +++ b/server/src/main/java/org/opensearch/action/search/SearchTask.java @@ -36,6 +36,7 @@ import org.opensearch.common.unit.TimeValue; import org.opensearch.core.tasks.TaskId; import org.opensearch.tasks.CancellableTask; +import org.opensearch.tasks.SandboxableTask; import org.opensearch.tasks.SearchBackpressureTask; import java.util.Map; @@ -49,10 +50,11 @@ * @opensearch.api */ @PublicApi(since = "1.0.0") -public class SearchTask extends CancellableTask implements SearchBackpressureTask { +public class SearchTask extends CancellableTask implements SearchBackpressureTask, SandboxableTask { // generating description in a lazy way since source can be quite big private final Supplier descriptionSupplier; private SearchProgressListener progressListener = SearchProgressListener.NOOP; + private String sandboxId; public SearchTask( long id, @@ -95,6 +97,14 @@ public final void setProgressListener(SearchProgressListener progressListener) { this.progressListener = progressListener; } + public String getSandboxId() { + return sandboxId; + } + + public void setSandboxId(String sandboxId) { + this.sandboxId = sandboxId; + } + /** * Return the {@link SearchProgressListener} attached to this task. */ 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 05f4308df74fa..27629a5527e04 100644 --- a/server/src/main/java/org/opensearch/action/search/TransportSearchAction.java +++ b/server/src/main/java/org/opensearch/action/search/TransportSearchAction.java @@ -85,6 +85,7 @@ import org.opensearch.search.pipeline.SearchPipelineService; import org.opensearch.search.profile.ProfileShardResult; import org.opensearch.search.profile.SearchProfileShardResults; +import org.opensearch.search.sandbox.RequestSandboxClassifier; import org.opensearch.tasks.CancellableTask; import org.opensearch.tasks.Task; import org.opensearch.telemetry.metrics.MetricsRegistry; @@ -193,6 +194,8 @@ public class TransportSearchAction extends HandledTransportAction listener ) { final IndexShard shard = getShard(request); + task.setSandboxId(request.getSandboxId()); rewriteAndFetchShardRequest(shard, request, new ActionListener() { @Override public void onResponse(ShardSearchRequest rewritten) { @@ -556,6 +557,7 @@ public void executeQueryPhase( assert request.canReturnNullResponseIfMatchNoDocs() == false || request.numberOfShards() > 1 : "empty responses require more than one shard"; final IndexShard shard = getShard(request); + task.setSandboxId(request.getSandboxId()); rewriteAndFetchShardRequest(shard, request, new ActionListener() { @Override public void onResponse(ShardSearchRequest orig) { @@ -663,6 +665,7 @@ public void executeQueryPhase( throw e; } runAsync(getExecutor(readerContext.indexShard()), () -> { + // TODO: might want to explore this execution path final ShardSearchRequest shardSearchRequest = readerContext.getShardSearchRequest(null); try ( SearchContext searchContext = createContext(readerContext, shardSearchRequest, task, false); @@ -686,6 +689,7 @@ public void executeQueryPhase(QuerySearchRequest request, SearchShardTask task, final ReaderContext readerContext = findReaderContext(request.contextId(), request.shardSearchRequest()); final ShardSearchRequest shardSearchRequest = readerContext.getShardSearchRequest(request.shardSearchRequest()); final Releasable markAsUsed = readerContext.markAsUsed(getKeepAlive(shardSearchRequest)); + task.setSandboxId(shardSearchRequest.getSandboxId()); runAsync(getExecutor(readerContext.indexShard()), () -> { readerContext.setAggregatedDfs(request.dfs()); try ( @@ -767,6 +771,7 @@ public void executeFetchPhase(ShardFetchRequest request, SearchShardTask task, A final ReaderContext readerContext = findReaderContext(request.contextId(), request); final ShardSearchRequest shardSearchRequest = readerContext.getShardSearchRequest(request.getShardSearchRequest()); final Releasable markAsUsed = readerContext.markAsUsed(getKeepAlive(shardSearchRequest)); + task.setSandboxId(shardSearchRequest.getSandboxId()); runAsync(getExecutor(readerContext.indexShard()), () -> { try (SearchContext searchContext = createContext(readerContext, shardSearchRequest, task, false)) { if (request.lastEmittedDoc() != null) { 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..2ba3561aef6d0 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 sandboxId; public ShardSearchRequest( OriginalIndices originalIndices, @@ -265,6 +266,9 @@ public ShardSearchRequest(StreamInput in) throws IOException { bottomSortValues = in.readOptionalWriteable(SearchSortValuesAndFormats::new); readerId = in.readOptionalWriteable(ShardSearchContextId::new); keepAlive = in.readOptionalTimeValue(); + if (in.getVersion().onOrAfter(Version.V_3_0_0)) { + sandboxId = in.readOptionalString(); + } originalIndices = OriginalIndices.readOriginalIndices(in); 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.sandboxId = clone.sandboxId; } @Override @@ -335,6 +340,10 @@ protected final void innerWriteTo(StreamOutput out, boolean asKey) throws IOExce out.writeOptionalWriteable(readerId); out.writeOptionalTimeValue(keepAlive); } + + if (out.getVersion().onOrAfter(Version.V_3_0_0)) { + out.writeOptionalString(sandboxId); + } } @Override @@ -353,6 +362,14 @@ public IndicesOptions indicesOptions() { return originalIndices.indicesOptions(); } + public String getSandboxId() { + return sandboxId; + } + + public void setSandboxId(String sandboxId) { + this.sandboxId = sandboxId; + } + public ShardId shardId() { return shardId; } diff --git a/server/src/main/java/org/opensearch/search/sandbox/Persistable.java b/server/src/main/java/org/opensearch/search/sandbox/Persistable.java new file mode 100644 index 0000000000000..95ceb3cff7a89 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/Persistable.java @@ -0,0 +1,23 @@ +/* + * 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.core.action.ActionListener; +import org.opensearch.core.action.ActionResponse; + +/** + * This interface defines the key APIs for implementing Sandbox persistence + */ +public interface Perisist { + /** + * persists the @link Sandbox in a durable storage + * @param sandbox + */ + void persist(Sandbox sandbox, ActionListener listener); +} 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..c08ea426f6e97 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/QuerySandboxService.java @@ -0,0 +1,70 @@ +/* + * 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.lifecycle.AbstractLifecycleComponent; +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 SandboxedRequestTrackerService requestTrackerService; + private volatile Scheduler.Cancellable scheduledFuture; + private final QuerySandboxServiceSettings sandboxServiceSettings; + private final ThreadPool threadPool; + + public QuerySandboxService( + SandboxedRequestTrackerService requestTrackerService, + QuerySandboxServiceSettings sandboxServiceSettings, + ThreadPool threadPool + ) { + this.requestTrackerService = requestTrackerService; + this.sandboxServiceSettings = sandboxServiceSettings; + this.threadPool = threadPool; + } + + private void doRun() { + requestTrackerService.updateSandboxResourceUsages(); + requestTrackerService.cancelViolatingTasks(); + requestTrackerService.pruneSandboxes(); + } + + @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..cb656893e0c9d --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/QuerySandboxServiceSettings.java @@ -0,0 +1,102 @@ +/* + * 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; + +/** + * 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; + public static final int DEFAULT_MAX_SANDBOX_COUNT_VALUE = 100; + static final String SANDBOX_COUNT_SETTING_NAME = "node.sandbox.max_count"; + + private TimeValue runIntervalMillis; + private Double nodeLevelJvmCancellationThreshold; + private Double nodeLevelJvmRejectionThreshold; + private volatile int maxSandboxCount; + + public static final Setting MAX_SANDBOX_COUNT = Setting.intSetting( + SANDBOX_COUNT_SETTING_NAME, + DEFAULT_MAX_SANDBOX_COUNT_VALUE, + 0, + Setting.Property.Dynamic, + Setting.Property.NodeScope + ); + private static final Setting QSB_RUN_INTERVAL_SETTING = Setting.longSetting( + "query_sandbox.service.run_interval_millis", + DEFAULT_RUN_INTERVAL_MILLIS, + 1, + Setting.Property.NodeScope + ); + + public static final Setting NODE_LEVEL_REJECTION_THRESHOLD = Setting.doubleSetting( + "query_sandbox.node.rejection_threshold", + DEFAULT_NODE_LEVEL_REJECTION_QUERY_SANDBOX_THRESHOLD, + Setting.Property.NodeScope + ); + public static final Setting NODE_LEVEL_CANCELLATION_THRESHOLD = Setting.doubleSetting( + "query_sandbox.node.cancellation_threshold", + DEFAULT_NODE_LEVEL_CANCELLATION_QUERY_SANDBOX_THRESHOLD, + Setting.Property.NodeScope + ); + + 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); + + clusterSettings.addSettingsUpdateConsumer(MAX_SANDBOX_COUNT, this::setMaxSandboxCount); + clusterSettings.addSettingsUpdateConsumer(NODE_LEVEL_CANCELLATION_THRESHOLD, this::setNodeLevelJvmCancellationThreshold); + clusterSettings.addSettingsUpdateConsumer(NODE_LEVEL_REJECTION_THRESHOLD, this::setNodeLevelJvmRejectionThreshold); + } + + public TimeValue getRunIntervalMillis() { + return runIntervalMillis; + } + + + public void setMaxSandboxCount(int newMaxSandboxCount) { + if (newMaxSandboxCount < 0) { + throw new IllegalArgumentException("node.sandbox.max_count can't be negative"); + } + this.maxSandboxCount = newMaxSandboxCount; + } + + public void setRunIntervalMillis(TimeValue runIntervalMillis) { + this.runIntervalMillis = runIntervalMillis; + } + + public Double getNodeLevelJvmCancellationThreshold() { + return nodeLevelJvmCancellationThreshold; + } + + public void setNodeLevelJvmCancellationThreshold(Double nodeLevelJvmCancellationThreshold) { + this.nodeLevelJvmCancellationThreshold = nodeLevelJvmCancellationThreshold; + } + + public Double getNodeLevelJvmRejectionThreshold() { + return nodeLevelJvmRejectionThreshold; + } + + public void setNodeLevelJvmRejectionThreshold(Double nodeLevelJvmRejectionThreshold) { + this.nodeLevelJvmRejectionThreshold = nodeLevelJvmRejectionThreshold; + } + + public int getMaxSandboxCount() { + return maxSandboxCount; + } +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/RequestAttributeExtractor.java b/server/src/main/java/org/opensearch/search/sandbox/RequestAttributeExtractor.java new file mode 100644 index 0000000000000..694a798b87d16 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/RequestAttributeExtractor.java @@ -0,0 +1,27 @@ +/* + * 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.action.ActionRequest; + +import java.util.Map; +import java.util.NoSuchElementException; + +/** + * This class is used to extract attributes from search/msearch requests at co-ordinator node level to classify the task into a Sandbox + */ +public interface RequestAttributeExtractor { + /** + * + * @param request must be SearchRequest or MultiSearchRequest + * @return + * @throws NoSuchElementException + */ + public Map extractAttributesFrom(ActionRequest request) throws NoSuchElementException; +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/RequestSandboxClassifier.java b/server/src/main/java/org/opensearch/search/sandbox/RequestSandboxClassifier.java new file mode 100644 index 0000000000000..3743d1aaa61d4 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/RequestSandboxClassifier.java @@ -0,0 +1,27 @@ +/* + * 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.action.ActionRequest; + +/** + * This class is used to classify co-ordinator search reqyests into sandboxes + */ +public class RequestSandboxClassifier { + + /** + * + * @param request is a coordinator request task + * @return List of matching sandboxes based on user firing the request + */ + public String resolveSandboxFor(final ActionRequest request) { + return "dummy"; + } + +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/SandboxResourceTracker.java b/server/src/main/java/org/opensearch/search/sandbox/SandboxResourceTracker.java new file mode 100644 index 0000000000000..7196e30a6df18 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/SandboxResourceTracker.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 org.opensearch.search.sandbox; + +/** + * This interface is mainly for tracking the sandbox level resource usages + */ +public interface SandboxResourceTracker { + public void updateSandboxResourceUsages(); +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/SandboxStatsHolder.java b/server/src/main/java/org/opensearch/search/sandbox/SandboxStatsHolder.java new file mode 100644 index 0000000000000..3c63c8bf67179 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/SandboxStatsHolder.java @@ -0,0 +1,2 @@ +package org.opensearch.search.sandbox;public class SandboxStatsHolder { +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/SandboxStatsReporter.java b/server/src/main/java/org/opensearch/search/sandbox/SandboxStatsReporter.java new file mode 100644 index 0000000000000..d30f2b764da19 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/SandboxStatsReporter.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. + */ + +package org.opensearch.search.sandbox; + +public interface StatsReporter { + public T getStats(); +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/SandboxedRequestTrackerService.java b/server/src/main/java/org/opensearch/search/sandbox/SandboxedRequestTrackerService.java new file mode 100644 index 0000000000000..8fc3d0efa196b --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/SandboxedRequestTrackerService.java @@ -0,0 +1,145 @@ +/* + * 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.core.tasks.resourcetracker.TaskResourceUsage; +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.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.LongSupplier; +import java.util.stream.Collectors; + +/** + * This class tracks requests per sandboxes + */ +public class SandboxedRequestTrackerService implements TaskManager.TaskEventListeners, SandboxResourceTracker, SandboxStatsReporter { + + 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; + /** + * It is used to track the task to sandbox mapping which will be useful to remove it from the @link tasksPerSandbox + */ + private final Map sandboxStats; + private final TaskManager taskManager; + private final TaskResourceTrackingService taskResourceTrackingService; + + public SandboxedRequestTrackerService( + TaskManager taskManager, + TaskResourceTrackingService taskResourceTrackingService, + LongSupplier timeNanosSupplier + ) { + this.taskManager = taskManager; + this.taskResourceTrackingService = taskResourceTrackingService; + toDeleteSandboxes = Collections.synchronizedList(new ArrayList<>()); + sandboxStats = new ConcurrentHashMap<>(); + this.timeNanosSupplier = timeNanosSupplier; + } + + @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; + } + } + + public void pruneSandboxes() { + toDeleteSandboxes = toDeleteSandboxes.stream().filter(this::hasUnfinishedTasks).collect(Collectors.toList()); + } + + public boolean hasUnfinishedTasks(String sandboxId) { + return false; + } + + @Override + public void onTaskCompleted(Task task) {} + + public void cancelViolatingTasks() { + List cancellableTasks = getCancellableTasks(); + for (TaskCancellation taskCancellation : cancellableTasks) { + taskCancellation.cancel(); + } + } + + private List getCancellableTasks() { + List inViolationSandboxes = getBreachingSandboxIds(); + List cancellableTasks = new ArrayList<>(); + for (String sandboxId : inViolationSandboxes) { + cancellableTasks.addAll(getCancellableTasksFrom(sandboxId)); + } + return cancellableTasks; + } + + public SandboxStatsHolder getSandboxLevelStats() { + return null; + } + + 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/matcher/SandboxMatchScorer.java b/server/src/main/java/org/opensearch/search/sandbox/matcher/SandboxMatchScorer.java new file mode 100644 index 0000000000000..8b73d8068422d --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/matcher/SandboxMatchScorer.java @@ -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. + */ + +package org.opensearch.search.sandbox.matcher; + +import java.util.Map; + +/** + * Main interface for calculation the score of a sandbox and request match + */ +public interface SandboxMatchScorer { + public double score(Map requestAttributes, Map sandboxAttributes) throws IllegalArgumentException; +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/matcher/StringMatchScorer.java b/server/src/main/java/org/opensearch/search/sandbox/matcher/StringMatchScorer.java new file mode 100644 index 0000000000000..c2bd8c07d2bd8 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/matcher/StringMatchScorer.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 org.opensearch.search.sandbox.matcher; + +/** + * This interface is mainly for calculating the match score of two strings + */ +public interface StringMatchScorer { + public double score(String input, String target) throws IllegalArgumentException; +} diff --git a/server/src/main/java/org/opensearch/search/sandbox/matcher/package-info.java b/server/src/main/java/org/opensearch/search/sandbox/matcher/package-info.java new file mode 100644 index 0000000000000..042b066651221 --- /dev/null +++ b/server/src/main/java/org/opensearch/search/sandbox/matcher/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. + */ + +/** + * This package is mainly employed to perform request to sandbox matching and scoring + */ + +package org.opensearch.search.sandbox.matcher; diff --git a/server/src/main/java/org/opensearch/tasks/SandboxableTask.java b/server/src/main/java/org/opensearch/tasks/SandboxableTask.java new file mode 100644 index 0000000000000..827b20f04aade --- /dev/null +++ b/server/src/main/java/org/opensearch/tasks/SandboxableTask.java @@ -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. + */ + +package org.opensearch.tasks; + +/** + * This interface is used to identify sandboxable tasks, which can be tracked and used under a sandbox + */ +public interface SandboxableTask { + public void setSandboxId(String sandboxId); + + public String getSandboxId(); +} From f94504ded53ef79d3a409033bccad6ec663f977a Mon Sep 17 00:00:00 2001 From: Kaushal Kumar Date: Mon, 1 Apr 2024 18:38:19 -0700 Subject: [PATCH 2/3] resolve merge conflicts Signed-off-by: Kaushal Kumar --- .../org/opensearch/action/search/FetchSearchPhase.java | 3 --- .../opensearch/action/search/TransportSearchAction.java | 6 +++--- .../java/org/opensearch/search/sandbox/Persistable.java | 4 ++-- .../opensearch/search/sandbox/SandboxStatsReporter.java | 7 +++++-- .../search/sandbox/SandboxedRequestTrackerService.java | 2 -- .../org/opensearch/snapshots/SnapshotResiliencyTests.java | 4 +++- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/server/src/main/java/org/opensearch/action/search/FetchSearchPhase.java b/server/src/main/java/org/opensearch/action/search/FetchSearchPhase.java index fa5b75d0c6a1a..ebb2f33f8f37d 100644 --- a/server/src/main/java/org/opensearch/action/search/FetchSearchPhase.java +++ b/server/src/main/java/org/opensearch/action/search/FetchSearchPhase.java @@ -194,9 +194,6 @@ private void innerRun() throws Exception { queryResult.getShardSearchRequest(), queryResult.getRescoreDocIds() ); - // set sandboxId in shard level fetch request - assert context.getTask().getSandboxId() != null : "Search task should have the sandboxId"; - fetchSearchRequest.setSandboxId(context.getTask().getSandboxId()); executeFetch(i, searchShardTarget, counter, fetchSearchRequest, queryResult.queryResult(), connection); } } 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 27629a5527e04..baeed3c561549 100644 --- a/server/src/main/java/org/opensearch/action/search/TransportSearchAction.java +++ b/server/src/main/java/org/opensearch/action/search/TransportSearchAction.java @@ -194,7 +194,7 @@ public class TransportSearchAction extends HandledTransportAction) SearchRequest::new); this.client = client; @@ -233,7 +234,6 @@ public TransportSearchAction( this.searchRequestSlowLog = searchRequestSlowLog; this.metricsRegistry = metricsRegistry; this.searchQueryMetricsEnabled = clusterService.getClusterSettings().get(SEARCH_QUERY_METRICS_ENABLED_SETTING); - this.searchRequestOperationsCompositeListenerFactory = searchRequestOperationsCompositeListenerFactory; this.requestSandboxClassifier = requestSandboxClassifier; clusterService.getClusterSettings() .addSettingsUpdateConsumer(SEARCH_QUERY_METRICS_ENABLED_SETTING, this::setSearchQueryMetricsEnabled); diff --git a/server/src/main/java/org/opensearch/search/sandbox/Persistable.java b/server/src/main/java/org/opensearch/search/sandbox/Persistable.java index 95ceb3cff7a89..f637f446cd761 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/Persistable.java +++ b/server/src/main/java/org/opensearch/search/sandbox/Persistable.java @@ -14,10 +14,10 @@ /** * This interface defines the key APIs for implementing Sandbox persistence */ -public interface Perisist { +public interface Persistable { /** * persists the @link Sandbox in a durable storage * @param sandbox */ - void persist(Sandbox sandbox, ActionListener listener); + void persist(Object sandbox, ActionListener listener); } diff --git a/server/src/main/java/org/opensearch/search/sandbox/SandboxStatsReporter.java b/server/src/main/java/org/opensearch/search/sandbox/SandboxStatsReporter.java index d30f2b764da19..7cbd94a4975ba 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/SandboxStatsReporter.java +++ b/server/src/main/java/org/opensearch/search/sandbox/SandboxStatsReporter.java @@ -8,6 +8,9 @@ package org.opensearch.search.sandbox; -public interface StatsReporter { - public T getStats(); +/** + * Interface to expose the sandbox level stats + */ +public interface SandboxStatsReporter { + public SandboxStatsHolder getStats(); } diff --git a/server/src/main/java/org/opensearch/search/sandbox/SandboxedRequestTrackerService.java b/server/src/main/java/org/opensearch/search/sandbox/SandboxedRequestTrackerService.java index 8fc3d0efa196b..789d4a5fff109 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/SandboxedRequestTrackerService.java +++ b/server/src/main/java/org/opensearch/search/sandbox/SandboxedRequestTrackerService.java @@ -39,7 +39,6 @@ public class SandboxedRequestTrackerService implements TaskManager.TaskEventList /** * It is used to track the task to sandbox mapping which will be useful to remove it from the @link tasksPerSandbox */ - private final Map sandboxStats; private final TaskManager taskManager; private final TaskResourceTrackingService taskResourceTrackingService; @@ -51,7 +50,6 @@ public SandboxedRequestTrackerService( this.taskManager = taskManager; this.taskResourceTrackingService = taskResourceTrackingService; toDeleteSandboxes = Collections.synchronizedList(new ArrayList<>()); - sandboxStats = new ConcurrentHashMap<>(); this.timeNanosSupplier = timeNanosSupplier; } diff --git a/server/src/test/java/org/opensearch/snapshots/SnapshotResiliencyTests.java b/server/src/test/java/org/opensearch/snapshots/SnapshotResiliencyTests.java index 9fe1f8294fc74..e93c0daeff7b2 100644 --- a/server/src/test/java/org/opensearch/snapshots/SnapshotResiliencyTests.java +++ b/server/src/test/java/org/opensearch/snapshots/SnapshotResiliencyTests.java @@ -222,6 +222,7 @@ import org.opensearch.search.fetch.FetchPhase; import org.opensearch.search.pipeline.SearchPipelineService; import org.opensearch.search.query.QueryPhase; +import org.opensearch.search.sandbox.RequestSandboxClassifier; import org.opensearch.snapshots.mockstore.MockEventuallyConsistentRepository; import org.opensearch.tasks.TaskResourceTrackingService; import org.opensearch.telemetry.metrics.noop.NoopMetricsRegistry; @@ -2312,7 +2313,8 @@ public void onFailure(final Exception e) { ), null, new SearchRequestSlowLog(clusterService), - NoopMetricsRegistry.INSTANCE + NoopMetricsRegistry.INSTANCE, + new RequestSandboxClassifier() ) ); actions.put( From 239e5ec6fdf2da7ff85f7a4687a65d96e795436e Mon Sep 17 00:00:00 2001 From: Kaushal Kumar Date: Mon, 1 Apr 2024 19:17:23 -0700 Subject: [PATCH 3/3] add validity checks for settings Signed-off-by: Kaushal Kumar --- .../sandbox/QuerySandboxServiceSettings.java | 45 +++++++++++++++++-- .../sandbox/RequestSandboxClassifier.java | 8 ++-- .../search/sandbox/SandboxStatsHolder.java | 16 ++++++- .../SandboxedRequestTrackerService.java | 2 - .../sandbox/matcher/SandboxMatchScorer.java | 2 +- .../sandbox/matcher/StringMatchScorer.java | 3 +- .../search/sandbox/package-info.java | 12 +++++ 7 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 server/src/main/java/org/opensearch/search/sandbox/package-info.java diff --git a/server/src/main/java/org/opensearch/search/sandbox/QuerySandboxServiceSettings.java b/server/src/main/java/org/opensearch/search/sandbox/QuerySandboxServiceSettings.java index cb656893e0c9d..91e080e972281 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/QuerySandboxServiceSettings.java +++ b/server/src/main/java/org/opensearch/search/sandbox/QuerySandboxServiceSettings.java @@ -35,20 +35,23 @@ public class QuerySandboxServiceSettings { Setting.Property.Dynamic, Setting.Property.NodeScope ); + public static final String QUERY_SANDBOX_SERVICE_RUN_INTERVAL_MILLIS_SETTING_NAME = "query_sandbox.service.run_interval_millis"; private static final Setting QSB_RUN_INTERVAL_SETTING = Setting.longSetting( - "query_sandbox.service.run_interval_millis", + QUERY_SANDBOX_SERVICE_RUN_INTERVAL_MILLIS_SETTING_NAME, DEFAULT_RUN_INTERVAL_MILLIS, 1, Setting.Property.NodeScope ); + public static final String QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME = "query_sandbox.node.rejection_threshold"; public static final Setting NODE_LEVEL_REJECTION_THRESHOLD = Setting.doubleSetting( - "query_sandbox.node.rejection_threshold", + QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME, DEFAULT_NODE_LEVEL_REJECTION_QUERY_SANDBOX_THRESHOLD, Setting.Property.NodeScope ); + public static final String QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME = "query_sandbox.node.cancellation_threshold"; public static final Setting NODE_LEVEL_CANCELLATION_THRESHOLD = Setting.doubleSetting( - "query_sandbox.node.cancellation_threshold", + QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME, DEFAULT_NODE_LEVEL_CANCELLATION_QUERY_SANDBOX_THRESHOLD, Setting.Property.NodeScope ); @@ -68,7 +71,6 @@ public TimeValue getRunIntervalMillis() { return runIntervalMillis; } - public void setMaxSandboxCount(int newMaxSandboxCount) { if (newMaxSandboxCount < 0) { throw new IllegalArgumentException("node.sandbox.max_count can't be negative"); @@ -77,6 +79,11 @@ public void setMaxSandboxCount(int newMaxSandboxCount) { } public void setRunIntervalMillis(TimeValue runIntervalMillis) { + if (runIntervalMillis.getMillis() < 100 && runIntervalMillis.getMillis() < 0) { + throw new IllegalArgumentException( + QUERY_SANDBOX_SERVICE_RUN_INTERVAL_MILLIS_SETTING_NAME + " can't be negative and should be greater than 100ms" + ); + } this.runIntervalMillis = runIntervalMillis; } @@ -85,6 +92,15 @@ public Double getNodeLevelJvmCancellationThreshold() { } public void setNodeLevelJvmCancellationThreshold(Double nodeLevelJvmCancellationThreshold) { + if (nodeLevelJvmCancellationThreshold > 0.95) { + 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; } @@ -93,9 +109,30 @@ public Double getNodeLevelJvmRejectionThreshold() { } public void setNodeLevelJvmRejectionThreshold(Double nodeLevelJvmRejectionThreshold) { + if (nodeLevelJvmRejectionThreshold > 0.90) { + 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 (nodeLevelJvmCancellationThreshold < nodeLevelJvmRejectionThreshold) { + throw new IllegalArgumentException( + QUERY_SANDBOX_NODE_CANCELLATION_THRESHOLD_SETTING_NAME + + " value should not be less than " + + QUERY_SANDBOX_NODE_REJECTION_THRESHOLD_SETTING_NAME + ); + } + } + public int getMaxSandboxCount() { return maxSandboxCount; } diff --git a/server/src/main/java/org/opensearch/search/sandbox/RequestSandboxClassifier.java b/server/src/main/java/org/opensearch/search/sandbox/RequestSandboxClassifier.java index 3743d1aaa61d4..9d6b08e584aae 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/RequestSandboxClassifier.java +++ b/server/src/main/java/org/opensearch/search/sandbox/RequestSandboxClassifier.java @@ -8,7 +8,7 @@ package org.opensearch.search.sandbox; -import org.opensearch.action.ActionRequest; +import org.opensearch.action.search.SearchRequest; /** * This class is used to classify co-ordinator search reqyests into sandboxes @@ -17,10 +17,10 @@ public class RequestSandboxClassifier { /** * - * @param request is a coordinator request task - * @return List of matching sandboxes based on user firing the request + * @param request is a coordinator search request + * @return matching sandboxId based on request attributes */ - public String resolveSandboxFor(final ActionRequest request) { + public String resolveSandboxFor(final SearchRequest request) { return "dummy"; } diff --git a/server/src/main/java/org/opensearch/search/sandbox/SandboxStatsHolder.java b/server/src/main/java/org/opensearch/search/sandbox/SandboxStatsHolder.java index 3c63c8bf67179..d0b7ff83229c0 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/SandboxStatsHolder.java +++ b/server/src/main/java/org/opensearch/search/sandbox/SandboxStatsHolder.java @@ -1,2 +1,16 @@ -package org.opensearch.search.sandbox;public class SandboxStatsHolder { +/* + * 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; + +/** + * Main class to hold sandbox level stats + */ +public class SandboxStatsHolder { + // TODO: We will fill in this class when raising the stats PR } diff --git a/server/src/main/java/org/opensearch/search/sandbox/SandboxedRequestTrackerService.java b/server/src/main/java/org/opensearch/search/sandbox/SandboxedRequestTrackerService.java index 789d4a5fff109..f758f1833271f 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/SandboxedRequestTrackerService.java +++ b/server/src/main/java/org/opensearch/search/sandbox/SandboxedRequestTrackerService.java @@ -17,8 +17,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.LongSupplier; import java.util.stream.Collectors; diff --git a/server/src/main/java/org/opensearch/search/sandbox/matcher/SandboxMatchScorer.java b/server/src/main/java/org/opensearch/search/sandbox/matcher/SandboxMatchScorer.java index 8b73d8068422d..b08f022796c36 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/matcher/SandboxMatchScorer.java +++ b/server/src/main/java/org/opensearch/search/sandbox/matcher/SandboxMatchScorer.java @@ -11,7 +11,7 @@ import java.util.Map; /** - * Main interface for calculation the score of a sandbox and request match + * Main interface for calculating the score of a sandbox and request match */ public interface SandboxMatchScorer { public double score(Map requestAttributes, Map sandboxAttributes) throws IllegalArgumentException; diff --git a/server/src/main/java/org/opensearch/search/sandbox/matcher/StringMatchScorer.java b/server/src/main/java/org/opensearch/search/sandbox/matcher/StringMatchScorer.java index c2bd8c07d2bd8..921e608c3e221 100644 --- a/server/src/main/java/org/opensearch/search/sandbox/matcher/StringMatchScorer.java +++ b/server/src/main/java/org/opensearch/search/sandbox/matcher/StringMatchScorer.java @@ -9,7 +9,8 @@ package org.opensearch.search.sandbox.matcher; /** - * This interface is mainly for calculating the match score of two strings + * This interface id for calculating the match score of two strings, It can be generalised into different approaches + * */ public interface StringMatchScorer { public double score(String input, String target) throws IllegalArgumentException; 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..86acf8037ca12 --- /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. + */ + +/** + * This package encapsulates query sandboxing related interfaces and classes + */ +package org.opensearch.search.sandbox;