From 54a15f70131b4180ae63b4592e373cc12a84a210 Mon Sep 17 00:00:00 2001 From: Daniel Mitterdorfer Date: Wed, 24 Jan 2024 14:06:00 +0100 Subject: [PATCH 01/37] [Profiling] More waiting in REST tests (#104672) Universal Profiling creates a lot of indices upon startup. On slower systems it might take longer than usual which leads to sporadic test failures. With this commit we: * Increase the initial timeout when waiting for resources to be created * Wait for a refresh after bulk-indexing data --- .../resources/rest-api-spec/test/profiling/10_basic.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/profiling/10_basic.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/profiling/10_basic.yml index 8bc863e6fca9f..abb0d038cb2c3 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/profiling/10_basic.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/profiling/10_basic.yml @@ -13,10 +13,11 @@ setup: - do: profiling.status: wait_for_resources_created: true + timeout: "1m" - do: bulk: - refresh: true + refresh: wait_for body: - {"create": {"_index": "profiling-events-all"}} - {"Stacktrace.count": [1], "profiling.project.id": ["100"], "os.kernel": ["9.9.9-0"], "tags": ["environment:qa", "region:eu-west-1"], "host.ip": ["192.168.1.2"], "@timestamp": ["1700504427"], "container.name": ["instance-0000000010"], "ecs.version": ["1.12.0"], "Stacktrace.id": ["S07KmaoGhvNte78xwwRbZQ"], "agent.version": ["head-be593ef3-1688111067"], "host.name": ["ip-192-168-1-2"], "host.id": ["8457605156473051743"], "process.thread.name": ["497295213074376"]} From 1d567671413e5f4491032b30e3da6dd7983a518a Mon Sep 17 00:00:00 2001 From: Daniel Mitterdorfer Date: Wed, 24 Jan 2024 14:11:56 +0100 Subject: [PATCH 02/37] [Profiling] Speed up processing of stacktraces (#104674) So far we kept track of stack frame and executable ids that are associated to stack traces in a sorted collection. The rationale behind this was that the mget should be faster. However, we have seen in benchmarks that the contrary is the case: Not the mgets are the bottleneck but rather insertion is so slow that it defers further processing internally by several hundred milliseconds. When we change to an unsorted (and pre-sized) collection we reduce median response time from ~ 1200ms to 1000ms (or 17%). --- docs/changelog/104674.yaml | 5 +++++ .../profiling/TransportGetStackTracesAction.java | 11 +++++------ 2 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 docs/changelog/104674.yaml diff --git a/docs/changelog/104674.yaml b/docs/changelog/104674.yaml new file mode 100644 index 0000000000000..12951488f89ce --- /dev/null +++ b/docs/changelog/104674.yaml @@ -0,0 +1,5 @@ +pr: 104674 +summary: "[Profiling] Speed up processing of stacktraces" +area: Application +type: enhancement +issues: [] diff --git a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/TransportGetStackTracesAction.java b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/TransportGetStackTracesAction.java index ff9ad2e4f2e38..6ac28bd90d1fa 100644 --- a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/TransportGetStackTracesAction.java +++ b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/TransportGetStackTracesAction.java @@ -59,7 +59,6 @@ import java.util.Set; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentSkipListSet; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; @@ -483,11 +482,8 @@ private class StackTraceHandler { private final GetStackTracesResponseBuilder responseBuilder; private final ActionListener submitListener; private final Map stackTracePerId; - // sort items lexicographically to access Lucene's term dictionary more efficiently when issuing an mget request. - // The term dictionary is lexicographically sorted and using the same order reduces the number of page faults - // needed to load it. - private final Set stackFrameIds = new ConcurrentSkipListSet<>(); - private final Set executableIds = new ConcurrentSkipListSet<>(); + private final Set stackFrameIds; + private final Set executableIds; private final AtomicInteger totalFrames = new AtomicInteger(); private final StopWatch watch = new StopWatch("retrieveStackTraces"); private final StopWatch hostsWatch = new StopWatch("retrieveHostMetadata"); @@ -506,6 +502,9 @@ private StackTraceHandler( this.submitTask = submitTask; this.clusterState = clusterState; this.stackTracePerId = new ConcurrentHashMap<>(stackTraceCount); + // pre-size with a bit of headroom so the collection isn't resized too often + this.stackFrameIds = Collections.newSetFromMap(new ConcurrentHashMap<>(stackTraceCount * 5)); + this.executableIds = Collections.newSetFromMap(new ConcurrentHashMap<>(stackTraceCount)); this.expectedResponses = new AtomicInteger(expectedResponses); this.client = client; this.responseBuilder = responseBuilder; From 0aeb9beb7ef0848abc8683c90a47fa33ebe534ce Mon Sep 17 00:00:00 2001 From: Bogdan Pintea Date: Wed, 24 Jan 2024 14:50:02 +0100 Subject: [PATCH 03/37] Lower the number of evaluation in testTooManyEval() (#104697) This reverts the increase in #104521, which causes the parser to sometimes stack overflow. Fixes #104694. --- .../org/elasticsearch/xpack/esql/heap_attack/HeapAttackIT.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/external-modules/esql-heap-attack/src/javaRestTest/java/org/elasticsearch/xpack/esql/heap_attack/HeapAttackIT.java b/test/external-modules/esql-heap-attack/src/javaRestTest/java/org/elasticsearch/xpack/esql/heap_attack/HeapAttackIT.java index 1685803df93c8..8d4b5ece98993 100644 --- a/test/external-modules/esql-heap-attack/src/javaRestTest/java/org/elasticsearch/xpack/esql/heap_attack/HeapAttackIT.java +++ b/test/external-modules/esql-heap-attack/src/javaRestTest/java/org/elasticsearch/xpack/esql/heap_attack/HeapAttackIT.java @@ -280,10 +280,9 @@ public void testManyEval() throws IOException { assertMap(map, matchesMap().entry("columns", columns).entry("values", hasSize(10_000))); } - @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/104694") public void testTooManyEval() throws IOException { initManyLongs(); - assertCircuitBreaks(() -> manyEval(1500)); + assertCircuitBreaks(() -> manyEval(1000)); } private Response manyEval(int evalLines) throws IOException { From d5c0dcf675a44bc40dbb7e2a17e32df7612beedc Mon Sep 17 00:00:00 2001 From: Jedr Blaszyk Date: Wed, 24 Jan 2024 15:14:43 +0100 Subject: [PATCH 04/37] [Connectors API] Implement update service type action (#104643) --- docs/changelog/104643.yaml | 5 + .../api/connector.update_service_type.json | 38 +++++ .../337_connector_update_service_type.yml | 61 ++++++++ .../xpack/application/EnterpriseSearch.java | 5 + .../connector/ConnectorIndexService.java | 47 ++++++ .../RestUpdateConnectorServiceTypeAction.java | 48 ++++++ ...sportUpdateConnectorServiceTypeAction.java | 52 +++++++ .../UpdateConnectorServiceTypeAction.java | 138 ++++++++++++++++++ .../connector/ConnectorIndexServiceTests.java | 48 ++++++ ...eTypeActionRequestBWCSerializingTests.java | 51 +++++++ .../xpack/security/operator/Constants.java | 1 + 11 files changed, 494 insertions(+) create mode 100644 docs/changelog/104643.yaml create mode 100644 rest-api-spec/src/main/resources/rest-api-spec/api/connector.update_service_type.json create mode 100644 x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/337_connector_update_service_type.yml create mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/RestUpdateConnectorServiceTypeAction.java create mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/TransportUpdateConnectorServiceTypeAction.java create mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/UpdateConnectorServiceTypeAction.java create mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/UpdateConnectorServiceTypeActionRequestBWCSerializingTests.java diff --git a/docs/changelog/104643.yaml b/docs/changelog/104643.yaml new file mode 100644 index 0000000000000..5a09cd081b376 --- /dev/null +++ b/docs/changelog/104643.yaml @@ -0,0 +1,5 @@ +pr: 104643 +summary: "[Connectors API] Implement update service type action" +area: Application +type: enhancement +issues: [] diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/connector.update_service_type.json b/rest-api-spec/src/main/resources/rest-api-spec/api/connector.update_service_type.json new file mode 100644 index 0000000000000..779fff1750276 --- /dev/null +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/connector.update_service_type.json @@ -0,0 +1,38 @@ +{ + "connector.update_service_type": { + "documentation": { + "url": "https://www.elastic.co/guide/en/elasticsearch/reference/master/connector-apis.html", + "description": "Updates the service type of the connector." + }, + "stability": "experimental", + "visibility": "public", + "headers": { + "accept": [ + "application/json" + ], + "content_type": [ + "application/json" + ] + }, + "url": { + "paths": [ + { + "path": "/_connector/{connector_id}/_service_type", + "methods": [ + "PUT" + ], + "parts": { + "connector_id": { + "type": "string", + "description": "The unique identifier of the connector to be updated." + } + } + } + ] + }, + "body": { + "description": "An object containing the connector's service type.", + "required": true + } + } +} diff --git a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/337_connector_update_service_type.yml b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/337_connector_update_service_type.yml new file mode 100644 index 0000000000000..53cef9f5067b7 --- /dev/null +++ b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/337_connector_update_service_type.yml @@ -0,0 +1,61 @@ +setup: + - skip: + version: " - 8.12.99" + reason: Introduced in 8.13.0 + + - do: + connector.put: + connector_id: test-connector + body: + index_name: search-1-test + name: my-connector + language: pl + is_native: false + service_type: super-connector + +--- +"Update Connector Service Type": + - do: + connector.update_service_type: + connector_id: test-connector + body: + service_type: even-better-connector + + + - match: { result: updated } + + - do: + connector.get: + connector_id: test-connector + + - match: { service_type: even-better-connector } + - match: { status: created } + +--- +"Update Connector Service Type - 404 when connector doesn't exist": + - do: + catch: "missing" + connector.update_service_type: + connector_id: test-non-existent-connector + body: + service_type: even-better-connector + +--- +"Update Connector Service Type - 400 status code when connector_id is empty": + - do: + catch: "bad_request" + connector.update_service_type: + connector_id: "" + body: + service_type: even-better-connector + +--- +"Update Connector Service Type - 400 status code when payload is not string": + - do: + catch: "bad_request" + connector.update_service_type: + connector_id: test-connector + body: + service_type: + field_1: test + field_2: something diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java index f61c1a7179f92..4b31778d469ac 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java @@ -62,6 +62,7 @@ import org.elasticsearch.xpack.application.connector.action.RestUpdateConnectorNativeAction; import org.elasticsearch.xpack.application.connector.action.RestUpdateConnectorPipelineAction; import org.elasticsearch.xpack.application.connector.action.RestUpdateConnectorSchedulingAction; +import org.elasticsearch.xpack.application.connector.action.RestUpdateConnectorServiceTypeAction; import org.elasticsearch.xpack.application.connector.action.TransportDeleteConnectorAction; import org.elasticsearch.xpack.application.connector.action.TransportGetConnectorAction; import org.elasticsearch.xpack.application.connector.action.TransportListConnectorAction; @@ -76,6 +77,7 @@ import org.elasticsearch.xpack.application.connector.action.TransportUpdateConnectorNativeAction; import org.elasticsearch.xpack.application.connector.action.TransportUpdateConnectorPipelineAction; import org.elasticsearch.xpack.application.connector.action.TransportUpdateConnectorSchedulingAction; +import org.elasticsearch.xpack.application.connector.action.TransportUpdateConnectorServiceTypeAction; import org.elasticsearch.xpack.application.connector.action.UpdateConnectorConfigurationAction; import org.elasticsearch.xpack.application.connector.action.UpdateConnectorErrorAction; import org.elasticsearch.xpack.application.connector.action.UpdateConnectorFilteringAction; @@ -85,6 +87,7 @@ import org.elasticsearch.xpack.application.connector.action.UpdateConnectorNativeAction; import org.elasticsearch.xpack.application.connector.action.UpdateConnectorPipelineAction; import org.elasticsearch.xpack.application.connector.action.UpdateConnectorSchedulingAction; +import org.elasticsearch.xpack.application.connector.action.UpdateConnectorServiceTypeAction; import org.elasticsearch.xpack.application.connector.syncjob.action.CancelConnectorSyncJobAction; import org.elasticsearch.xpack.application.connector.syncjob.action.CheckInConnectorSyncJobAction; import org.elasticsearch.xpack.application.connector.syncjob.action.DeleteConnectorSyncJobAction; @@ -239,6 +242,7 @@ protected XPackLicenseState getLicenseState() { new ActionHandler<>(UpdateConnectorNativeAction.INSTANCE, TransportUpdateConnectorNativeAction.class), new ActionHandler<>(UpdateConnectorPipelineAction.INSTANCE, TransportUpdateConnectorPipelineAction.class), new ActionHandler<>(UpdateConnectorSchedulingAction.INSTANCE, TransportUpdateConnectorSchedulingAction.class), + new ActionHandler<>(UpdateConnectorServiceTypeAction.INSTANCE, TransportUpdateConnectorServiceTypeAction.class), // SyncJob API new ActionHandler<>(GetConnectorSyncJobAction.INSTANCE, TransportGetConnectorSyncJobAction.class), @@ -318,6 +322,7 @@ public List getRestHandlers( new RestUpdateConnectorNativeAction(), new RestUpdateConnectorPipelineAction(), new RestUpdateConnectorSchedulingAction(), + new RestUpdateConnectorServiceTypeAction(), // SyncJob API new RestGetConnectorSyncJobAction(), diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorIndexService.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorIndexService.java index f925d482b27e8..d92074dacc129 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorIndexService.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorIndexService.java @@ -41,6 +41,7 @@ import org.elasticsearch.xpack.application.connector.action.UpdateConnectorNativeAction; import org.elasticsearch.xpack.application.connector.action.UpdateConnectorPipelineAction; import org.elasticsearch.xpack.application.connector.action.UpdateConnectorSchedulingAction; +import org.elasticsearch.xpack.application.connector.action.UpdateConnectorServiceTypeAction; import java.time.Instant; import java.util.Arrays; @@ -555,6 +556,52 @@ public void updateConnectorScheduling(UpdateConnectorSchedulingAction.Request re } } + /** + * Updates the service type property of a {@link Connector} and its {@link ConnectorStatus}. + * + * @param request The request for updating the connector's service type. + * @param listener The listener for handling responses, including successful updates or errors. + */ + public void updateConnectorServiceType(UpdateConnectorServiceTypeAction.Request request, ActionListener listener) { + try { + String connectorId = request.getConnectorId(); + getConnector(connectorId, listener.delegateFailure((l, connector) -> { + + ConnectorStatus prevStatus = connector.getStatus(); + ConnectorStatus newStatus = prevStatus == ConnectorStatus.CREATED + ? ConnectorStatus.CREATED + : ConnectorStatus.NEEDS_CONFIGURATION; + + final UpdateRequest updateRequest = new UpdateRequest(CONNECTOR_INDEX_NAME, connectorId).doc( + new IndexRequest(CONNECTOR_INDEX_NAME).opType(DocWriteRequest.OpType.INDEX) + .id(connectorId) + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source( + Map.of( + Connector.SERVICE_TYPE_FIELD.getPreferredName(), + request.getServiceType(), + Connector.STATUS_FIELD.getPreferredName(), + newStatus + ) + ) + + ); + clientWithOrigin.update( + updateRequest, + new DelegatingIndexNotFoundActionListener<>(connectorId, listener, (updateListener, updateResponse) -> { + if (updateResponse.getResult() == UpdateResponse.Result.NOT_FOUND) { + updateListener.onFailure(new ResourceNotFoundException(connectorId)); + return; + } + updateListener.onResponse(updateResponse); + }) + ); + })); + } catch (Exception e) { + listener.onFailure(e); + } + } + private static ConnectorIndexService.ConnectorResult mapSearchResponseToConnectorList(SearchResponse response) { final List connectorResults = Arrays.stream(response.getHits().getHits()) .map(ConnectorIndexService::hitToConnector) diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/RestUpdateConnectorServiceTypeAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/RestUpdateConnectorServiceTypeAction.java new file mode 100644 index 0000000000000..89c3303f8cc94 --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/RestUpdateConnectorServiceTypeAction.java @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.action; + +import org.elasticsearch.client.internal.node.NodeClient; +import org.elasticsearch.rest.BaseRestHandler; +import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.Scope; +import org.elasticsearch.rest.ServerlessScope; +import org.elasticsearch.rest.action.RestToXContentListener; +import org.elasticsearch.xpack.application.EnterpriseSearch; + +import java.util.List; + +import static org.elasticsearch.rest.RestRequest.Method.PUT; + +@ServerlessScope(Scope.PUBLIC) +public class RestUpdateConnectorServiceTypeAction extends BaseRestHandler { + + @Override + public String getName() { + return "connector_update_service_type_action"; + } + + @Override + public List routes() { + return List.of(new Route(PUT, "/" + EnterpriseSearch.CONNECTOR_API_ENDPOINT + "/{connector_id}/_service_type")); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest restRequest, NodeClient client) { + UpdateConnectorServiceTypeAction.Request request = UpdateConnectorServiceTypeAction.Request.fromXContentBytes( + restRequest.param("connector_id"), + restRequest.content(), + restRequest.getXContentType() + ); + return channel -> client.execute( + UpdateConnectorServiceTypeAction.INSTANCE, + request, + new RestToXContentListener<>(channel, ConnectorUpdateActionResponse::status) + ); + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/TransportUpdateConnectorServiceTypeAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/TransportUpdateConnectorServiceTypeAction.java new file mode 100644 index 0000000000000..b336584a8a5c9 --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/TransportUpdateConnectorServiceTypeAction.java @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.action; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.action.support.HandledTransportAction; +import org.elasticsearch.client.internal.Client; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.util.concurrent.EsExecutors; +import org.elasticsearch.tasks.Task; +import org.elasticsearch.transport.TransportService; +import org.elasticsearch.xpack.application.connector.ConnectorIndexService; + +public class TransportUpdateConnectorServiceTypeAction extends HandledTransportAction< + UpdateConnectorServiceTypeAction.Request, + ConnectorUpdateActionResponse> { + + protected final ConnectorIndexService connectorIndexService; + + @Inject + public TransportUpdateConnectorServiceTypeAction( + TransportService transportService, + ClusterService clusterService, + ActionFilters actionFilters, + Client client + ) { + super( + UpdateConnectorServiceTypeAction.NAME, + transportService, + actionFilters, + UpdateConnectorServiceTypeAction.Request::new, + EsExecutors.DIRECT_EXECUTOR_SERVICE + ); + this.connectorIndexService = new ConnectorIndexService(client); + } + + @Override + protected void doExecute( + Task task, + UpdateConnectorServiceTypeAction.Request request, + ActionListener listener + ) { + connectorIndexService.updateConnectorServiceType(request, listener.map(r -> new ConnectorUpdateActionResponse(r.getResult()))); + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/UpdateConnectorServiceTypeAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/UpdateConnectorServiceTypeAction.java new file mode 100644 index 0000000000000..39d0d4f1f14c4 --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/UpdateConnectorServiceTypeAction.java @@ -0,0 +1,138 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.action; + +import org.elasticsearch.ElasticsearchParseException; +import org.elasticsearch.action.ActionRequest; +import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.action.ActionType; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.xcontent.XContentHelper; +import org.elasticsearch.xcontent.ConstructingObjectParser; +import org.elasticsearch.xcontent.ToXContentObject; +import org.elasticsearch.xcontent.XContentBuilder; +import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; +import org.elasticsearch.xcontent.XContentType; +import org.elasticsearch.xpack.application.connector.Connector; + +import java.io.IOException; +import java.util.Objects; + +import static org.elasticsearch.action.ValidateActions.addValidationError; +import static org.elasticsearch.xcontent.ConstructingObjectParser.constructorArg; + +public class UpdateConnectorServiceTypeAction extends ActionType { + + public static final UpdateConnectorServiceTypeAction INSTANCE = new UpdateConnectorServiceTypeAction(); + public static final String NAME = "cluster:admin/xpack/connector/update_service_type"; + + public UpdateConnectorServiceTypeAction() { + super(NAME, ConnectorUpdateActionResponse::new); + } + + public static class Request extends ActionRequest implements ToXContentObject { + + private final String connectorId; + private final String serviceType; + + public Request(String connectorId, String serviceType) { + this.connectorId = connectorId; + this.serviceType = serviceType; + } + + public Request(StreamInput in) throws IOException { + super(in); + this.connectorId = in.readString(); + this.serviceType = in.readString(); + } + + public String getConnectorId() { + return connectorId; + } + + public String getServiceType() { + return serviceType; + } + + private static final ConstructingObjectParser PARSER = + new ConstructingObjectParser<>( + "connector_update_service_type_request", + false, + ((args, connectorId) -> new UpdateConnectorServiceTypeAction.Request(connectorId, (String) args[0])) + ); + + static { + PARSER.declareString(constructorArg(), Connector.SERVICE_TYPE_FIELD); + } + + public static UpdateConnectorServiceTypeAction.Request fromXContentBytes( + String connectorId, + BytesReference source, + XContentType xContentType + ) { + try (XContentParser parser = XContentHelper.createParser(XContentParserConfiguration.EMPTY, source, xContentType)) { + return UpdateConnectorServiceTypeAction.Request.fromXContent(parser, connectorId); + } catch (IOException e) { + throw new ElasticsearchParseException("Failed to parse: " + source.utf8ToString(), e); + } + } + + public static UpdateConnectorServiceTypeAction.Request fromXContent(XContentParser parser, String connectorId) throws IOException { + return PARSER.parse(parser, connectorId); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + { + builder.field(Connector.SERVICE_TYPE_FIELD.getPreferredName(), serviceType); + } + builder.endObject(); + return builder; + } + + @Override + public ActionRequestValidationException validate() { + ActionRequestValidationException validationException = null; + + if (Strings.isNullOrEmpty(connectorId)) { + validationException = addValidationError("[connector_id] cannot be [null] or [\"\"].", validationException); + } + + if (Strings.isNullOrEmpty(serviceType)) { + validationException = addValidationError("[service_type] cannot be [null] or [\"\"].", validationException); + } + + return validationException; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeString(connectorId); + out.writeString(serviceType); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Request request = (Request) o; + return Objects.equals(connectorId, request.connectorId) && Objects.equals(serviceType, request.serviceType); + } + + @Override + public int hashCode() { + return Objects.hash(connectorId, serviceType); + } + } +} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIndexServiceTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIndexServiceTests.java index 170f9bb915057..542ea948c12df 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIndexServiceTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIndexServiceTests.java @@ -25,6 +25,7 @@ import org.elasticsearch.xpack.application.connector.action.UpdateConnectorNativeAction; import org.elasticsearch.xpack.application.connector.action.UpdateConnectorPipelineAction; import org.elasticsearch.xpack.application.connector.action.UpdateConnectorSchedulingAction; +import org.elasticsearch.xpack.application.connector.action.UpdateConnectorServiceTypeAction; import org.junit.Before; import java.util.ArrayList; @@ -217,6 +218,27 @@ public void testUpdateConnectorScheduling() throws Exception { assertThat(updatedScheduling, equalTo(indexedConnector.getScheduling())); } + public void testUpdateConnectorServiceType() throws Exception { + Connector connector = ConnectorTestUtils.getRandomConnector(); + String connectorId = randomUUID(); + + DocWriteResponse resp = buildRequestAndAwaitPutConnector(connectorId, connector); + assertThat(resp.status(), anyOf(equalTo(RestStatus.CREATED), equalTo(RestStatus.OK))); + + String newServiceType = randomAlphaOfLengthBetween(3, 10); + + UpdateConnectorServiceTypeAction.Request updateServiceTypeRequest = new UpdateConnectorServiceTypeAction.Request( + connectorId, + newServiceType + ); + + DocWriteResponse updateResponse = awaitUpdateConnectorServiceType(updateServiceTypeRequest); + assertThat(updateResponse.status(), equalTo(RestStatus.OK)); + + Connector indexedConnector = awaitGetConnector(connectorId); + assertThat(newServiceType, equalTo(indexedConnector.getServiceType())); + } + public void testUpdateConnectorError() throws Exception { Connector connector = ConnectorTestUtils.getRandomConnector(); String connectorId = randomUUID(); @@ -602,6 +624,32 @@ public void onFailure(Exception e) { return resp.get(); } + private UpdateResponse awaitUpdateConnectorServiceType(UpdateConnectorServiceTypeAction.Request updateServiceTypeRequest) + throws Exception { + CountDownLatch latch = new CountDownLatch(1); + final AtomicReference resp = new AtomicReference<>(null); + final AtomicReference exc = new AtomicReference<>(null); + connectorIndexService.updateConnectorServiceType(updateServiceTypeRequest, new ActionListener<>() { + @Override + public void onResponse(UpdateResponse indexResponse) { + resp.set(indexResponse); + latch.countDown(); + } + + @Override + public void onFailure(Exception e) { + exc.set(e); + latch.countDown(); + } + }); + assertTrue("Timeout waiting for update service type request", latch.await(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS)); + if (exc.get() != null) { + throw exc.get(); + } + assertNotNull("Received null response from update service type request", resp.get()); + return resp.get(); + } + private UpdateResponse awaitUpdateConnectorName(UpdateConnectorNameAction.Request updatedNameOrDescription) throws Exception { CountDownLatch latch = new CountDownLatch(1); final AtomicReference resp = new AtomicReference<>(null); diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/UpdateConnectorServiceTypeActionRequestBWCSerializingTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/UpdateConnectorServiceTypeActionRequestBWCSerializingTests.java new file mode 100644 index 0000000000000..a30e0a6b8d493 --- /dev/null +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/UpdateConnectorServiceTypeActionRequestBWCSerializingTests.java @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.action; + +import org.elasticsearch.TransportVersion; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xpack.core.ml.AbstractBWCSerializationTestCase; + +import java.io.IOException; + +public class UpdateConnectorServiceTypeActionRequestBWCSerializingTests extends AbstractBWCSerializationTestCase< + UpdateConnectorServiceTypeAction.Request> { + + private String connectorId; + + @Override + protected Writeable.Reader instanceReader() { + return UpdateConnectorServiceTypeAction.Request::new; + } + + @Override + protected UpdateConnectorServiceTypeAction.Request createTestInstance() { + this.connectorId = randomUUID(); + return new UpdateConnectorServiceTypeAction.Request(connectorId, randomAlphaOfLengthBetween(3, 10)); + } + + @Override + protected UpdateConnectorServiceTypeAction.Request mutateInstance(UpdateConnectorServiceTypeAction.Request instance) + throws IOException { + return randomValueOtherThan(instance, this::createTestInstance); + } + + @Override + protected UpdateConnectorServiceTypeAction.Request doParseInstance(XContentParser parser) throws IOException { + return UpdateConnectorServiceTypeAction.Request.fromXContent(parser, this.connectorId); + } + + @Override + protected UpdateConnectorServiceTypeAction.Request mutateInstanceForVersion( + UpdateConnectorServiceTypeAction.Request instance, + TransportVersion version + ) { + return instance; + } +} diff --git a/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java b/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java index 30c159782f1e1..d4d0bded045f6 100644 --- a/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java +++ b/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java @@ -137,6 +137,7 @@ public class Constants { "cluster:admin/xpack/connector/update_native", "cluster:admin/xpack/connector/update_pipeline", "cluster:admin/xpack/connector/update_scheduling", + "cluster:admin/xpack/connector/update_service_type", "cluster:admin/xpack/connector/sync_job/cancel", "cluster:admin/xpack/connector/sync_job/check_in", "cluster:admin/xpack/connector/sync_job/delete", From ef630a630483468eab309364b3e3e3bda11817a7 Mon Sep 17 00:00:00 2001 From: Benjamin Trent Date: Wed, 24 Jan 2024 09:47:07 -0500 Subject: [PATCH 05/37] adding known issue for int8_hnsw (#104664) --- docs/reference/release-notes/8.12.0.asciidoc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/reference/release-notes/8.12.0.asciidoc b/docs/reference/release-notes/8.12.0.asciidoc index 468f81145c391..267f00192ecdc 100644 --- a/docs/reference/release-notes/8.12.0.asciidoc +++ b/docs/reference/release-notes/8.12.0.asciidoc @@ -3,13 +3,22 @@ Also see <>. +[[known-issues-8.12.0]] +[float] +=== Known issues + +* `int8_hnsw` vector index format may fail to merge segments and prevent from indexing documents (issue: {es-issue}104617[#104617]) ++ +When using `int8_hnsw` and the default `confidence_interval` (or any `confidence_interval` less than `1.0`) and when +there are deleted documents in the segments, quantiles may fail to build and prevent merging. + [[breaking-8.12.0]] [float] === Breaking changes There are no breaking changes in 8.12 [[notable-8.12.0]] -[float] +[float] === Notable changes There are notable changes in 8.12 that you need to be aware of but that we do not consider breaking, items that we may consider as notable changes are From 9d3207c863027861e7eec397c72ed2b2e80f1703 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Wed, 24 Jan 2024 15:56:10 +0100 Subject: [PATCH 06/37] Speedup check for dynamic mappers when parsing documents (#104698) The stream + collect operation on empty lists was causing 6% of all allocations during document parsing. Lets have 0-alloc methods to check for this dynamic fields before we do anything about them. --- .../elasticsearch/index/mapper/DocumentParser.java | 2 +- .../index/mapper/DocumentParserContext.java | 14 ++++++++++++++ .../index/mapper/TsidExtractingIdFieldMapper.java | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java b/server/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java index e551c4ee05269..54223e1e692f3 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java @@ -247,7 +247,7 @@ private static DocumentParsingException wrapInDocumentParsingException(DocumentP } static Mapping createDynamicUpdate(DocumentParserContext context) { - if (context.getDynamicMappers().isEmpty() && context.getDynamicRuntimeFields().isEmpty()) { + if (context.hasDynamicMappersOrRuntimeFields() == false) { return null; } RootObjectMapper.Builder rootBuilder = context.updateRoot(); diff --git a/server/src/main/java/org/elasticsearch/index/mapper/DocumentParserContext.java b/server/src/main/java/org/elasticsearch/index/mapper/DocumentParserContext.java index 700f0e492af73..b9dfc83d17683 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/DocumentParserContext.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/DocumentParserContext.java @@ -339,6 +339,20 @@ public final void addDynamicMapper(Mapper mapper) { dynamicMappers.computeIfAbsent(mapper.name(), k -> new ArrayList<>()).add(mapper); } + /** + * @return true if either {@link #getDynamicMappers} or {@link #getDynamicRuntimeFields()} will return a non-empty result + */ + public final boolean hasDynamicMappersOrRuntimeFields() { + return hasDynamicMappers() || dynamicRuntimeFields.isEmpty() == false; + } + + /** + * @return true if either {@link #getDynamicMappers} will return a non-empty mapper list + */ + public final boolean hasDynamicMappers() { + return dynamicMappers.isEmpty() == false; + } + /** * Get dynamic mappers created as a result of parsing an incoming document. Responsible for exposing all the newly created * fields that need to be merged into the existing mappings. Used to create the required mapping update at the end of document parsing. diff --git a/server/src/main/java/org/elasticsearch/index/mapper/TsidExtractingIdFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/TsidExtractingIdFieldMapper.java index 9245e78602eb7..62bd8ec994639 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/TsidExtractingIdFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/TsidExtractingIdFieldMapper.java @@ -113,7 +113,7 @@ public static void createField(DocumentParserContext context, IndexRouting.Extra } long timestamp = timestampFields.get(0).numericValue().longValue(); byte[] suffix = new byte[16]; - String id = createId(context.getDynamicMappers().isEmpty(), routingBuilder, tsid, timestamp, suffix); + String id = createId(context.hasDynamicMappers() == false, routingBuilder, tsid, timestamp, suffix); /* * Make sure that _id from extracting the tsid matches that _id * from extracting the _source. This should be true for all valid From 7ef80f282a066bcdd6ec08e23bafdb192d5a71f3 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Wed, 24 Jan 2024 16:18:56 +0100 Subject: [PATCH 07/37] Fix precision issue in CI for cartesian centroids (#104707) Even with Kahan summation, there is a tiny precisoin loss. We already fixed this before for GeoPoint by using the encode/decode to doc-values quantization in the final display results, and for CartesianPoint we fix by casting the coordinates to float for both the expected and actual results. --- .../xpack/esql/qa/rest/EsqlSpecTestCase.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java index 63f3e27830fa8..58d9fbfbdf8aa 100644 --- a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java +++ b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java @@ -179,8 +179,8 @@ private static Object valueMapper(CsvTestUtils.Type type, Object value) { if (value == null) { return "null"; } - if (type == CsvTestUtils.Type.GEO_POINT) { - // GeoPoint tests are failing in clustered integration tests because of tiny precision differences at very small scales + if (type == CsvTestUtils.Type.GEO_POINT || type == CsvTestUtils.Type.CARTESIAN_POINT) { + // Point tests are failing in clustered integration tests because of tiny precision differences at very small scales if (value instanceof GeoPoint point) { return normalizedGeoPoint(point.getX(), point.getY()); } @@ -188,7 +188,7 @@ private static Object valueMapper(CsvTestUtils.Type type, Object value) { try { Geometry geometry = WellKnownText.fromWKT(GeometryValidator.NOOP, false, wkt); if (geometry instanceof Point point) { - return normalizedGeoPoint(point.getX(), point.getY()); + return normalizedPoint(type, point.getX(), point.getY()); } } catch (Throwable ignored) {} } @@ -196,6 +196,13 @@ private static Object valueMapper(CsvTestUtils.Type type, Object value) { return value.toString(); } + private static String normalizedPoint(CsvTestUtils.Type type, double x, double y) { + if (type == CsvTestUtils.Type.GEO_POINT) { + return normalizedGeoPoint(x, y); + } + return String.format(Locale.ROOT, "POINT (%f %f)", (float) x, (float) y); + } + private static String normalizedGeoPoint(double x, double y) { x = decodeLongitude(encodeLongitude(x)); y = decodeLatitude(encodeLatitude(y)); From 1c29d6e775b499dea792c51b922e792fb6745ecd Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Wed, 24 Jan 2024 16:21:20 +0100 Subject: [PATCH 08/37] Use faster way of making a set from a CHM (#104704) Using the Collections wrapper is less optimal than `new ConcurrentHashMap().keySet(Boolean.TRUE);` solution. With the collection wrapper, mod counts on the CHM are updated on NOOP add calls. For contested concurrent noop updated this solution was benchmarked to be more than 2x as fast and should outperform the Collections wrapper in essentially all cases (not just for the mod count update reasons, it also has fewer virtual calls). --- .../reindex/AbstractAsyncBulkByScrollAction.java | 5 ++--- .../elasticsearch/action/bulk/BulkProcessor2RetryIT.java | 6 +++--- .../org/elasticsearch/action/bulk/BulkProcessorRetryIT.java | 4 ++-- .../common/util/concurrent/ConcurrentCollections.java | 3 +-- .../org/elasticsearch/http/AbstractHttpServerTransport.java | 4 ++-- .../org/elasticsearch/indices/IndexingMemoryController.java | 4 ++-- .../index/shard/IndexShardOperationPermitsTests.java | 5 ++--- .../transport/ClusterConnectionManagerTests.java | 3 +-- .../test/java/org/elasticsearch/compute/OperatorTests.java | 2 +- .../xpack/profiling/TransportGetStackTracesAction.java | 4 ++-- 10 files changed, 18 insertions(+), 22 deletions(-) diff --git a/modules/reindex/src/main/java/org/elasticsearch/reindex/AbstractAsyncBulkByScrollAction.java b/modules/reindex/src/main/java/org/elasticsearch/reindex/AbstractAsyncBulkByScrollAction.java index 609702a58bf84..7a2166e5860b4 100644 --- a/modules/reindex/src/main/java/org/elasticsearch/reindex/AbstractAsyncBulkByScrollAction.java +++ b/modules/reindex/src/main/java/org/elasticsearch/reindex/AbstractAsyncBulkByScrollAction.java @@ -27,6 +27,7 @@ import org.elasticsearch.client.internal.ParentTaskAssigningClient; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.util.concurrent.AbstractRunnable; +import org.elasticsearch.common.util.concurrent.ConcurrentCollections; import org.elasticsearch.core.Nullable; import org.elasticsearch.core.TimeValue; import org.elasticsearch.index.VersionType; @@ -48,13 +49,11 @@ import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.function.BiFunction; @@ -92,7 +91,7 @@ public abstract class AbstractAsyncBulkByScrollAction< protected final Request mainRequest; private final AtomicLong startTime = new AtomicLong(-1); - private final Set destinationIndices = Collections.newSetFromMap(new ConcurrentHashMap<>()); + private final Set destinationIndices = ConcurrentCollections.newConcurrentSet(); private final ParentTaskAssigningClient searchClient; private final ParentTaskAssigningClient bulkClient; diff --git a/server/src/internalClusterTest/java/org/elasticsearch/action/bulk/BulkProcessor2RetryIT.java b/server/src/internalClusterTest/java/org/elasticsearch/action/bulk/BulkProcessor2RetryIT.java index 6a2ab41fae5d6..3768daaa20ffc 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/action/bulk/BulkProcessor2RetryIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/action/bulk/BulkProcessor2RetryIT.java @@ -12,12 +12,12 @@ import org.elasticsearch.action.DocWriteRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.concurrent.ConcurrentCollections; import org.elasticsearch.core.Tuple; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.test.ESIntegTestCase; -import java.util.Collections; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -67,8 +67,8 @@ public void testBulkRejectionLoadWithBackoff() throws Throwable { private void executeBulkRejectionLoad(int maxRetries, boolean rejectedExecutionExpected) throws Throwable { int numberOfAsyncOps = randomIntBetween(600, 700); final CountDownLatch latch = new CountDownLatch(numberOfAsyncOps); - final Set successfulResponses = Collections.newSetFromMap(new ConcurrentHashMap<>()); - final Set> failedResponses = Collections.newSetFromMap(new ConcurrentHashMap<>()); + final Set successfulResponses = ConcurrentCollections.newConcurrentSet(); + final Set> failedResponses = ConcurrentCollections.newConcurrentSet(); assertAcked(prepareCreate(INDEX_NAME)); ensureGreen(); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/action/bulk/BulkProcessorRetryIT.java b/server/src/internalClusterTest/java/org/elasticsearch/action/bulk/BulkProcessorRetryIT.java index 8bd3a6cf02868..cfdaacfae9cfb 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/action/bulk/BulkProcessorRetryIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/action/bulk/BulkProcessorRetryIT.java @@ -10,12 +10,12 @@ import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.concurrent.ConcurrentCollections; import org.elasticsearch.core.TimeValue; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.test.ESIntegTestCase; -import java.util.Collections; import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -61,7 +61,7 @@ private void executeBulkRejectionLoad(BackoffPolicy backoffPolicy, boolean rejec final CorrelatingBackoffPolicy internalPolicy = new CorrelatingBackoffPolicy(backoffPolicy); int numberOfAsyncOps = randomIntBetween(600, 700); final CountDownLatch latch = new CountDownLatch(numberOfAsyncOps); - final Set responses = Collections.newSetFromMap(new ConcurrentHashMap<>()); + final Set responses = ConcurrentCollections.newConcurrentSet(); assertAcked(prepareCreate(INDEX_NAME)); ensureGreen(); diff --git a/server/src/main/java/org/elasticsearch/common/util/concurrent/ConcurrentCollections.java b/server/src/main/java/org/elasticsearch/common/util/concurrent/ConcurrentCollections.java index e19d828648782..eac85bfbf5740 100644 --- a/server/src/main/java/org/elasticsearch/common/util/concurrent/ConcurrentCollections.java +++ b/server/src/main/java/org/elasticsearch/common/util/concurrent/ConcurrentCollections.java @@ -8,7 +8,6 @@ package org.elasticsearch.common.util.concurrent; -import java.util.Collections; import java.util.Deque; import java.util.Queue; import java.util.Set; @@ -46,7 +45,7 @@ public static ConcurrentMap newConcurrentMap() { } public static Set newConcurrentSet() { - return Collections.newSetFromMap(ConcurrentCollections.newConcurrentMap()); + return ConcurrentHashMap.newKeySet(); } public static Queue newQueue() { diff --git a/server/src/main/java/org/elasticsearch/http/AbstractHttpServerTransport.java b/server/src/main/java/org/elasticsearch/http/AbstractHttpServerTransport.java index 177e4d471cf30..cfd72bf6ae4a5 100644 --- a/server/src/main/java/org/elasticsearch/http/AbstractHttpServerTransport.java +++ b/server/src/main/java/org/elasticsearch/http/AbstractHttpServerTransport.java @@ -29,6 +29,7 @@ import org.elasticsearch.common.transport.PortsRange; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.common.unit.ByteSizeValue; +import org.elasticsearch.common.util.concurrent.ConcurrentCollections; import org.elasticsearch.common.util.concurrent.FutureUtils; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; @@ -51,7 +52,6 @@ import java.nio.channels.CancelledKeyException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -93,7 +93,7 @@ public abstract class AbstractHttpServerTransport extends AbstractLifecycleCompo private final Map httpChannels = new ConcurrentHashMap<>(); private final PlainActionFuture allClientsClosedListener = new PlainActionFuture<>(); private final RefCounted refCounted = AbstractRefCounted.of(() -> allClientsClosedListener.onResponse(null)); - private final Set httpServerChannels = Collections.newSetFromMap(new ConcurrentHashMap<>()); + private final Set httpServerChannels = ConcurrentCollections.newConcurrentSet(); private final long shutdownGracePeriodMillis; private final HttpClientStatsTracker httpClientStatsTracker; diff --git a/server/src/main/java/org/elasticsearch/indices/IndexingMemoryController.java b/server/src/main/java/org/elasticsearch/indices/IndexingMemoryController.java index c0271ad30d720..9ce2bc201c20f 100644 --- a/server/src/main/java/org/elasticsearch/indices/IndexingMemoryController.java +++ b/server/src/main/java/org/elasticsearch/indices/IndexingMemoryController.java @@ -16,6 +16,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; +import org.elasticsearch.common.util.concurrent.ConcurrentCollections; import org.elasticsearch.common.util.concurrent.EsExecutors; import org.elasticsearch.core.TimeValue; import org.elasticsearch.index.engine.Engine; @@ -35,7 +36,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.ReentrantLock; @@ -108,7 +108,7 @@ public class IndexingMemoryController implements IndexingOperationListener, Clos private final ShardsIndicesStatusChecker statusChecker; - private final Set pendingWriteIndexingBufferSet = Collections.newSetFromMap(new ConcurrentHashMap<>()); + private final Set pendingWriteIndexingBufferSet = ConcurrentCollections.newConcurrentSet(); private final Deque pendingWriteIndexingBufferQueue = new ConcurrentLinkedDeque<>(); IndexingMemoryController(Settings settings, ThreadPool threadPool, Iterable indexServices) { diff --git a/server/src/test/java/org/elasticsearch/index/shard/IndexShardOperationPermitsTests.java b/server/src/test/java/org/elasticsearch/index/shard/IndexShardOperationPermitsTests.java index aa3be82801008..668a47645a17f 100644 --- a/server/src/test/java/org/elasticsearch/index/shard/IndexShardOperationPermitsTests.java +++ b/server/src/test/java/org/elasticsearch/index/shard/IndexShardOperationPermitsTests.java @@ -12,6 +12,7 @@ import org.elasticsearch.action.support.ActionTestUtils; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.concurrent.ConcurrentCollections; import org.elasticsearch.common.util.concurrent.EsExecutors; import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException; import org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor; @@ -29,11 +30,9 @@ import org.junit.BeforeClass; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Set; import java.util.concurrent.BrokenBarrierException; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutionException; @@ -425,7 +424,7 @@ public void testAsyncBlockOperationsRace() throws Exception { final int operations = scaledRandomIntBetween(1, 64); final CyclicBarrier barrier = new CyclicBarrier(1 + 1 + operations); final CountDownLatch operationLatch = new CountDownLatch(1 + operations); - final Set values = Collections.newSetFromMap(new ConcurrentHashMap<>()); + final Set values = ConcurrentCollections.newConcurrentSet(); final List threads = new ArrayList<>(); for (int i = 0; i < operations; i++) { final int value = i; diff --git a/server/src/test/java/org/elasticsearch/transport/ClusterConnectionManagerTests.java b/server/src/test/java/org/elasticsearch/transport/ClusterConnectionManagerTests.java index 59cf83c0c06f3..7ef22abf91b0f 100644 --- a/server/src/test/java/org/elasticsearch/transport/ClusterConnectionManagerTests.java +++ b/server/src/test/java/org/elasticsearch/transport/ClusterConnectionManagerTests.java @@ -38,7 +38,6 @@ import java.util.Collections; import java.util.List; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutionException; @@ -210,7 +209,7 @@ public void testDisconnectLogging() { } public void testConcurrentConnects() throws Exception { - Set connections = Collections.newSetFromMap(new ConcurrentHashMap<>()); + Set connections = ConcurrentCollections.newConcurrentSet(); DiscoveryNode node = DiscoveryNodeUtils.create("", new TransportAddress(InetAddress.getLoopbackAddress(), 0)); doAnswer(invocationOnMock -> { diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/OperatorTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/OperatorTests.java index 45a019328940c..bce4d2b0a454a 100644 --- a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/OperatorTests.java +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/OperatorTests.java @@ -97,7 +97,7 @@ public void testQueryOperator() throws IOException { LuceneOperator.Factory factory = luceneOperatorFactory(reader, query, LuceneOperator.NO_LIMIT); List drivers = new ArrayList<>(); try { - Set actualDocIds = Collections.newSetFromMap(ConcurrentCollections.newConcurrentMap()); + Set actualDocIds = ConcurrentCollections.newConcurrentSet(); for (int t = 0; t < factory.taskConcurrency(); t++) { PageConsumerOperator docCollector = new PageConsumerOperator(page -> { DocVector docVector = page.getBlock(0).asVector(); diff --git a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/TransportGetStackTracesAction.java b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/TransportGetStackTracesAction.java index 6ac28bd90d1fa..29d9fcb314363 100644 --- a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/TransportGetStackTracesAction.java +++ b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/TransportGetStackTracesAction.java @@ -503,8 +503,8 @@ private StackTraceHandler( this.clusterState = clusterState; this.stackTracePerId = new ConcurrentHashMap<>(stackTraceCount); // pre-size with a bit of headroom so the collection isn't resized too often - this.stackFrameIds = Collections.newSetFromMap(new ConcurrentHashMap<>(stackTraceCount * 5)); - this.executableIds = Collections.newSetFromMap(new ConcurrentHashMap<>(stackTraceCount)); + this.stackFrameIds = ConcurrentHashMap.newKeySet(stackTraceCount * 5); + this.executableIds = ConcurrentHashMap.newKeySet(stackTraceCount); this.expectedResponses = new AtomicInteger(expectedResponses); this.client = client; this.responseBuilder = responseBuilder; From 324d35fb2143c82672d1196e58fbc7e4a6ed73e4 Mon Sep 17 00:00:00 2001 From: Jan Kuipers <148754765+jan-elastic@users.noreply.github.com> Date: Wed, 24 Jan 2024 16:46:04 +0100 Subject: [PATCH 09/37] Also allow test_grok_pattern's content passed by query param (#104714) Fixes: https://github.com/elastic/elasticsearch/issues/104708 --- .../xpack/textstructure/rest/RestTestGrokPatternAction.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/x-pack/plugin/text-structure/src/main/java/org/elasticsearch/xpack/textstructure/rest/RestTestGrokPatternAction.java b/x-pack/plugin/text-structure/src/main/java/org/elasticsearch/xpack/textstructure/rest/RestTestGrokPatternAction.java index 2aa52da619b8b..c13534b6f90c2 100644 --- a/x-pack/plugin/text-structure/src/main/java/org/elasticsearch/xpack/textstructure/rest/RestTestGrokPatternAction.java +++ b/x-pack/plugin/text-structure/src/main/java/org/elasticsearch/xpack/textstructure/rest/RestTestGrokPatternAction.java @@ -14,7 +14,6 @@ import org.elasticsearch.rest.ServerlessScope; import org.elasticsearch.rest.action.RestToXContentListener; import org.elasticsearch.xcontent.XContentParser; -import org.elasticsearch.xpack.core.textstructure.action.FindStructureAction; import org.elasticsearch.xpack.core.textstructure.action.TestGrokPatternAction; import java.io.IOException; @@ -40,8 +39,8 @@ public List routes() { @Override protected RestChannelConsumer prepareRequest(RestRequest restRequest, NodeClient client) throws IOException { TestGrokPatternAction.Request request; - String ecsCompatibility = restRequest.param(FindStructureAction.Request.ECS_COMPATIBILITY.getPreferredName()); - try (XContentParser parser = restRequest.contentParser()) { + String ecsCompatibility = restRequest.param(TestGrokPatternAction.Request.ECS_COMPATIBILITY.getPreferredName()); + try (XContentParser parser = restRequest.contentOrSourceParamParser()) { request = TestGrokPatternAction.Request.parseRequest(ecsCompatibility, parser); } From 30f963960e3e030459e42e855294612441e92871 Mon Sep 17 00:00:00 2001 From: David Turner Date: Wed, 24 Jan 2024 17:52:54 +0000 Subject: [PATCH 10/37] Improve S3 storage class docs (#104599) Moves some of the detail about S3 storage classes to their own section for easier linking, and adds a note about `intelligent_tiering` archive classes. --- .../snapshot-restore/repository-s3.asciidoc | 47 ++++++++++++++----- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/docs/reference/snapshot-restore/repository-s3.asciidoc b/docs/reference/snapshot-restore/repository-s3.asciidoc index e204061c28458..b01f7322f9834 100644 --- a/docs/reference/snapshot-restore/repository-s3.asciidoc +++ b/docs/reference/snapshot-restore/repository-s3.asciidoc @@ -296,18 +296,10 @@ include::repository-shared-settings.asciidoc[] `storage_class`:: - Sets the S3 storage class for objects stored in the snapshot repository. - Values may be `standard`, `reduced_redundancy`, `standard_ia`, `onezone_ia` - and `intelligent_tiering`. Defaults to `standard`. Changing this setting on - an existing repository only affects the storage class for newly created - objects, resulting in a mixed usage of storage classes. You may use an S3 - Lifecycle Policy to adjust the storage class of existing objects in your - repository, but you must not transition objects to Glacier classes and you - must not expire objects. If you use Glacier storage classes or object - expiry then you may permanently lose access to your repository contents. - For more information about S3 storage classes, see - https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html[AWS - Storage Classes Guide] + Sets the S3 storage class for objects written to the repository. Values may + be `standard`, `reduced_redundancy`, `standard_ia`, `onezone_ia` and + `intelligent_tiering`. Defaults to `standard`. See + <> for more information. NOTE: The option of defining client settings in the repository settings as documented below is considered deprecated, and will be removed in a future @@ -338,6 +330,37 @@ PUT _snapshot/my_s3_repository This sets up a repository that uses all client settings from the client `my_client_name` except for the `endpoint` that is overridden to `my.s3.endpoint` by the repository settings. +` +[[repository-s3-storage-classes]] +==== S3 storage classes + +Amazon S3 supports a variety of _storage classes_, each of which offers +different operational characteristics. For instance, some classes cost less per +byte stored per month, but cost more per request, and other classes may vary in +terms of their availability guarantees. + +You may specify the storage class that {es} uses to store data objects with the +`storage_class` repository setting. + +Changing the `storage_class` setting on an existing repository only affects the +storage class for newly created objects, resulting in a mixed usage of storage +classes. + +You may use an S3 Lifecycle Policy to adjust the storage class of existing +objects in your repository, but you must not transition objects to an +unsupported class such as the Glacier classes, and you must not expire objects. +If you use a Glacier storage class, or another unsupported storage class, or +object expiry, then you may permanently lose access to your repository +contents. + +You may use the `intellligent_tiering` storage class to automatically manage +the class of objects, but you must not enable the optional Archive Access or +Deep Archive Access tiers. If you use these tiers then you may permanently lose +access to your repository contents. + +For more information about S3 storage classes, see +https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html[AWS +Storage Classes Guide]. [[repository-s3-permissions]] ==== Recommended S3 permissions From 83634375f97ab75d59c03538eeaacb57acafd217 Mon Sep 17 00:00:00 2001 From: David Turner Date: Wed, 24 Jan 2024 18:26:14 +0000 Subject: [PATCH 11/37] TestGrokPatternAction is local-only (#104710) Misc tidy-up following #104394: - This action only runs on the coordinating node, no need to define wire serialization for its request/response types. - No need to subclass `ActionType`, nor to define how to receive responses from remote clusters. - Moves to executing an `AbstractRunnable` to be sure to handle all failures (including threadpool rejections) properly. --- .../action/TestGrokPatternAction.java | 32 ++++--------------- .../TransportTestGrokPatternAction.java | 27 +++++----------- 2 files changed, 15 insertions(+), 44 deletions(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/textstructure/action/TestGrokPatternAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/textstructure/action/TestGrokPatternAction.java index 2751abedbfaf5..ad8cd00fbff6e 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/textstructure/action/TestGrokPatternAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/textstructure/action/TestGrokPatternAction.java @@ -11,8 +11,8 @@ import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.ActionType; +import org.elasticsearch.action.support.TransportAction; import org.elasticsearch.common.Strings; -import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.grok.GrokCaptureExtracter; @@ -28,14 +28,11 @@ import java.util.Map; import java.util.Objects; -public class TestGrokPatternAction extends ActionType { +public class TestGrokPatternAction { - public static final TestGrokPatternAction INSTANCE = new TestGrokPatternAction(); - public static final String NAME = "cluster:monitor/text_structure/test_grok_pattern"; - - private TestGrokPatternAction() { - super(NAME, Response::new); - } + public static final ActionType INSTANCE = ActionType.localOnly( + "cluster:monitor/text_structure/test_grok_pattern" + ); public static class Request extends ActionRequest { @@ -87,23 +84,13 @@ private Request(String grokPattern, List text, String ecsCompatibility) this.ecsCompatibility = ecsCompatibility; } - public Request(StreamInput in) throws IOException { - super(in); - grokPattern = in.readString(); - text = in.readStringCollectionAsList(); - ecsCompatibility = in.readOptionalString(); - } - public static Request parseRequest(String ecsCompatibility, XContentParser parser) throws IOException { return PARSER.parse(parser, null).ecsCompatibility(ecsCompatibility).build(); } @Override public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(grokPattern); - out.writeStringCollection(text); - out.writeOptionalString(ecsCompatibility); + TransportAction.localOnly(); } public String getGrokPattern() { @@ -150,11 +137,6 @@ public Response(List> ranges) { this.ranges = ranges; } - public Response(StreamInput in) throws IOException { - super(in); - ranges = in.readCollectionAsList(StreamInput::readGenericMap); - } - @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); @@ -193,7 +175,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws @Override public void writeTo(StreamOutput out) throws IOException { - out.writeGenericList(ranges, StreamOutput::writeGenericMap); + TransportAction.localOnly(); } } } diff --git a/x-pack/plugin/text-structure/src/main/java/org/elasticsearch/xpack/textstructure/transport/TransportTestGrokPatternAction.java b/x-pack/plugin/text-structure/src/main/java/org/elasticsearch/xpack/textstructure/transport/TransportTestGrokPatternAction.java index 6712e7a5ad68a..f8ce7a1099952 100644 --- a/x-pack/plugin/text-structure/src/main/java/org/elasticsearch/xpack/textstructure/transport/TransportTestGrokPatternAction.java +++ b/x-pack/plugin/text-structure/src/main/java/org/elasticsearch/xpack/textstructure/transport/TransportTestGrokPatternAction.java @@ -10,15 +10,16 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.ActionRunnable; import org.elasticsearch.action.support.ActionFilters; -import org.elasticsearch.action.support.HandledTransportAction; +import org.elasticsearch.action.support.TransportAction; import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.util.concurrent.EsExecutors; import org.elasticsearch.grok.Grok; import org.elasticsearch.grok.GrokBuiltinPatterns; import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; +import org.elasticsearch.transport.Transports; import org.elasticsearch.xpack.core.textstructure.action.TestGrokPatternAction; import java.util.ArrayList; @@ -27,7 +28,7 @@ import static org.elasticsearch.grok.GrokBuiltinPatterns.ECS_COMPATIBILITY_V1; -public class TransportTestGrokPatternAction extends HandledTransportAction { +public class TransportTestGrokPatternAction extends TransportAction { private static final Logger logger = LogManager.getLogger(TransportTestGrokPatternAction.class); @@ -35,30 +36,18 @@ public class TransportTestGrokPatternAction extends HandledTransportAction listener) { - // As matching a regular expression might take a while, we run - // in a different thread to avoid blocking the network thread. - threadPool.generic().execute(() -> { - try { - listener.onResponse(getResponse(request)); - } catch (Exception e) { - listener.onFailure(e); - } - }); + // As matching a regular expression might take a while, we run in a different thread to avoid blocking the network thread. + threadPool.generic().execute(ActionRunnable.supply(listener, () -> getResponse(request))); } private TestGrokPatternAction.Response getResponse(TestGrokPatternAction.Request request) { + assert Transports.assertNotTransportThread("matching regexes is too expensive for a network thread"); boolean ecsCompatibility = ECS_COMPATIBILITY_V1.equals(request.getEcsCompatibility()); Grok grok = new Grok(GrokBuiltinPatterns.get(ecsCompatibility), request.getGrokPattern(), logger::debug); List> ranges = new ArrayList<>(); From ab8ee60bba2e8a52463360b58fa20e18b9f119a1 Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Wed, 24 Jan 2024 19:44:31 +0100 Subject: [PATCH 12/37] Fix SamlAuthenticationIT flakyness (#103867) --- .buildkite/scripts/fixture-deploy.sh | 9 ++ .../internal/docker/DockerBuildTask.java | 42 +++++-- distribution/docker/build.gradle | 4 +- .../DockerEnvironmentAwareTestContainer.java | 6 +- x-pack/qa/saml-idp-tests/build.gradle | 2 +- .../authc/saml/SamlAuthenticationIT.java | 2 - x-pack/test/idp-fixture/build.gradle | 27 ++++ .../test/fixtures/idp/IdpTestContainer.java | 117 +----------------- .../fixtures/idp/OpenLdapTestContainer.java | 35 +----- .../src/main/resources/idp/Dockerfile | 17 +-- .../src/main/resources/openldap/Dockerfile | 17 +++ 11 files changed, 108 insertions(+), 170 deletions(-) create mode 100755 .buildkite/scripts/fixture-deploy.sh create mode 100644 x-pack/test/idp-fixture/src/main/resources/openldap/Dockerfile diff --git a/.buildkite/scripts/fixture-deploy.sh b/.buildkite/scripts/fixture-deploy.sh new file mode 100755 index 0000000000000..3c30b3a3176d2 --- /dev/null +++ b/.buildkite/scripts/fixture-deploy.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -euo pipefail + +echo "$DOCKER_REGISTRY_PASSWORD" | docker login -u "$DOCKER_REGISTRY_USERNAME" --password-stdin docker.elastic.co +unset DOCKER_REGISTRY_USERNAME DOCKER_REGISTRY_PASSWORD + +docker buildx create --use +.ci/scripts/run-gradle.sh deployFixtureDockerImages diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/docker/DockerBuildTask.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/docker/DockerBuildTask.java index 20f46990815bd..4b5eac1a2e379 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/docker/DockerBuildTask.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/docker/DockerBuildTask.java @@ -20,8 +20,10 @@ import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.MapProperty; import org.gradle.api.provider.Property; +import org.gradle.api.provider.SetProperty; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputDirectory; +import org.gradle.api.tasks.Optional; import org.gradle.api.tasks.OutputFile; import org.gradle.api.tasks.PathSensitive; import org.gradle.api.tasks.PathSensitivity; @@ -36,6 +38,7 @@ import java.nio.file.Files; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; import javax.inject.Inject; @@ -43,7 +46,7 @@ * This task wraps up the details of building a Docker image, including adding a pull * mechanism that can retry, and emitting the image SHA as a task output. */ -public class DockerBuildTask extends DefaultTask { +public abstract class DockerBuildTask extends DefaultTask { private static final Logger LOGGER = Logging.getLogger(DockerBuildTask.class); private final WorkerExecutor workerExecutor; @@ -55,7 +58,6 @@ public class DockerBuildTask extends DefaultTask { private boolean noCache = true; private String[] baseImages; private MapProperty buildArgs; - private Property platform; @Inject public DockerBuildTask(WorkerExecutor workerExecutor, ObjectFactory objectFactory, ProjectLayout projectLayout) { @@ -63,7 +65,6 @@ public DockerBuildTask(WorkerExecutor workerExecutor, ObjectFactory objectFactor this.markerFile = objectFactory.fileProperty(); this.dockerContext = objectFactory.directoryProperty(); this.buildArgs = objectFactory.mapProperty(String.class, String.class); - this.platform = objectFactory.property(String.class).convention(Architecture.current().dockerPlatform); this.markerFile.set(projectLayout.getBuildDirectory().file("markers/" + this.getName() + ".marker")); } @@ -75,9 +76,10 @@ public void build() { params.getTags().set(Arrays.asList(tags)); params.getPull().set(pull); params.getNoCache().set(noCache); + params.getPush().set(getPush().getOrElse(false)); params.getBaseImages().set(Arrays.asList(baseImages)); params.getBuildArgs().set(buildArgs); - params.getPlatform().set(platform); + params.getPlatforms().set(getPlatforms()); }); } @@ -129,9 +131,11 @@ public MapProperty getBuildArgs() { } @Input - public Property getPlatform() { - return platform; - } + public abstract SetProperty getPlatforms(); + + @Input + @Optional + public abstract Property getPush(); @OutputFile public RegularFileProperty getMarkerFile() { @@ -181,7 +185,7 @@ public void execute() { } final List tags = parameters.getTags().get(); - final boolean isCrossPlatform = parameters.getPlatform().get().equals(Architecture.current().dockerPlatform) == false; + final boolean isCrossPlatform = isCrossPlatform(); LoggedExec.exec(execOperations, spec -> { spec.executable("docker"); @@ -193,7 +197,7 @@ public void execute() { spec.args("build", parameters.getDockerContext().get().getAsFile().getAbsolutePath()); if (isCrossPlatform) { - spec.args("--platform", parameters.getPlatform().get()); + spec.args("--platform", parameters.getPlatforms().get().stream().collect(Collectors.joining(","))); } if (parameters.getNoCache().get()) { @@ -203,11 +207,20 @@ public void execute() { tags.forEach(tag -> spec.args("--tag", tag)); parameters.getBuildArgs().get().forEach((k, v) -> spec.args("--build-arg", k + "=" + v)); + + if (parameters.getPush().getOrElse(false)) { + spec.args("--push"); + } }); // Fetch the Docker image's hash, and write it to desk as the task's output. Doing this allows us // to do proper up-to-date checks in Gradle. try { + // multi-platform image builds do not end up in local registry, so we need to pull the just build image + // first to get the checksum and also serves as a test for the image being pushed correctly + if (parameters.getPlatforms().get().size() > 1 && parameters.getPush().getOrElse(false)) { + pullBaseImage(tags.get(0)); + } final String checksum = getImageChecksum(tags.get(0)); Files.writeString(parameters.getMarkerFile().getAsFile().get().toPath(), checksum + "\n"); } catch (IOException e) { @@ -215,6 +228,13 @@ public void execute() { } } + private boolean isCrossPlatform() { + return getParameters().getPlatforms() + .get() + .stream() + .anyMatch(any -> any.equals(Architecture.current().dockerPlatform) == false); + } + private String getImageChecksum(String imageTag) { final ByteArrayOutputStream stdout = new ByteArrayOutputStream(); @@ -243,6 +263,8 @@ interface Parameters extends WorkParameters { MapProperty getBuildArgs(); - Property getPlatform(); + SetProperty getPlatforms(); + + Property getPush(); } } diff --git a/distribution/docker/build.gradle b/distribution/docker/build.gradle index 96e577d5635ab..10f4d56c03046 100644 --- a/distribution/docker/build.gradle +++ b/distribution/docker/build.gradle @@ -398,7 +398,7 @@ void addBuildDockerImageTask(Architecture architecture, DockerBase base) { noCache = BuildParams.isCi tags = generateTags(base, architecture) - platform = architecture.dockerPlatform + platforms.add(architecture.dockerPlatform) // We don't build the Iron Bank image when we release Elasticsearch, as there's // separate process for submitting new releases. However, for testing we do a @@ -468,7 +468,7 @@ void addBuildEssDockerImageTask(Architecture architecture) { noCache = BuildParams.isCi baseImages = [] tags = generateTags(base, architecture) - platform = architecture.dockerPlatform + platforms.add(architecture.dockerPlatform) onlyIf("$architecture supported") { isArchitectureSupported(architecture) } } diff --git a/test/fixtures/testcontainer-utils/src/main/java/org/elasticsearch/test/fixtures/testcontainers/DockerEnvironmentAwareTestContainer.java b/test/fixtures/testcontainer-utils/src/main/java/org/elasticsearch/test/fixtures/testcontainers/DockerEnvironmentAwareTestContainer.java index ce4d6fda861cd..be8d597c26010 100644 --- a/test/fixtures/testcontainer-utils/src/main/java/org/elasticsearch/test/fixtures/testcontainers/DockerEnvironmentAwareTestContainer.java +++ b/test/fixtures/testcontainer-utils/src/main/java/org/elasticsearch/test/fixtures/testcontainers/DockerEnvironmentAwareTestContainer.java @@ -16,7 +16,6 @@ import org.testcontainers.DockerClientFactory; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; -import org.testcontainers.images.builder.ImageFromDockerfile; import java.io.File; import java.io.IOException; @@ -27,6 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.Future; import java.util.stream.Collectors; public abstract class DockerEnvironmentAwareTestContainer extends GenericContainer @@ -56,8 +56,8 @@ private static boolean isDockerAvailable() { } } - public DockerEnvironmentAwareTestContainer(ImageFromDockerfile imageFromDockerfile) { - super(imageFromDockerfile); + public DockerEnvironmentAwareTestContainer(Future image) { + super(image); } @Override diff --git a/x-pack/qa/saml-idp-tests/build.gradle b/x-pack/qa/saml-idp-tests/build.gradle index 6a7d60f88a1d7..1c41e58ffb0da 100644 --- a/x-pack/qa/saml-idp-tests/build.gradle +++ b/x-pack/qa/saml-idp-tests/build.gradle @@ -5,9 +5,9 @@ dependencies { javaRestTestImplementation "com.google.jimfs:jimfs:${versions.jimfs}" javaRestTestImplementation "com.google.guava:guava:${versions.jimfs_guava}" javaRestTestImplementation project(":x-pack:test:idp-fixture") + javaRestTestRuntimeOnly "org.slf4j:slf4j-simple:${versions.slf4j}" } - tasks.named("javaRestTest").configure { usesDefaultDistribution() } diff --git a/x-pack/qa/saml-idp-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/saml/SamlAuthenticationIT.java b/x-pack/qa/saml-idp-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/saml/SamlAuthenticationIT.java index 5718930f37c82..c8b3b3fc3aed2 100644 --- a/x-pack/qa/saml-idp-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/saml/SamlAuthenticationIT.java +++ b/x-pack/qa/saml-idp-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/saml/SamlAuthenticationIT.java @@ -28,7 +28,6 @@ import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpCoreContext; import org.apache.http.util.EntityUtils; -import org.apache.lucene.tests.util.LuceneTestCase; import org.elasticsearch.client.Request; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.Response; @@ -92,7 +91,6 @@ /** * An integration test for validating SAML authentication against a real Identity Provider (Shibboleth) */ -@LuceneTestCase.AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/103717") @ThreadLeakFilters(filters = { TestContainersThreadFilter.class }) public class SamlAuthenticationIT extends ESRestTestCase { diff --git a/x-pack/test/idp-fixture/build.gradle b/x-pack/test/idp-fixture/build.gradle index 691483bcfe5c3..b1243b9eb681b 100644 --- a/x-pack/test/idp-fixture/build.gradle +++ b/x-pack/test/idp-fixture/build.gradle @@ -1,3 +1,7 @@ +import org.elasticsearch.gradle.Architecture +import org.elasticsearch.gradle.internal.docker.DockerBuildTask +import org.elasticsearch.gradle.internal.info.BuildParams + apply plugin: 'elasticsearch.java' apply plugin: 'elasticsearch.cache-test-fixtures' @@ -7,3 +11,26 @@ dependencies { api project(':test:fixtures:testcontainer-utils') api "junit:junit:${versions.junit}" } + +tasks.register("deployIdpFixtureDockerImages", DockerBuildTask) { + dockerContext.fileValue(file("src/main/resources/idp")) + baseImages = ["openjdk:11.0.16-jre"] + noCache = BuildParams.isCi + tags = ["docker.elastic.co/elasticsearch-dev/idp-fixture:1.0"] + push = BuildParams.isCI + getPlatforms().addAll( Architecture.values().collect{ it.dockerPlatform } ) +} + + +tasks.register("deployOpenLdapFixtureDockerImages", DockerBuildTask) { + dockerContext.fileValue(file("src/main/resources/openldap")) + baseImages = ["osixia/openldap:1.4.0"] + noCache = BuildParams.isCi + tags = ["docker.elastic.co/elasticsearch-dev/openldap-fixture:1.0"] + push = BuildParams.isCI + getPlatforms().addAll( Architecture.values().collect{ it.dockerPlatform } ) +} + +tasks.register("deployFixtureDockerImages") { + dependsOn tasks.withType(DockerBuildTask) +} diff --git a/x-pack/test/idp-fixture/src/main/java/org/elasticsearch/test/fixtures/idp/IdpTestContainer.java b/x-pack/test/idp-fixture/src/main/java/org/elasticsearch/test/fixtures/idp/IdpTestContainer.java index 692cd4b081411..d76ca5741d8b3 100644 --- a/x-pack/test/idp-fixture/src/main/java/org/elasticsearch/test/fixtures/idp/IdpTestContainer.java +++ b/x-pack/test/idp-fixture/src/main/java/org/elasticsearch/test/fixtures/idp/IdpTestContainer.java @@ -11,8 +11,7 @@ import org.junit.rules.TemporaryFolder; import org.testcontainers.containers.Network; import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; -import org.testcontainers.images.builder.dockerfile.statement.SingleArgumentStatement; +import org.testcontainers.images.RemoteDockerImage; import java.io.IOException; import java.nio.file.Path; @@ -21,8 +20,7 @@ public final class IdpTestContainer extends DockerEnvironmentAwareTestContainer { - public static final String DOCKER_BASE_IMAGE = "openjdk:11.0.16-jre"; - + private static final String DOCKER_BASE_IMAGE = "docker.elastic.co/elasticsearch-dev/idp-fixture:1.0"; private final TemporaryFolder temporaryFolder = new TemporaryFolder(); private Path certsPath; @@ -34,117 +32,10 @@ protected IdpTestContainer() { } public IdpTestContainer(Network network) { - super( - new ImageFromDockerfile("es-idp-testfixture").withDockerfileFromBuilder( - builder -> builder.from(DOCKER_BASE_IMAGE) - .env("jetty_version", "9.3.27.v20190418") - .env("jetty_hash", "7c7c80dd1c9f921771e2b1a05deeeec652d5fcaa") - .env("idp_version", "3.4.3") - .env("idp_hash", "eb86bc7b6366ce2a44f97cae1b014d307b84257e3149469b22b2d091007309db") - .env("dta_hash", "2f547074b06952b94c35631398f36746820a7697") - .env("slf4j_version", "1.7.25") - .env("slf4j_hash", "da76ca59f6a57ee3102f8f9bd9cee742973efa8a") - .env("logback_version", "1.2.3") - .env("logback_classic_hash", "7c4f3c474fb2c041d8028740440937705ebb473a") - .env("logback_core_hash", "864344400c3d4d92dfeb0a305dc87d953677c03c") - .env("logback_access_hash", "e8a841cb796f6423c7afd8738df6e0e4052bf24a") - - .env("JETTY_HOME", "/opt/jetty-home") - .env("JETTY_BASE", "/opt/shib-jetty-base") - .env("PATH", "$PATH:$JAVA_HOME/bin") - .env("JETTY_BROWSER_SSL_KEYSTORE_PASSWORD", "secret") - .env("JETTY_BACKCHANNEL_SSL_KEYSTORE_PASSWORD", "secret") - .env("JETTY_MAX_HEAP", "64m") - // Manually override the jetty keystore otherwise it will attempt to download and fail - .run("mkdir -p /opt/shib-jetty-base/modules") - .copy("idp/jetty-custom/ssl.mod", "/opt/shib-jetty-base/modules/ssl.mod") - .copy("idp/jetty-custom/keystore", "/opt/shib-jetty-base/etc/keystore") - // Download Jetty, verify the hash, and install, initialize a new base - .run( - "wget -q https://repo.maven.apache.org/maven2/org/eclipse/jetty/jetty-distribution/$jetty_version/jetty-distribution-$jetty_version.tar.gz" - + " && echo \"$jetty_hash jetty-distribution-$jetty_version.tar.gz\" | sha1sum -c -" - + " && tar -zxvf jetty-distribution-$jetty_version.tar.gz -C /opt" - + " && ln -s /opt/jetty-distribution-$jetty_version/ /opt/jetty-home" - ) - // Config Jetty - .run( - "mkdir -p /opt/shib-jetty-base/modules /opt/shib-jetty-base/lib/ext /opt/shib-jetty-base/lib/logging /opt/shib-jetty-base/resources" - + " && cd /opt/shib-jetty-base" - + " && touch start.ini" - + " && java -jar ../jetty-home/start.jar --add-to-startd=http,https,deploy,ext,annotations,jstl,rewrite" - ) - // Download Shibboleth IdP, verify the hash, and install - .run( - "wget -q https://shibboleth.net/downloads/identity-provider/archive/$idp_version/shibboleth-identity-provider-$idp_version.tar.gz" - + " && echo \"$idp_hash shibboleth-identity-provider-$idp_version.tar.gz\" | sha256sum -c -" - + " && tar -zxvf shibboleth-identity-provider-$idp_version.tar.gz -C /opt" - + " && ln -s /opt/shibboleth-identity-provider-$idp_version/ /opt/shibboleth-idp" - ) - // Download the library to allow SOAP Endpoints, verify the hash, and place - .run( - "wget -q https://build.shibboleth.net/nexus/content/repositories/releases/net/shibboleth/utilities/jetty9/jetty9-dta-ssl/1.0.0/jetty9-dta-ssl-1.0.0.jar" - + " && echo \"$dta_hash jetty9-dta-ssl-1.0.0.jar\" | sha1sum -c -" - + " && mv jetty9-dta-ssl-1.0.0.jar /opt/shib-jetty-base/lib/ext/" - ) - // Download the slf4j library for Jetty logging, verify the hash, and place - .run( - "wget -q https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/$slf4j_version/slf4j-api-$slf4j_version.jar" - + " && echo \"$slf4j_hash slf4j-api-$slf4j_version.jar\" | sha1sum -c -" - + " && mv slf4j-api-$slf4j_version.jar /opt/shib-jetty-base/lib/logging/" - ) - // Download the logback_classic library for Jetty logging, verify the hash, and place - .run( - "wget -q https://repo.maven.apache.org/maven2/ch/qos/logback/logback-classic/$logback_version/logback-classic-$logback_version.jar" - + " && echo \"$logback_classic_hash logback-classic-$logback_version.jar\" | sha1sum -c -" - + " && mv logback-classic-$logback_version.jar /opt/shib-jetty-base/lib/logging/" - ) - // Download the logback-core library for Jetty logging, verify the hash, and place - .run( - "wget -q https://repo.maven.apache.org/maven2/ch/qos/logback/logback-core/$logback_version/logback-core-$logback_version.jar" - + " && echo \"$logback_core_hash logback-core-$logback_version.jar\" | sha1sum -c -" - + " && mv logback-core-$logback_version.jar /opt/shib-jetty-base/lib/logging/" - ) - // Download the logback-access library for Jetty logging, verify the hash, and place - .run( - "wget -q https://repo.maven.apache.org/maven2/ch/qos/logback/logback-access/$logback_version/logback-access-$logback_version.jar" - + " && echo \"$logback_access_hash logback-access-$logback_version.jar\" | sha1sum -c -" - + " && mv logback-access-$logback_version.jar /opt/shib-jetty-base/lib/logging/" - ) - // ## Copy local files - .copy("idp/shib-jetty-base/", "/opt/shib-jetty-base/") - .copy("idp/shibboleth-idp/", "/opt/shibboleth-idp/") - .copy("idp/bin/", "/usr/local/bin/") - // Setting owner ownership and permissions - .run( - "useradd jetty -U -s /bin/false" - + " && chown -R root:jetty /opt" - + " && chmod -R 640 /opt" - + " && chown -R root:jetty /opt/shib-jetty-base" - + " && chmod -R 640 /opt/shib-jetty-base" - + " && chmod -R 750 /opt/shibboleth-idp/bin" - ) - .run("chmod 750 /usr/local/bin/run-jetty.sh /usr/local/bin/init-idp.sh") - .run("chmod +x /opt/jetty-home/bin/jetty.sh") - // Opening 4443 (browser TLS), 8443 (mutual auth TLS) - .cmd("run-jetty.sh") - .withStatement( - new SingleArgumentStatement( - "HEALTHCHECK", - "CMD curl -f -s --http0.9 http://localhost:4443 " + "--connect-timeout 10 --max-time 10 --output - > /dev/null" - ) - ) - // .expose(4443) - .build() - ) - .withFileFromClasspath("idp/jetty-custom/ssl.mod", "/idp/jetty-custom/ssl.mod") - .withFileFromClasspath("idp/jetty-custom/keystore", "/idp/jetty-custom/keystore") - .withFileFromClasspath("idp/shib-jetty-base/", "/idp/shib-jetty-base/") - .withFileFromClasspath("idp/shibboleth-idp/", "/idp/shibboleth-idp/") - .withFileFromClasspath("idp/bin/", "/idp/bin/") - ); + super(new RemoteDockerImage(DOCKER_BASE_IMAGE)); withNetworkAliases("idp"); withNetwork(network); - waitingFor(Wait.forHealthcheck()); + waitingFor(Wait.forListeningPorts(4443)); addExposedPorts(4443, 8443); } diff --git a/x-pack/test/idp-fixture/src/main/java/org/elasticsearch/test/fixtures/idp/OpenLdapTestContainer.java b/x-pack/test/idp-fixture/src/main/java/org/elasticsearch/test/fixtures/idp/OpenLdapTestContainer.java index 2f65134f2ec72..69d42e8b985a3 100644 --- a/x-pack/test/idp-fixture/src/main/java/org/elasticsearch/test/fixtures/idp/OpenLdapTestContainer.java +++ b/x-pack/test/idp-fixture/src/main/java/org/elasticsearch/test/fixtures/idp/OpenLdapTestContainer.java @@ -10,7 +10,7 @@ import org.elasticsearch.test.fixtures.testcontainers.DockerEnvironmentAwareTestContainer; import org.junit.rules.TemporaryFolder; import org.testcontainers.containers.Network; -import org.testcontainers.images.builder.ImageFromDockerfile; +import org.testcontainers.images.RemoteDockerImage; import java.io.IOException; import java.nio.file.Path; @@ -19,7 +19,7 @@ public final class OpenLdapTestContainer extends DockerEnvironmentAwareTestContainer { - public static final String DOCKER_BASE_IMAGE = "osixia/openldap:1.4.0"; + private static final String DOCKER_BASE_IMAGE = "docker.elastic.co/elasticsearch-dev/openldap-fixture:1.0"; private final TemporaryFolder temporaryFolder = new TemporaryFolder(); private Path certsPath; @@ -29,36 +29,7 @@ public OpenLdapTestContainer() { } public OpenLdapTestContainer(Network network) { - super( - new ImageFromDockerfile("es-openldap-testfixture").withDockerfileFromBuilder( - builder -> builder.from(DOCKER_BASE_IMAGE) - .env("LDAP_ADMIN_PASSWORD", "NickFuryHeartsES") - .env("LDAP_DOMAIN", "oldap.test.elasticsearch.com") - .env("LDAP_BASE_DN", "DC=oldap,DC=test,DC=elasticsearch,DC=com") - .env("LDAP_TLS", "true") - .env("LDAP_TLS_CRT_FILENAME", "ldap_server.pem") - .env("LDAP_TLS_CA_CRT_FILENAME", "ca_server.pem") - .env("LDAP_TLS_KEY_FILENAME", "ldap_server.key") - .env("LDAP_TLS_VERIFY_CLIENT", "never") - .env("LDAP_TLS_CIPHER_SUITE", "NORMAL") - .env("LDAP_LOG_LEVEL", "256") - .copy( - "openldap/ldif/users.ldif", - "/container/service/slapd/assets/config/bootstrap/ldif/custom/20-bootstrap-users.ldif" - ) - .copy( - "openldap/ldif/config.ldif", - "/container/service/slapd/assets/config/bootstrap/ldif/custom/10-bootstrap-config.ldif" - ) - .copy("openldap/certs", "/container/service/slapd/assets/certs") - - .build() - ) - .withFileFromClasspath("openldap/certs", "/openldap/certs/") - .withFileFromClasspath("openldap/ldif/users.ldif", "/openldap/ldif/users.ldif") - .withFileFromClasspath("openldap/ldif/config.ldif", "/openldap/ldif/config.ldif") - ); - // withLogConsumer(new Slf4jLogConsumer(logger())); + super(new RemoteDockerImage(DOCKER_BASE_IMAGE)); withNetworkAliases("openldap"); withNetwork(network); withExposedPorts(389, 636); diff --git a/x-pack/test/idp-fixture/src/main/resources/idp/Dockerfile b/x-pack/test/idp-fixture/src/main/resources/idp/Dockerfile index ea7b6880fb42b..7acb86c05e0e1 100644 --- a/x-pack/test/idp-fixture/src/main/resources/idp/Dockerfile +++ b/x-pack/test/idp-fixture/src/main/resources/idp/Dockerfile @@ -20,12 +20,13 @@ ENV JETTY_HOME=/opt/jetty-home \ JETTY_BASE=/opt/shib-jetty-base \ PATH=$PATH:$JAVA_HOME/bin \ JETTY_BROWSER_SSL_KEYSTORE_PASSWORD=secret \ - JETTY_BACKCHANNEL_SSL_KEYSTORE_PASSWORD=secret - + JETTY_BACKCHANNEL_SSL_KEYSTORE_PASSWORD=secret \ + JETTY_MAX_HEAP=64m + # Manually override the jetty keystore otherwise it will attempt to download and fail RUN mkdir -p /opt/shib-jetty-base/modules -COPY ./idp/jetty-custom/ssl.mod /opt/shib-jetty-base/modules/ssl.mod -COPY ./idp/jetty-custom/keystore /opt/shib-jetty-base/etc/keystore +COPY ./jetty-custom/ssl.mod /opt/shib-jetty-base/modules/ssl.mod +COPY ./jetty-custom/keystore /opt/shib-jetty-base/etc/keystore # Download Jetty, verify the hash, and install, initialize a new base RUN wget -q https://repo.maven.apache.org/maven2/org/eclipse/jetty/jetty-distribution/$jetty_version/jetty-distribution-$jetty_version.tar.gz \ @@ -71,9 +72,9 @@ RUN wget -q https://repo.maven.apache.org/maven2/ch/qos/logback/logback-access/$ && mv logback-access-$logback_version.jar /opt/shib-jetty-base/lib/logging/ ## Copy local files -COPY idp/shib-jetty-base/ /opt/shib-jetty-base/ -COPY idp/shibboleth-idp/ /opt/shibboleth-idp/ -COPY idp/bin/ /usr/local/bin/ +COPY shib-jetty-base/ /opt/shib-jetty-base/ +COPY shibboleth-idp/ /opt/shibboleth-idp/ +COPY bin/ /usr/local/bin/ # Setting owner ownership and permissions RUN useradd jetty -U -s /bin/false \ @@ -86,6 +87,8 @@ RUN useradd jetty -U -s /bin/false \ RUN chmod 750 /usr/local/bin/run-jetty.sh /usr/local/bin/init-idp.sh RUN chmod +x /opt/jetty-home/bin/jetty.sh +RUN apt-get update && apt-get install -y netcat + # Opening 4443 (browser TLS), 8443 (mutual auth TLS) EXPOSE 4443 8443 diff --git a/x-pack/test/idp-fixture/src/main/resources/openldap/Dockerfile b/x-pack/test/idp-fixture/src/main/resources/openldap/Dockerfile new file mode 100644 index 0000000000000..58c9952e2f4b9 --- /dev/null +++ b/x-pack/test/idp-fixture/src/main/resources/openldap/Dockerfile @@ -0,0 +1,17 @@ +FROM osixia/openldap:1.4.0 + + +ENV LDAP_ADMIN_PASSWORD=NickFuryHeartsES +ENV LDAP_DOMAIN=oldap.test.elasticsearch.com +ENV LDAP_BASE_DN=DC=oldap,DC=test,DC=elasticsearch,DC=com +ENV LDAP_TLS=true +ENV LDAP_TLS_CRT_FILENAME=ldap_server.pem +ENV LDAP_TLS_CA_CRT_FILENAME=ca_server.pem +ENV LDAP_TLS_KEY_FILENAME=ldap_server.key +ENV LDAP_TLS_VERIFY_CLIENT=never +ENV LDAP_TLS_CIPHER_SUITE=NORMAL +ENV LDAP_LOG_LEVEL=256 + +COPY ./ldif/users.ldif /container/service/slapd/assets/config/bootstrap/ldif/custom/20-bootstrap-users.ldif +COPY ./ldif/config.ldif /container/service/slapd/assets/config/bootstrap/ldif/custom/10-bootstrap-config.ldif +COPY ./certs /container/service/slapd/assets/certs From 6b910dbac1240155d5098e8fb1ed5939afa71eda Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Wed, 24 Jan 2024 20:12:31 +0100 Subject: [PATCH 13/37] Fix serverless docker setup compatibility (#104724) --- .../elasticsearch/gradle/internal/docker/DockerBuildTask.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/docker/DockerBuildTask.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/docker/DockerBuildTask.java index 4b5eac1a2e379..b84a90259787e 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/docker/DockerBuildTask.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/docker/DockerBuildTask.java @@ -133,6 +133,10 @@ public MapProperty getBuildArgs() { @Input public abstract SetProperty getPlatforms(); + public void setPlatform(String platform) { + getPlatforms().set(Arrays.asList(platform)); + } + @Input @Optional public abstract Property getPush(); From 0f17ff416001c17798199749e57b1d1ab36abc00 Mon Sep 17 00:00:00 2001 From: David Roberts Date: Wed, 24 Jan 2024 20:42:52 +0000 Subject: [PATCH 14/37] [ML] Avoid possible datafeed infinite loop with filtering aggregations (#104722) When advancing a datafeed's search interval past a period with no data, always advance by at least one time chunk. This avoids a problem where the simple aggregation used to advance time might think there is data while the datafeed's own aggregation has filtered it all out. Prior to this change, this could cause the datafeed to go into an infinite loop. After this change the worst that can happen is that we step slowly through a period where filtering inside the datafeed's aggregation is causing empty buckets. Fixes #104699 --- docs/changelog/104722.yaml | 6 ++ .../ml/integration/DatafeedJobsRestIT.java | 85 +++++++++++++++++++ .../chunked/ChunkedDataExtractor.java | 16 ++++ .../chunked/ChunkedDataExtractorTests.java | 14 +-- 4 files changed, 114 insertions(+), 7 deletions(-) create mode 100644 docs/changelog/104722.yaml diff --git a/docs/changelog/104722.yaml b/docs/changelog/104722.yaml new file mode 100644 index 0000000000000..ed9f2d41ff908 --- /dev/null +++ b/docs/changelog/104722.yaml @@ -0,0 +1,6 @@ +pr: 104722 +summary: Avoid possible datafeed infinite loop with filtering aggregations +area: Machine Learning +type: bug +issues: + - 104699 diff --git a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/DatafeedJobsRestIT.java b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/DatafeedJobsRestIT.java index d12672fd4afb0..1f76fe97144a8 100644 --- a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/DatafeedJobsRestIT.java +++ b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/DatafeedJobsRestIT.java @@ -794,6 +794,91 @@ public void testLookbackOnlyGivenAggregationsWithHistogram() throws Exception { assertThat(jobStatsResponseAsString, containsString("\"missing_field_count\":0")); } + /** + * This test confirms the fix for the issue + * where a datafeed with aggregations that filter everything for a bucket can go into an infinite loop. + * In this test the filter in the aggregation is crazy as it literally filters everything. Real users would + * have a filter that only occasionally results in no results from the aggregation while the query alone + * returns data. But the code path that's exercised is the same. + */ + public void testLookbackOnlyGivenAggregationsWithHistogramAndBucketFilter() throws Exception { + String jobId = "aggs-histogram-filter-job"; + Request createJobRequest = new Request("PUT", MachineLearning.BASE_PATH + "anomaly_detectors/" + jobId); + createJobRequest.setJsonEntity(""" + { + "description": "Aggs job with dodgy filter", + "analysis_config": { + "bucket_span": "1h", + "summary_count_field_name": "doc_count", + "detectors": [ + { + "function": "mean", + "field_name": "responsetime", + "by_field_name": "airline" + } + ] + }, + "data_description": {"time_field": "time stamp"} + }"""); + client().performRequest(createJobRequest); + + String datafeedId = "datafeed-" + jobId; + // The "filter_everything" aggregation in here means the output is always empty. + String aggregations = """ + { + "buckets": { + "histogram": { + "field": "time stamp", + "interval": 3600000 + }, + "aggregations": { + "time stamp": { + "max": { + "field": "time stamp" + } + }, + "filter_everything" : { + "filter": { + "term" : { + "airline": "does not exist" + } + }, + "aggregations": { + "airline": { + "terms": { + "field": "airline", + "size": 10 + }, + "aggregations": { + "responsetime": { + "avg": { + "field": "responsetime" + } + } + } + } + } + } + } + } + }"""; + // The chunking timespan of 1 hour here must be less than the span of the data in order for the problem to be reproduced + new DatafeedBuilder(datafeedId, jobId, "airline-data-aggs").setChunkingTimespan("1h").setAggregations(aggregations).build(); + openJob(client(), jobId); + + startDatafeedAndWaitUntilStopped(datafeedId); + waitUntilJobIsClosed(jobId); + Response jobStatsResponse = client().performRequest( + new Request("GET", MachineLearning.BASE_PATH + "anomaly_detectors/" + jobId + "/_stats") + ); + String jobStatsResponseAsString = EntityUtils.toString(jobStatsResponse.getEntity()); + assertThat(jobStatsResponseAsString, containsString("\"input_record_count\":0")); + assertThat(jobStatsResponseAsString, containsString("\"processed_record_count\":0")); + assertThat(jobStatsResponseAsString, containsString("\"bucket_count\":0")); + + // The most important thing this test is asserting is that we don't go into an infinite loop! + } + public void testLookbackOnlyGivenAggregationsWithDateHistogram() throws Exception { String jobId = "aggs-date-histogram-job"; Request createJobRequest = new Request("PUT", MachineLearning.BASE_PATH + "anomaly_detectors/" + jobId); diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/extractor/chunked/ChunkedDataExtractor.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/extractor/chunked/ChunkedDataExtractor.java index 835e0086637e4..567aa68890875 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/extractor/chunked/ChunkedDataExtractor.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/extractor/chunked/ChunkedDataExtractor.java @@ -178,6 +178,22 @@ private Result getNextStream() throws IOException { if (isNewSearch && hasNext()) { // If it was a new search it means it returned 0 results. Thus, // we reconfigure and jump to the next time interval where there are data. + // In theory, if everything is consistent, it would be sufficient to call + // setUpChunkedSearch() here. However, the way that works is to take the + // query from the datafeed config and add on some simple aggregations. + // These aggregations are completely separate from any that might be defined + // in the datafeed config. It is possible that the aggregations in the + // datafeed config rather than the query are responsible for no data being + // found. For example, "filter" or "bucket_selector" aggregations can do this. + // Originally we thought this situation would never happen, with the query + // selecting data and the aggregations just grouping it, but recently we've + // seen cases of users filtering in the aggregations. Therefore, we + // unconditionally advance the start time by one chunk here. setUpChunkedSearch() + // might then advance substantially further, but in the pathological cases + // where setUpChunkedSearch() thinks data exists at the current start time + // while the datafeed's own aggregation doesn't, at least we'll step forward + // a little bit rather than go into an infinite loop. + currentStart += chunkSpan; setUpChunkedSearch(); } } diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/datafeed/extractor/chunked/ChunkedDataExtractorTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/datafeed/extractor/chunked/ChunkedDataExtractorTests.java index 4bbaafa9db0cd..d1f1fdc1ddf6d 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/datafeed/extractor/chunked/ChunkedDataExtractorTests.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/datafeed/extractor/chunked/ChunkedDataExtractorTests.java @@ -431,12 +431,12 @@ public void testExtractionGivenAutoChunkAndIntermediateEmptySearchShouldReconfig InputStream inputStream1 = mock(InputStream.class); - DataExtractor subExtactor1 = new StubSubExtractor(new SearchInterval(100_000L, 200_000L), inputStream1); - when(dataExtractorFactory.newExtractor(100000L, 200000L)).thenReturn(subExtactor1); + DataExtractor subExtractor1 = new StubSubExtractor(new SearchInterval(100_000L, 200_000L), inputStream1); + when(dataExtractorFactory.newExtractor(100000L, 200000L)).thenReturn(subExtractor1); // This one is empty - DataExtractor subExtactor2 = new StubSubExtractor(new SearchInterval(200_000L, 300_000L)); - when(dataExtractorFactory.newExtractor(200000, 300000L)).thenReturn(subExtactor2); + DataExtractor subExtractor2 = new StubSubExtractor(new SearchInterval(200_000L, 300_000L)); + when(dataExtractorFactory.newExtractor(200000, 300000L)).thenReturn(subExtractor2); assertThat(extractor.hasNext(), is(true)); assertEquals(inputStream1, extractor.next().data().get()); @@ -447,8 +447,8 @@ public void testExtractionGivenAutoChunkAndIntermediateEmptySearchShouldReconfig // This is the last one InputStream inputStream2 = mock(InputStream.class); - DataExtractor subExtactor3 = new StubSubExtractor(new SearchInterval(200_000L, 400_000L), inputStream2); - when(dataExtractorFactory.newExtractor(200000, 400000)).thenReturn(subExtactor3); + DataExtractor subExtractor3 = new StubSubExtractor(new SearchInterval(200_000L, 400_000L), inputStream2); + when(dataExtractorFactory.newExtractor(200000, 400000)).thenReturn(subExtractor3); assertEquals(inputStream2, extractor.next().data().get()); assertThat(extractor.next().data().isPresent(), is(false)); @@ -464,7 +464,7 @@ public void testExtractionGivenAutoChunkAndIntermediateEmptySearchShouldReconfig String searchRequest = capturedSearchRequests.get(0).toString().replaceAll("\\s", ""); assertThat(searchRequest, containsString("\"gte\":100000,\"lt\":400000")); searchRequest = capturedSearchRequests.get(1).toString().replaceAll("\\s", ""); - assertThat(searchRequest, containsString("\"gte\":200000,\"lt\":400000")); + assertThat(searchRequest, containsString("\"gte\":300000,\"lt\":400000")); } public void testCancelGivenNextWasNeverCalled() { From eb8c73f4fbf340f58144bd5d60460d9f02f7ca3f Mon Sep 17 00:00:00 2001 From: Jonathan Buttner <56361221+jonathan-buttner@users.noreply.github.com> Date: Wed, 24 Jan 2024 16:14:40 -0500 Subject: [PATCH 15/37] [ML] Adding support for Cohere inference service (#104559) * Starting cohere * Making progress on cohere * Filling out the embedding types * Working cohere * Fixing tests * Removing rate limit error message * Fixing a few comments * Update docs/changelog/104559.yaml * Addressing most feedback * Using separate named writeables for byte results and floats * Fixing a few comments and adding tests * Fixing mutation issue * Removing cohere service settings from named writeable registry --- docs/changelog/104559.yaml | 5 + .../org/elasticsearch/TransportVersions.java | 1 + .../elasticsearch/inference/InputType.java | 16 +- .../org/elasticsearch/inference/Model.java | 14 + .../inference/ModelConfigurations.java | 26 + .../inference/action/InferenceAction.java | 4 +- .../core/inference/results/EmbeddingInt.java | 12 + .../core/inference/results/TextEmbedding.java | 18 + .../results/TextEmbeddingByteResults.java | 146 +++ .../results/TextEmbeddingResults.java | 15 +- .../inference/results/TextEmbeddingUtils.java | 30 + .../inference/src/main/java/module-info.java | 5 - .../InferenceNamedWriteablesProvider.java | 22 + .../xpack/inference/InferencePlugin.java | 4 +- .../external/action/ActionUtils.java | 12 + .../action/cohere/CohereActionCreator.java | 36 + .../action/cohere/CohereActionVisitor.java | 17 + .../action/cohere/CohereEmbeddingsAction.java | 88 ++ .../action/openai/OpenAiEmbeddingsAction.java | 14 +- .../external/cohere/CohereAccount.java | 21 + .../cohere/CohereResponseHandler.java | 87 ++ .../http/retry/ResponseHandlerUtils.java | 22 + .../openai/OpenAiResponseHandler.java | 10 +- .../external/request/RequestUtils.java | 16 + .../cohere/CohereEmbeddingsRequest.java | 93 ++ .../cohere/CohereEmbeddingsRequestEntity.java | 78 ++ .../external/request/cohere/CohereUtils.java | 16 + .../openai/OpenAiEmbeddingsRequest.java | 13 +- .../CohereEmbeddingsResponseEntity.java | 232 +++++ .../cohere/CohereErrorResponseEntity.java | 59 ++ .../inference/services/ServiceUtils.java | 67 +- .../services/cohere/CohereModel.java | 34 + .../services/cohere/CohereService.java | 179 ++++ .../services/cohere/CohereServiceFields.java | 12 + .../cohere/CohereServiceSettings.java | 182 ++++ .../services/cohere/CohereTruncation.java | 42 + .../embeddings/CohereEmbeddingType.java | 41 + .../embeddings/CohereEmbeddingsModel.java | 88 ++ .../CohereEmbeddingsServiceSettings.java | 111 +++ .../CohereEmbeddingsTaskSettings.java | 115 +++ .../HuggingFaceServiceSettings.java | 4 +- .../services/openai/OpenAiModel.java | 10 + .../openai/OpenAiServiceSettings.java | 21 +- .../embeddings/OpenAiEmbeddingsModel.java | 22 +- .../cohere/CohereActionCreatorTests.java | 149 +++ .../cohere/CohereEmbeddingsActionTests.java | 348 +++++++ .../cohere/CohereResponseHandlerTests.java | 126 +++ .../CohereEmbeddingsRequestEntityTests.java | 69 ++ .../cohere/CohereEmbeddingsRequestTests.java | 164 ++++ .../CohereEmbeddingsResponseEntityTests.java | 476 ++++++++++ .../CohereErrorResponseEntityTests.java | 50 + .../TextEmbeddingByteResultsTests.java | 165 ++++ .../inference/services/ServiceUtilsTests.java | 144 ++- .../cohere/CohereServiceSettingsTests.java | 160 ++++ .../services/cohere/CohereServiceTests.java | 895 ++++++++++++++++++ .../CohereEmbeddingsModelTests.java | 108 +++ .../CohereEmbeddingsServiceSettingsTests.java | 167 ++++ .../CohereEmbeddingsTaskSettingsTests.java | 124 +++ .../OpenAiEmbeddingsTaskSettingsTests.java | 15 +- 59 files changed, 5102 insertions(+), 118 deletions(-) create mode 100644 docs/changelog/104559.yaml create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/EmbeddingInt.java create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/TextEmbedding.java create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/TextEmbeddingByteResults.java create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/TextEmbeddingUtils.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereActionCreator.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereActionVisitor.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereEmbeddingsAction.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/cohere/CohereAccount.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/cohere/CohereResponseHandler.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/http/retry/ResponseHandlerUtils.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereEmbeddingsRequest.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereEmbeddingsRequestEntity.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereUtils.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/response/cohere/CohereEmbeddingsResponseEntity.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/response/cohere/CohereErrorResponseEntity.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereModel.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereService.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereServiceFields.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereServiceSettings.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereTruncation.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingType.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsModel.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsServiceSettings.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsTaskSettings.java create mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereActionCreatorTests.java create mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereEmbeddingsActionTests.java create mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/cohere/CohereResponseHandlerTests.java create mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereEmbeddingsRequestEntityTests.java create mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereEmbeddingsRequestTests.java create mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/response/cohere/CohereEmbeddingsResponseEntityTests.java create mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/response/cohere/CohereErrorResponseEntityTests.java create mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/results/TextEmbeddingByteResultsTests.java create mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/CohereServiceSettingsTests.java create mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/CohereServiceTests.java create mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsModelTests.java create mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsServiceSettingsTests.java create mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsTaskSettingsTests.java diff --git a/docs/changelog/104559.yaml b/docs/changelog/104559.yaml new file mode 100644 index 0000000000000..d6d030783c4cc --- /dev/null +++ b/docs/changelog/104559.yaml @@ -0,0 +1,5 @@ +pr: 104559 +summary: Adding support for Cohere inference service +area: Machine Learning +type: enhancement +issues: [] diff --git a/server/src/main/java/org/elasticsearch/TransportVersions.java b/server/src/main/java/org/elasticsearch/TransportVersions.java index 03345ca0a369e..7b3ca0e2f069a 100644 --- a/server/src/main/java/org/elasticsearch/TransportVersions.java +++ b/server/src/main/java/org/elasticsearch/TransportVersions.java @@ -190,6 +190,7 @@ static TransportVersion def(int id) { public static final TransportVersion ESQL_MULTI_CLUSTERS_ENRICH = def(8_576_00_0); public static final TransportVersion NESTED_KNN_MORE_INNER_HITS = def(8_577_00_0); public static final TransportVersion REQUIRE_DATA_STREAM_ADDED = def(8_578_00_0); + public static final TransportVersion ML_INFERENCE_COHERE_EMBEDDINGS_ADDED = def(8_579_00_0); /* * STOP! READ THIS FIRST! No, really, diff --git a/server/src/main/java/org/elasticsearch/inference/InputType.java b/server/src/main/java/org/elasticsearch/inference/InputType.java index f8bbea4ae121f..ffc67995c1dda 100644 --- a/server/src/main/java/org/elasticsearch/inference/InputType.java +++ b/server/src/main/java/org/elasticsearch/inference/InputType.java @@ -8,17 +8,12 @@ package org.elasticsearch.inference; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Writeable; - -import java.io.IOException; import java.util.Locale; /** * Defines the type of request, whether the request is to ingest a document or search for a document. */ -public enum InputType implements Writeable { +public enum InputType { INGEST, SEARCH; @@ -29,12 +24,7 @@ public String toString() { return name().toLowerCase(Locale.ROOT); } - public static InputType fromStream(StreamInput in) throws IOException { - return in.readEnum(InputType.class); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeEnum(this); + public static InputType fromString(String name) { + return valueOf(name.trim().toUpperCase(Locale.ROOT)); } } diff --git a/server/src/main/java/org/elasticsearch/inference/Model.java b/server/src/main/java/org/elasticsearch/inference/Model.java index 02be39d8a653d..e5f1d7936e605 100644 --- a/server/src/main/java/org/elasticsearch/inference/Model.java +++ b/server/src/main/java/org/elasticsearch/inference/Model.java @@ -23,6 +23,20 @@ public Model(ModelConfigurations configurations, ModelSecrets secrets) { this.secrets = Objects.requireNonNull(secrets); } + public Model(Model model, TaskSettings taskSettings) { + Objects.requireNonNull(model); + + configurations = ModelConfigurations.of(model, taskSettings); + secrets = model.getSecrets(); + } + + public Model(Model model, ServiceSettings serviceSettings) { + Objects.requireNonNull(model); + + configurations = ModelConfigurations.of(model, serviceSettings); + secrets = model.getSecrets(); + } + public Model(ModelConfigurations configurations) { this(configurations, new ModelSecrets()); } diff --git a/server/src/main/java/org/elasticsearch/inference/ModelConfigurations.java b/server/src/main/java/org/elasticsearch/inference/ModelConfigurations.java index cdccca7eb0c0e..e91f373d55d37 100644 --- a/server/src/main/java/org/elasticsearch/inference/ModelConfigurations.java +++ b/server/src/main/java/org/elasticsearch/inference/ModelConfigurations.java @@ -27,6 +27,32 @@ public class ModelConfigurations implements ToXContentObject, VersionedNamedWrit public static final String TASK_SETTINGS = "task_settings"; private static final String NAME = "inference_model"; + public static ModelConfigurations of(Model model, TaskSettings taskSettings) { + Objects.requireNonNull(model); + Objects.requireNonNull(taskSettings); + + return new ModelConfigurations( + model.getConfigurations().getModelId(), + model.getConfigurations().getTaskType(), + model.getConfigurations().getService(), + model.getServiceSettings(), + taskSettings + ); + } + + public static ModelConfigurations of(Model model, ServiceSettings serviceSettings) { + Objects.requireNonNull(model); + Objects.requireNonNull(serviceSettings); + + return new ModelConfigurations( + model.getConfigurations().getModelId(), + model.getConfigurations().getTaskType(), + model.getConfigurations().getService(), + serviceSettings, + model.getTaskSettings() + ); + } + private final String modelId; private final TaskType taskType; private final String service; diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/InferenceAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/InferenceAction.java index 732bc3d66bedc..30375e36a0e1d 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/InferenceAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/InferenceAction.java @@ -88,7 +88,7 @@ public Request(StreamInput in) throws IOException { } this.taskSettings = in.readGenericMap(); if (in.getTransportVersion().onOrAfter(TransportVersions.ML_INFERENCE_REQUEST_INPUT_TYPE_ADDED)) { - this.inputType = InputType.fromStream(in); + this.inputType = in.readEnum(InputType.class); } else { this.inputType = InputType.INGEST; } @@ -141,7 +141,7 @@ public void writeTo(StreamOutput out) throws IOException { } out.writeGenericMap(taskSettings); if (out.getTransportVersion().onOrAfter(TransportVersions.ML_INFERENCE_REQUEST_INPUT_TYPE_ADDED)) { - inputType.writeTo(out); + out.writeEnum(inputType); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/EmbeddingInt.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/EmbeddingInt.java new file mode 100644 index 0000000000000..05fc8a3cef1b6 --- /dev/null +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/EmbeddingInt.java @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.core.inference.results; + +public interface EmbeddingInt { + int getSize(); +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/TextEmbedding.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/TextEmbedding.java new file mode 100644 index 0000000000000..a185c2938223e --- /dev/null +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/TextEmbedding.java @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.core.inference.results; + +public interface TextEmbedding { + + /** + * Returns the first text embedding entry in the result list's array size. + * @return the size of the text embedding + * @throws IllegalStateException if the list of embeddings is empty + */ + int getFirstEmbeddingSize() throws IllegalStateException; +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/TextEmbeddingByteResults.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/TextEmbeddingByteResults.java new file mode 100644 index 0000000000000..4ffef36359589 --- /dev/null +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/TextEmbeddingByteResults.java @@ -0,0 +1,146 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.core.inference.results; + +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.inference.InferenceResults; +import org.elasticsearch.inference.InferenceServiceResults; +import org.elasticsearch.inference.TaskType; +import org.elasticsearch.xcontent.ToXContentObject; +import org.elasticsearch.xcontent.XContentBuilder; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Writes a text embedding result in the follow json format + * { + * "text_embedding": [ + * { + * "embedding": [ + * 23 + * ] + * }, + * { + * "embedding": [ + * -23 + * ] + * } + * ] + * } + */ +public record TextEmbeddingByteResults(List embeddings) implements InferenceServiceResults, TextEmbedding { + public static final String NAME = "text_embedding_service_byte_results"; + public static final String TEXT_EMBEDDING = TaskType.TEXT_EMBEDDING.toString(); + + public TextEmbeddingByteResults(StreamInput in) throws IOException { + this(in.readCollectionAsList(Embedding::new)); + } + + @Override + public int getFirstEmbeddingSize() { + return TextEmbeddingUtils.getFirstEmbeddingSize(new ArrayList<>(embeddings)); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startArray(TEXT_EMBEDDING); + for (Embedding embedding : embeddings) { + embedding.toXContent(builder, params); + } + builder.endArray(); + return builder; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeCollection(embeddings); + } + + @Override + public String getWriteableName() { + return NAME; + } + + @Override + public List transformToCoordinationFormat() { + return embeddings.stream() + .map(embedding -> embedding.values.stream().mapToDouble(value -> value).toArray()) + .map(values -> new org.elasticsearch.xpack.core.ml.inference.results.TextEmbeddingResults(TEXT_EMBEDDING, values, false)) + .toList(); + } + + @Override + @SuppressWarnings("deprecation") + public List transformToLegacyFormat() { + var legacyEmbedding = new LegacyTextEmbeddingResults( + embeddings.stream().map(embedding -> new LegacyTextEmbeddingResults.Embedding(embedding.toFloats())).toList() + ); + + return List.of(legacyEmbedding); + } + + public Map asMap() { + Map map = new LinkedHashMap<>(); + map.put(TEXT_EMBEDDING, embeddings.stream().map(Embedding::asMap).collect(Collectors.toList())); + + return map; + } + + public record Embedding(List values) implements Writeable, ToXContentObject, EmbeddingInt { + public static final String EMBEDDING = "embedding"; + + public Embedding(StreamInput in) throws IOException { + this(in.readCollectionAsImmutableList(StreamInput::readByte)); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeCollection(values, StreamOutput::writeByte); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + + builder.startArray(EMBEDDING); + for (Byte value : values) { + builder.value(value); + } + builder.endArray(); + + builder.endObject(); + return builder; + } + + @Override + public String toString() { + return Strings.toString(this); + } + + public Map asMap() { + return Map.of(EMBEDDING, values); + } + + public List toFloats() { + return values.stream().map(Byte::floatValue).toList(); + } + + @Override + public int getSize() { + return values().size(); + } + } +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/TextEmbeddingResults.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/TextEmbeddingResults.java index ace5974866038..75eb4ebc19902 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/TextEmbeddingResults.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/TextEmbeddingResults.java @@ -18,6 +18,7 @@ import org.elasticsearch.xcontent.XContentBuilder; import java.io.IOException; +import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -40,7 +41,7 @@ * ] * } */ -public record TextEmbeddingResults(List embeddings) implements InferenceServiceResults { +public record TextEmbeddingResults(List embeddings) implements InferenceServiceResults, TextEmbedding { public static final String NAME = "text_embedding_service_results"; public static final String TEXT_EMBEDDING = TaskType.TEXT_EMBEDDING.toString(); @@ -58,6 +59,11 @@ public TextEmbeddingResults(StreamInput in) throws IOException { ); } + @Override + public int getFirstEmbeddingSize() { + return TextEmbeddingUtils.getFirstEmbeddingSize(new ArrayList<>(embeddings)); + } + @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startArray(TEXT_EMBEDDING); @@ -103,13 +109,18 @@ public Map asMap() { return map; } - public record Embedding(List values) implements Writeable, ToXContentObject { + public record Embedding(List values) implements Writeable, ToXContentObject, EmbeddingInt { public static final String EMBEDDING = "embedding"; public Embedding(StreamInput in) throws IOException { this(in.readCollectionAsImmutableList(StreamInput::readFloat)); } + @Override + public int getSize() { + return values.size(); + } + @Override public void writeTo(StreamOutput out) throws IOException { out.writeCollection(values, StreamOutput::writeFloat); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/TextEmbeddingUtils.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/TextEmbeddingUtils.java new file mode 100644 index 0000000000000..02cb3b878c7fe --- /dev/null +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/results/TextEmbeddingUtils.java @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.core.inference.results; + +import java.util.List; + +public class TextEmbeddingUtils { + + /** + * Returns the first text embedding entry's array size. + * @param embeddings the list of embeddings + * @return the size of the text embedding + * @throws IllegalStateException if the list of embeddings is empty + */ + public static int getFirstEmbeddingSize(List embeddings) throws IllegalStateException { + if (embeddings.isEmpty()) { + throw new IllegalStateException("Embeddings list is empty"); + } + + return embeddings.get(0).getSize(); + } + + private TextEmbeddingUtils() {} + +} diff --git a/x-pack/plugin/inference/src/main/java/module-info.java b/x-pack/plugin/inference/src/main/java/module-info.java index 3879a0a344e06..2d25a48117778 100644 --- a/x-pack/plugin/inference/src/main/java/module-info.java +++ b/x-pack/plugin/inference/src/main/java/module-info.java @@ -22,10 +22,5 @@ exports org.elasticsearch.xpack.inference.registry; exports org.elasticsearch.xpack.inference.rest; exports org.elasticsearch.xpack.inference.services; - exports org.elasticsearch.xpack.inference.external.http.sender; - exports org.elasticsearch.xpack.inference.external.http; - exports org.elasticsearch.xpack.inference.services.elser; - exports org.elasticsearch.xpack.inference.services.huggingface.elser; - exports org.elasticsearch.xpack.inference.services.openai; exports org.elasticsearch.xpack.inference; } diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferenceNamedWriteablesProvider.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferenceNamedWriteablesProvider.java index c632c568fea16..c23e245b5696c 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferenceNamedWriteablesProvider.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferenceNamedWriteablesProvider.java @@ -16,7 +16,11 @@ import org.elasticsearch.inference.TaskSettings; import org.elasticsearch.xpack.core.inference.results.LegacyTextEmbeddingResults; import org.elasticsearch.xpack.core.inference.results.SparseEmbeddingResults; +import org.elasticsearch.xpack.core.inference.results.TextEmbeddingByteResults; import org.elasticsearch.xpack.core.inference.results.TextEmbeddingResults; +import org.elasticsearch.xpack.inference.services.cohere.CohereServiceSettings; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsServiceSettings; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsTaskSettings; import org.elasticsearch.xpack.inference.services.elser.ElserMlNodeServiceSettings; import org.elasticsearch.xpack.inference.services.elser.ElserMlNodeTaskSettings; import org.elasticsearch.xpack.inference.services.huggingface.HuggingFaceServiceSettings; @@ -49,6 +53,9 @@ public static List getNamedWriteables() { namedWriteables.add( new NamedWriteableRegistry.Entry(InferenceServiceResults.class, TextEmbeddingResults.NAME, TextEmbeddingResults::new) ); + namedWriteables.add( + new NamedWriteableRegistry.Entry(InferenceServiceResults.class, TextEmbeddingByteResults.NAME, TextEmbeddingByteResults::new) + ); // Empty default task settings namedWriteables.add(new NamedWriteableRegistry.Entry(TaskSettings.class, EmptyTaskSettings.NAME, EmptyTaskSettings::new)); @@ -87,6 +94,21 @@ public static List getNamedWriteables() { new NamedWriteableRegistry.Entry(TaskSettings.class, OpenAiEmbeddingsTaskSettings.NAME, OpenAiEmbeddingsTaskSettings::new) ); + // Cohere + namedWriteables.add( + new NamedWriteableRegistry.Entry(ServiceSettings.class, CohereServiceSettings.NAME, CohereServiceSettings::new) + ); + namedWriteables.add( + new NamedWriteableRegistry.Entry( + ServiceSettings.class, + CohereEmbeddingsServiceSettings.NAME, + CohereEmbeddingsServiceSettings::new + ) + ); + namedWriteables.add( + new NamedWriteableRegistry.Entry(TaskSettings.class, CohereEmbeddingsTaskSettings.NAME, CohereEmbeddingsTaskSettings::new) + ); + return namedWriteables; } } diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java index 4b3da18008eac..e25b223742edd 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java @@ -54,6 +54,7 @@ import org.elasticsearch.xpack.inference.rest.RestInferenceAction; import org.elasticsearch.xpack.inference.rest.RestPutInferenceModelAction; import org.elasticsearch.xpack.inference.services.ServiceComponents; +import org.elasticsearch.xpack.inference.services.cohere.CohereService; import org.elasticsearch.xpack.inference.services.elser.ElserMlNodeService; import org.elasticsearch.xpack.inference.services.huggingface.HuggingFaceService; import org.elasticsearch.xpack.inference.services.huggingface.elser.HuggingFaceElserService; @@ -155,7 +156,8 @@ public List getInferenceServiceFactories() { ElserMlNodeService::new, context -> new HuggingFaceElserService(httpFactory, serviceComponents), context -> new HuggingFaceService(httpFactory, serviceComponents), - context -> new OpenAiService(httpFactory, serviceComponents) + context -> new OpenAiService(httpFactory, serviceComponents), + context -> new CohereService(httpFactory, serviceComponents) ); } diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/ActionUtils.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/ActionUtils.java index 856146fafcb45..e4d6e39fdf1f2 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/ActionUtils.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/ActionUtils.java @@ -11,9 +11,13 @@ import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.common.Strings; +import org.elasticsearch.core.Nullable; import org.elasticsearch.inference.InferenceServiceResults; import org.elasticsearch.rest.RestStatus; +import java.net.URI; + public class ActionUtils { public static ActionListener wrapFailuresInElasticsearchException( @@ -35,5 +39,13 @@ public static ElasticsearchStatusException createInternalServerError(Throwable e return new ElasticsearchStatusException(message, RestStatus.INTERNAL_SERVER_ERROR, e); } + public static String constructFailedToSendRequestMessage(@Nullable URI uri, String message) { + if (uri != null) { + return Strings.format("Failed to send %s request to [%s]", message, uri); + } + + return Strings.format("Failed to send %s request", message); + } + private ActionUtils() {} } diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereActionCreator.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereActionCreator.java new file mode 100644 index 0000000000000..8c9d70f0a7323 --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereActionCreator.java @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.action.cohere; + +import org.elasticsearch.xpack.inference.external.action.ExecutableAction; +import org.elasticsearch.xpack.inference.external.http.sender.Sender; +import org.elasticsearch.xpack.inference.services.ServiceComponents; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsModel; + +import java.util.Map; +import java.util.Objects; + +/** + * Provides a way to construct an {@link ExecutableAction} using the visitor pattern based on the cohere model type. + */ +public class CohereActionCreator implements CohereActionVisitor { + private final Sender sender; + private final ServiceComponents serviceComponents; + + public CohereActionCreator(Sender sender, ServiceComponents serviceComponents) { + this.sender = Objects.requireNonNull(sender); + this.serviceComponents = Objects.requireNonNull(serviceComponents); + } + + @Override + public ExecutableAction create(CohereEmbeddingsModel model, Map taskSettings) { + var overriddenModel = model.overrideWith(taskSettings); + + return new CohereEmbeddingsAction(sender, overriddenModel, serviceComponents); + } +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereActionVisitor.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereActionVisitor.java new file mode 100644 index 0000000000000..1500d48e3c201 --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereActionVisitor.java @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.action.cohere; + +import org.elasticsearch.xpack.inference.external.action.ExecutableAction; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsModel; + +import java.util.Map; + +public interface CohereActionVisitor { + ExecutableAction create(CohereEmbeddingsModel model, Map taskSettings); +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereEmbeddingsAction.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereEmbeddingsAction.java new file mode 100644 index 0000000000000..55611ab06a641 --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereEmbeddingsAction.java @@ -0,0 +1,88 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.action.cohere; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.inference.InferenceServiceResults; +import org.elasticsearch.xpack.inference.external.action.ExecutableAction; +import org.elasticsearch.xpack.inference.external.cohere.CohereAccount; +import org.elasticsearch.xpack.inference.external.cohere.CohereResponseHandler; +import org.elasticsearch.xpack.inference.external.http.retry.ResponseHandler; +import org.elasticsearch.xpack.inference.external.http.retry.RetrySettings; +import org.elasticsearch.xpack.inference.external.http.retry.RetryingHttpSender; +import org.elasticsearch.xpack.inference.external.http.sender.Sender; +import org.elasticsearch.xpack.inference.external.request.cohere.CohereEmbeddingsRequest; +import org.elasticsearch.xpack.inference.external.response.cohere.CohereEmbeddingsResponseEntity; +import org.elasticsearch.xpack.inference.services.ServiceComponents; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsModel; + +import java.util.List; +import java.util.Objects; + +import static org.elasticsearch.xpack.inference.external.action.ActionUtils.constructFailedToSendRequestMessage; +import static org.elasticsearch.xpack.inference.external.action.ActionUtils.createInternalServerError; +import static org.elasticsearch.xpack.inference.external.action.ActionUtils.wrapFailuresInElasticsearchException; + +public class CohereEmbeddingsAction implements ExecutableAction { + private static final Logger logger = LogManager.getLogger(CohereEmbeddingsAction.class); + private static final ResponseHandler HANDLER = createEmbeddingsHandler(); + + private final CohereAccount account; + private final CohereEmbeddingsModel model; + private final String failedToSendRequestErrorMessage; + private final RetryingHttpSender sender; + + public CohereEmbeddingsAction(Sender sender, CohereEmbeddingsModel model, ServiceComponents serviceComponents) { + this.model = Objects.requireNonNull(model); + this.account = new CohereAccount( + this.model.getServiceSettings().getCommonSettings().getUri(), + this.model.getSecretSettings().apiKey() + ); + this.failedToSendRequestErrorMessage = constructFailedToSendRequestMessage( + this.model.getServiceSettings().getCommonSettings().getUri(), + "Cohere embeddings" + ); + this.sender = new RetryingHttpSender( + Objects.requireNonNull(sender), + serviceComponents.throttlerManager(), + logger, + new RetrySettings(serviceComponents.settings()), + serviceComponents.threadPool() + ); + } + + @Override + public void execute(List input, ActionListener listener) { + try { + CohereEmbeddingsRequest request = new CohereEmbeddingsRequest( + account, + input, + model.getTaskSettings(), + model.getServiceSettings().getCommonSettings().getModel(), + model.getServiceSettings().getEmbeddingType() + ); + ActionListener wrappedListener = wrapFailuresInElasticsearchException( + failedToSendRequestErrorMessage, + listener + ); + + sender.send(request, HANDLER, wrappedListener); + } catch (ElasticsearchException e) { + listener.onFailure(e); + } catch (Exception e) { + listener.onFailure(createInternalServerError(e, failedToSendRequestErrorMessage)); + } + } + + private static ResponseHandler createEmbeddingsHandler() { + return new CohereResponseHandler("cohere text embedding", CohereEmbeddingsResponseEntity::fromResponse); + } +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/openai/OpenAiEmbeddingsAction.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/openai/OpenAiEmbeddingsAction.java index 20128f1168bb9..f7bcd53724168 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/openai/OpenAiEmbeddingsAction.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/action/openai/OpenAiEmbeddingsAction.java @@ -9,7 +9,6 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.core.Nullable; import org.elasticsearch.inference.InferenceServiceResults; import org.elasticsearch.xpack.inference.common.Truncator; import org.elasticsearch.xpack.inference.external.action.ExecutableAction; @@ -20,12 +19,11 @@ import org.elasticsearch.xpack.inference.services.ServiceComponents; import org.elasticsearch.xpack.inference.services.openai.embeddings.OpenAiEmbeddingsModel; -import java.net.URI; import java.util.List; import java.util.Objects; -import static org.elasticsearch.core.Strings.format; import static org.elasticsearch.xpack.inference.common.Truncator.truncate; +import static org.elasticsearch.xpack.inference.external.action.ActionUtils.constructFailedToSendRequestMessage; import static org.elasticsearch.xpack.inference.external.action.ActionUtils.createInternalServerError; import static org.elasticsearch.xpack.inference.external.action.ActionUtils.wrapFailuresInElasticsearchException; @@ -45,18 +43,10 @@ public OpenAiEmbeddingsAction(Sender sender, OpenAiEmbeddingsModel model, Servic this.model.getSecretSettings().apiKey() ); this.client = new OpenAiClient(Objects.requireNonNull(sender), Objects.requireNonNull(serviceComponents)); - this.errorMessage = getErrorMessage(this.model.getServiceSettings().uri()); + this.errorMessage = constructFailedToSendRequestMessage(this.model.getServiceSettings().uri(), "OpenAI embeddings"); this.truncator = Objects.requireNonNull(serviceComponents.truncator()); } - private static String getErrorMessage(@Nullable URI uri) { - if (uri != null) { - return format("Failed to send OpenAI embeddings request to [%s]", uri.toString()); - } - - return "Failed to send OpenAI embeddings request"; - } - @Override public void execute(List input, ActionListener listener) { try { diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/cohere/CohereAccount.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/cohere/CohereAccount.java new file mode 100644 index 0000000000000..9847d496d14ee --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/cohere/CohereAccount.java @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.cohere; + +import org.elasticsearch.common.settings.SecureString; +import org.elasticsearch.core.Nullable; + +import java.net.URI; +import java.util.Objects; + +public record CohereAccount(@Nullable URI url, SecureString apiKey) { + + public CohereAccount { + Objects.requireNonNull(apiKey); + } +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/cohere/CohereResponseHandler.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/cohere/CohereResponseHandler.java new file mode 100644 index 0000000000000..59cf6f4ca52f6 --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/cohere/CohereResponseHandler.java @@ -0,0 +1,87 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.cohere; + +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.logging.log4j.Logger; +import org.elasticsearch.xpack.inference.external.http.HttpResult; +import org.elasticsearch.xpack.inference.external.http.retry.BaseResponseHandler; +import org.elasticsearch.xpack.inference.external.http.retry.ResponseParser; +import org.elasticsearch.xpack.inference.external.http.retry.RetryException; +import org.elasticsearch.xpack.inference.external.response.cohere.CohereErrorResponseEntity; +import org.elasticsearch.xpack.inference.logging.ThrottlerManager; + +import static org.elasticsearch.xpack.inference.external.http.HttpUtils.checkForEmptyBody; + +/** + * Defines how to handle various errors returned from the Cohere integration. + * + * NOTE: + * These headers are returned for trial API keys only (they also do not exist within 429 responses) + * + * + * x-endpoint-monthly-call-limit + * x-trial-endpoint-call-limit + * x-trial-endpoint-call-remaining + * + */ +public class CohereResponseHandler extends BaseResponseHandler { + static final String TEXTS_ARRAY_TOO_LARGE_MESSAGE_MATCHER = "invalid request: total number of texts must be at most"; + static final String TEXTS_ARRAY_ERROR_MESSAGE = "Received a texts array too large response"; + + public CohereResponseHandler(String requestType, ResponseParser parseFunction) { + super(requestType, parseFunction, CohereErrorResponseEntity::fromResponse); + } + + @Override + public void validateResponse(ThrottlerManager throttlerManager, Logger logger, HttpRequestBase request, HttpResult result) + throws RetryException { + checkForFailureStatusCode(request, result); + checkForEmptyBody(throttlerManager, logger, request, result); + } + + /** + * Validates the status code throws an RetryException if not in the range [200, 300). + * + * @param request The http request + * @param result The http response and body + * @throws RetryException Throws if status code is {@code >= 300 or < 200 } + */ + void checkForFailureStatusCode(HttpRequestBase request, HttpResult result) throws RetryException { + int statusCode = result.response().getStatusLine().getStatusCode(); + if (statusCode >= 200 && statusCode < 300) { + return; + } + + // handle error codes + if (statusCode >= 500) { + throw new RetryException(false, buildError(SERVER_ERROR, request, result)); + } else if (statusCode == 429) { + throw new RetryException(true, buildError(RATE_LIMIT, request, result)); + } else if (isTextsArrayTooLarge(result)) { + throw new RetryException(false, buildError(TEXTS_ARRAY_ERROR_MESSAGE, request, result)); + } else if (statusCode == 401) { + throw new RetryException(false, buildError(AUTHENTICATION, request, result)); + } else if (statusCode >= 300 && statusCode < 400) { + throw new RetryException(false, buildError(REDIRECTION, request, result)); + } else { + throw new RetryException(false, buildError(UNSUCCESSFUL, request, result)); + } + } + + private static boolean isTextsArrayTooLarge(HttpResult result) { + int statusCode = result.response().getStatusLine().getStatusCode(); + + if (statusCode == 400) { + var errorEntity = CohereErrorResponseEntity.fromResponse(result); + return errorEntity != null && errorEntity.getErrorMessage().contains(TEXTS_ARRAY_TOO_LARGE_MESSAGE_MATCHER); + } + + return false; + } +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/http/retry/ResponseHandlerUtils.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/http/retry/ResponseHandlerUtils.java new file mode 100644 index 0000000000000..6269c81d4ceb7 --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/http/retry/ResponseHandlerUtils.java @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.http.retry; + +import org.apache.http.HttpResponse; + +public class ResponseHandlerUtils { + public static String getFirstHeaderOrUnknown(HttpResponse response, String name) { + var header = response.getFirstHeader(name); + if (header != null && header.getElements().length > 0) { + return header.getElements()[0].getName(); + } + return "unknown"; + } + + private ResponseHandlerUtils() {} +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/openai/OpenAiResponseHandler.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/openai/OpenAiResponseHandler.java index 40ceb1a968f18..424d25cd0210b 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/openai/OpenAiResponseHandler.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/openai/OpenAiResponseHandler.java @@ -7,7 +7,6 @@ package org.elasticsearch.xpack.inference.external.openai; -import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpRequestBase; import org.apache.logging.log4j.Logger; import org.elasticsearch.common.Strings; @@ -20,6 +19,7 @@ import org.elasticsearch.xpack.inference.logging.ThrottlerManager; import static org.elasticsearch.xpack.inference.external.http.HttpUtils.checkForEmptyBody; +import static org.elasticsearch.xpack.inference.external.http.retry.ResponseHandlerUtils.getFirstHeaderOrUnknown; public class OpenAiResponseHandler extends BaseResponseHandler { /** @@ -115,12 +115,4 @@ static String buildRateLimitErrorMessage(HttpResult result) { return RATE_LIMIT + ". " + usageMessage; } - - private static String getFirstHeaderOrUnknown(HttpResponse response, String name) { - var header = response.getFirstHeader(name); - if (header != null && header.getElements().length > 0) { - return header.getElements()[0].getName(); - } - return "unknown"; - } } diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/RequestUtils.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/RequestUtils.java index 355db7288dacc..6116b1cc234c6 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/RequestUtils.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/RequestUtils.java @@ -10,7 +10,14 @@ import org.apache.http.Header; import org.apache.http.HttpHeaders; import org.apache.http.message.BasicHeader; +import org.elasticsearch.ElasticsearchStatusException; +import org.elasticsearch.common.CheckedSupplier; +import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.SecureString; +import org.elasticsearch.rest.RestStatus; + +import java.net.URI; +import java.net.URISyntaxException; public class RequestUtils { @@ -18,5 +25,14 @@ public static Header createAuthBearerHeader(SecureString apiKey) { return new BasicHeader(HttpHeaders.AUTHORIZATION, "Bearer " + apiKey.toString()); } + public static URI buildUri(URI accountUri, String service, CheckedSupplier uriBuilder) { + try { + return accountUri == null ? uriBuilder.get() : accountUri; + } catch (URISyntaxException e) { + // using bad request here so that potentially sensitive URL information does not get logged + throw new ElasticsearchStatusException(Strings.format("Failed to construct %s URL", service), RestStatus.BAD_REQUEST, e); + } + } + private RequestUtils() {} } diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereEmbeddingsRequest.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereEmbeddingsRequest.java new file mode 100644 index 0000000000000..954ec9039351b --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereEmbeddingsRequest.java @@ -0,0 +1,93 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.request.cohere; + +import org.apache.http.HttpHeaders; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.ByteArrayEntity; +import org.elasticsearch.common.Strings; +import org.elasticsearch.core.Nullable; +import org.elasticsearch.xcontent.XContentType; +import org.elasticsearch.xpack.inference.external.cohere.CohereAccount; +import org.elasticsearch.xpack.inference.external.request.Request; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingType; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsTaskSettings; + +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Objects; + +import static org.elasticsearch.xpack.inference.external.request.RequestUtils.buildUri; +import static org.elasticsearch.xpack.inference.external.request.RequestUtils.createAuthBearerHeader; + +public class CohereEmbeddingsRequest implements Request { + + private final CohereAccount account; + private final List input; + private final URI uri; + private final CohereEmbeddingsTaskSettings taskSettings; + private final String model; + private final CohereEmbeddingType embeddingType; + + public CohereEmbeddingsRequest( + CohereAccount account, + List input, + CohereEmbeddingsTaskSettings taskSettings, + @Nullable String model, + @Nullable CohereEmbeddingType embeddingType + ) { + this.account = Objects.requireNonNull(account); + this.input = Objects.requireNonNull(input); + this.uri = buildUri(this.account.url(), "Cohere", CohereEmbeddingsRequest::buildDefaultUri); + this.taskSettings = Objects.requireNonNull(taskSettings); + this.model = model; + this.embeddingType = embeddingType; + } + + @Override + public HttpRequestBase createRequest() { + HttpPost httpPost = new HttpPost(uri); + + ByteArrayEntity byteEntity = new ByteArrayEntity( + Strings.toString(new CohereEmbeddingsRequestEntity(input, taskSettings, model, embeddingType)).getBytes(StandardCharsets.UTF_8) + ); + httpPost.setEntity(byteEntity); + + httpPost.setHeader(HttpHeaders.CONTENT_TYPE, XContentType.JSON.mediaType()); + httpPost.setHeader(createAuthBearerHeader(account.apiKey())); + + return httpPost; + } + + @Override + public URI getURI() { + return uri; + } + + @Override + public Request truncate() { + return this; + } + + @Override + public boolean[] getTruncationInfo() { + return null; + } + + // default for testing + static URI buildDefaultUri() throws URISyntaxException { + return new URIBuilder().setScheme("https") + .setHost(CohereUtils.HOST) + .setPathSegments(CohereUtils.VERSION_1, CohereUtils.EMBEDDINGS_PATH) + .build(); + } +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereEmbeddingsRequestEntity.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereEmbeddingsRequestEntity.java new file mode 100644 index 0000000000000..a0b5444ee45e4 --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereEmbeddingsRequestEntity.java @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.request.cohere; + +import org.elasticsearch.core.Nullable; +import org.elasticsearch.inference.InputType; +import org.elasticsearch.xcontent.ToXContentObject; +import org.elasticsearch.xcontent.XContentBuilder; +import org.elasticsearch.xpack.inference.services.cohere.CohereServiceFields; +import org.elasticsearch.xpack.inference.services.cohere.CohereServiceSettings; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingType; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsTaskSettings; + +import java.io.IOException; +import java.util.List; +import java.util.Objects; + +public record CohereEmbeddingsRequestEntity( + List input, + CohereEmbeddingsTaskSettings taskSettings, + @Nullable String model, + @Nullable CohereEmbeddingType embeddingType +) implements ToXContentObject { + + private static final String SEARCH_DOCUMENT = "search_document"; + private static final String SEARCH_QUERY = "search_query"; + /** + * Maps the {@link InputType} to the expected value for cohere for the input_type field in the request using the enum's ordinal. + * The order of these entries is important and needs to match the order in the enum + */ + private static final String[] INPUT_TYPE_MAPPING = { SEARCH_DOCUMENT, SEARCH_QUERY }; + static { + assert INPUT_TYPE_MAPPING.length == InputType.values().length : "input type mapping was incorrectly defined"; + } + + private static final String TEXTS_FIELD = "texts"; + + static final String INPUT_TYPE_FIELD = "input_type"; + static final String EMBEDDING_TYPES_FIELD = "embedding_types"; + + public CohereEmbeddingsRequestEntity { + Objects.requireNonNull(input); + Objects.requireNonNull(taskSettings); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field(TEXTS_FIELD, input); + if (model != null) { + builder.field(CohereServiceSettings.MODEL, model); + } + + if (taskSettings.inputType() != null) { + builder.field(INPUT_TYPE_FIELD, covertToString(taskSettings.inputType())); + } + + if (embeddingType != null) { + builder.field(EMBEDDING_TYPES_FIELD, List.of(embeddingType)); + } + + if (taskSettings.truncation() != null) { + builder.field(CohereServiceFields.TRUNCATE, taskSettings.truncation()); + } + + builder.endObject(); + return builder; + } + + private static String covertToString(InputType inputType) { + return INPUT_TYPE_MAPPING[inputType.ordinal()]; + } +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereUtils.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereUtils.java new file mode 100644 index 0000000000000..f8ccd91d4e3d2 --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereUtils.java @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.request.cohere; + +public class CohereUtils { + public static final String HOST = "api.cohere.ai"; + public static final String VERSION_1 = "v1"; + public static final String EMBEDDINGS_PATH = "embed"; + + private CohereUtils() {} +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/openai/OpenAiEmbeddingsRequest.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/openai/OpenAiEmbeddingsRequest.java index 3a9fab44aa04e..9ead692b9e110 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/openai/OpenAiEmbeddingsRequest.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/request/openai/OpenAiEmbeddingsRequest.java @@ -12,9 +12,7 @@ import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.utils.URIBuilder; import org.apache.http.entity.ByteArrayEntity; -import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.common.Strings; -import org.elasticsearch.rest.RestStatus; import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xpack.inference.common.Truncator; import org.elasticsearch.xpack.inference.external.openai.OpenAiAccount; @@ -26,6 +24,7 @@ import java.nio.charset.StandardCharsets; import java.util.Objects; +import static org.elasticsearch.xpack.inference.external.request.RequestUtils.buildUri; import static org.elasticsearch.xpack.inference.external.request.RequestUtils.createAuthBearerHeader; import static org.elasticsearch.xpack.inference.external.request.openai.OpenAiUtils.createOrgHeader; @@ -46,18 +45,10 @@ public OpenAiEmbeddingsRequest( this.truncator = Objects.requireNonNull(truncator); this.account = Objects.requireNonNull(account); this.truncationResult = Objects.requireNonNull(input); - this.uri = buildUri(this.account.url()); + this.uri = buildUri(this.account.url(), "OpenAI", OpenAiEmbeddingsRequest::buildDefaultUri); this.taskSettings = Objects.requireNonNull(taskSettings); } - private static URI buildUri(URI accountUri) { - try { - return accountUri == null ? buildDefaultUri() : accountUri; - } catch (URISyntaxException e) { - throw new ElasticsearchStatusException("Failed to construct OpenAI URL", RestStatus.INTERNAL_SERVER_ERROR, e); - } - } - public HttpRequestBase createRequest() { HttpPost httpPost = new HttpPost(uri); diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/response/cohere/CohereEmbeddingsResponseEntity.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/response/cohere/CohereEmbeddingsResponseEntity.java new file mode 100644 index 0000000000000..bd808c225d7e3 --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/response/cohere/CohereEmbeddingsResponseEntity.java @@ -0,0 +1,232 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.response.cohere; + +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; +import org.elasticsearch.common.xcontent.XContentParserUtils; +import org.elasticsearch.core.CheckedFunction; +import org.elasticsearch.inference.InferenceServiceResults; +import org.elasticsearch.xcontent.XContentFactory; +import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; +import org.elasticsearch.xcontent.XContentType; +import org.elasticsearch.xpack.core.inference.results.TextEmbeddingByteResults; +import org.elasticsearch.xpack.core.inference.results.TextEmbeddingResults; +import org.elasticsearch.xpack.inference.external.http.HttpResult; +import org.elasticsearch.xpack.inference.external.request.Request; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingType; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import static org.elasticsearch.common.xcontent.XContentParserUtils.throwUnknownToken; +import static org.elasticsearch.xpack.inference.external.response.XContentUtils.moveToFirstToken; +import static org.elasticsearch.xpack.inference.external.response.XContentUtils.positionParserAtTokenAfterField; +import static org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingType.toLowerCase; + +public class CohereEmbeddingsResponseEntity { + private static final String FAILED_TO_FIND_FIELD_TEMPLATE = "Failed to find required field [%s] in Cohere embeddings response"; + + private static final Map> EMBEDDING_PARSERS = Map.of( + toLowerCase(CohereEmbeddingType.FLOAT), + CohereEmbeddingsResponseEntity::parseFloatEmbeddingsArray, + toLowerCase(CohereEmbeddingType.INT8), + CohereEmbeddingsResponseEntity::parseByteEmbeddingsArray + ); + private static final String VALID_EMBEDDING_TYPES_STRING = supportedEmbeddingTypes(); + + private static String supportedEmbeddingTypes() { + var validTypes = EMBEDDING_PARSERS.keySet().toArray(String[]::new); + Arrays.sort(validTypes); + return String.join(", ", validTypes); + } + + /** + * Parses the OpenAI json response. + * For a request like: + * + *
+     * 
+     * {
+     *  "texts": ["hello this is my name", "I wish I was there!"]
+     * }
+     * 
+     * 
+ * + * The response would look like: + * + *
+     * 
+     * {
+     *  "id": "da4f9ea6-37e4-41ab-b5e1-9e2985609555",
+     *  "texts": [
+     *      "hello",
+     *      "awesome"
+     *  ],
+     *  "embeddings": [
+     *      [
+     *          123
+     *      ],
+     *      [
+     *          123
+     *      ]
+     *  ],
+     *  "meta": {
+     *      "api_version": {
+     *          "version": "1"
+     *      },
+     *      "warnings": [
+     *          "default model on embed will be deprecated in the future, please specify a model in the request."
+     *      ],
+     *      "billed_units": {
+     *          "input_tokens": 3
+     *      }
+     *  },
+     *  "response_type": "embeddings_floats"
+     * }
+     * 
+     * 
+ * + * Or this: + * + *
+     * 
+     * {
+     *  "id": "da4f9ea6-37e4-41ab-b5e1-9e2985609555",
+     *  "texts": [
+     *      "hello",
+     *      "awesome"
+     *  ],
+     *  "embeddings": {
+     *      "float": [
+     *          [
+     *              123
+     *          ],
+     *          [
+     *              123
+     *          ],
+     *      ]
+     *  },
+     *  "meta": {
+     *      "api_version": {
+     *          "version": "1"
+     *      },
+     *      "warnings": [
+     *          "default model on embed will be deprecated in the future, please specify a model in the request."
+     *      ],
+     *      "billed_units": {
+     *          "input_tokens": 3
+     *      }
+     *  },
+     *  "response_type": "embeddings_floats"
+     * }
+     * 
+     * 
+ */ + public static InferenceServiceResults fromResponse(Request request, HttpResult response) throws IOException { + var parserConfig = XContentParserConfiguration.EMPTY.withDeprecationHandler(LoggingDeprecationHandler.INSTANCE); + + try (XContentParser jsonParser = XContentFactory.xContent(XContentType.JSON).createParser(parserConfig, response.body())) { + moveToFirstToken(jsonParser); + + XContentParser.Token token = jsonParser.currentToken(); + XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, token, jsonParser); + + positionParserAtTokenAfterField(jsonParser, "embeddings", FAILED_TO_FIND_FIELD_TEMPLATE); + + token = jsonParser.currentToken(); + if (token == XContentParser.Token.START_OBJECT) { + return parseEmbeddingsObject(jsonParser); + } else if (token == XContentParser.Token.START_ARRAY) { + // if the request did not specify the embedding types then it will default to floats + return parseFloatEmbeddingsArray(jsonParser); + } else { + throwUnknownToken(token, jsonParser); + } + + // This should never be reached. The above code should either return successfully or hit the throwUnknownToken + // or throw a parsing exception + throw new IllegalStateException("Reached an invalid state while parsing the Cohere response"); + } + } + + private static InferenceServiceResults parseEmbeddingsObject(XContentParser parser) throws IOException { + XContentParser.Token token; + + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + var embeddingValueParser = EMBEDDING_PARSERS.get(parser.currentName()); + if (embeddingValueParser == null) { + continue; + } + + parser.nextToken(); + return embeddingValueParser.apply(parser); + } + } + + throw new IllegalStateException( + Strings.format( + "Failed to find a supported embedding type in the Cohere embeddings response. Supported types are [%s]", + VALID_EMBEDDING_TYPES_STRING + ) + ); + } + + private static InferenceServiceResults parseByteEmbeddingsArray(XContentParser parser) throws IOException { + var embeddingList = XContentParserUtils.parseList(parser, CohereEmbeddingsResponseEntity::parseByteArrayEntry); + + return new TextEmbeddingByteResults(embeddingList); + } + + private static TextEmbeddingByteResults.Embedding parseByteArrayEntry(XContentParser parser) throws IOException { + XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_ARRAY, parser.currentToken(), parser); + List embeddingValues = XContentParserUtils.parseList(parser, CohereEmbeddingsResponseEntity::parseEmbeddingInt8Entry); + + return new TextEmbeddingByteResults.Embedding(embeddingValues); + } + + private static Byte parseEmbeddingInt8Entry(XContentParser parser) throws IOException { + XContentParser.Token token = parser.currentToken(); + XContentParserUtils.ensureExpectedToken(XContentParser.Token.VALUE_NUMBER, token, parser); + var parsedByte = parser.shortValue(); + checkByteBounds(parsedByte); + + return (byte) parsedByte; + } + + private static void checkByteBounds(short value) { + if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) { + throw new IllegalArgumentException("Value [" + value + "] is out of range for a byte"); + } + } + + private static InferenceServiceResults parseFloatEmbeddingsArray(XContentParser parser) throws IOException { + var embeddingList = XContentParserUtils.parseList(parser, CohereEmbeddingsResponseEntity::parseFloatArrayEntry); + + return new TextEmbeddingResults(embeddingList); + } + + private static TextEmbeddingResults.Embedding parseFloatArrayEntry(XContentParser parser) throws IOException { + XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_ARRAY, parser.currentToken(), parser); + List embeddingValues = XContentParserUtils.parseList(parser, CohereEmbeddingsResponseEntity::parseEmbeddingFloatEntry); + + return new TextEmbeddingResults.Embedding(embeddingValues); + } + + private static Float parseEmbeddingFloatEntry(XContentParser parser) throws IOException { + XContentParser.Token token = parser.currentToken(); + XContentParserUtils.ensureExpectedToken(XContentParser.Token.VALUE_NUMBER, token, parser); + return parser.floatValue(); + } + + private CohereEmbeddingsResponseEntity() {} +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/response/cohere/CohereErrorResponseEntity.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/response/cohere/CohereErrorResponseEntity.java new file mode 100644 index 0000000000000..7d1731105e2f5 --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/response/cohere/CohereErrorResponseEntity.java @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.response.cohere; + +import org.elasticsearch.xcontent.XContentFactory; +import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; +import org.elasticsearch.xcontent.XContentType; +import org.elasticsearch.xpack.inference.external.http.HttpResult; +import org.elasticsearch.xpack.inference.external.http.retry.ErrorMessage; + +public class CohereErrorResponseEntity implements ErrorMessage { + + private final String errorMessage; + + private CohereErrorResponseEntity(String errorMessage) { + this.errorMessage = errorMessage; + } + + @Override + public String getErrorMessage() { + return errorMessage; + } + + /** + * An example error response for invalid auth would look like + * + * { + * "message": "invalid request: total number of texts must be at most 96 - received 97" + * } + * + * + * + * @param response The error response + * @return An error entity if the response is JSON with the above structure + * or null if the response does not contain the message field + */ + public static CohereErrorResponseEntity fromResponse(HttpResult response) { + try ( + XContentParser jsonParser = XContentFactory.xContent(XContentType.JSON) + .createParser(XContentParserConfiguration.EMPTY, response.body()) + ) { + var responseMap = jsonParser.map(); + var message = (String) responseMap.get("message"); + if (message != null) { + return new CohereErrorResponseEntity(message); + } + } catch (Exception e) { + // swallow the error + } + + return null; + } +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/ServiceUtils.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/ServiceUtils.java index 1686cd32d4a6b..7029f9ca3bf56 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/ServiceUtils.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/ServiceUtils.java @@ -11,17 +11,22 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.common.ValidationException; import org.elasticsearch.common.settings.SecureString; +import org.elasticsearch.core.CheckedFunction; +import org.elasticsearch.core.Nullable; import org.elasticsearch.core.Strings; import org.elasticsearch.inference.InferenceService; import org.elasticsearch.inference.Model; import org.elasticsearch.inference.TaskType; import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.xpack.core.inference.results.TextEmbedding; import org.elasticsearch.xpack.core.inference.results.TextEmbeddingResults; import org.elasticsearch.xpack.inference.common.SimilarityMeasure; import java.net.URI; import java.net.URISyntaxException; +import java.util.Arrays; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; @@ -105,9 +110,23 @@ public static String mustBeNonEmptyString(String settingName, String scope) { return Strings.format("[%s] Invalid value empty string. [%s] must be a non-empty string", scope, settingName); } + public static String invalidValue(String settingName, String scope, String invalidType, String... requiredTypes) { + return Strings.format( + "[%s] Invalid value [%s] received. [%s] must be one of [%s]", + scope, + invalidType, + settingName, + String.join(", ", requiredTypes) + ); + } + // TODO improve URI validation logic - public static URI convertToUri(String url, String settingName, String settingScope, ValidationException validationException) { + public static URI convertToUri(@Nullable String url, String settingName, String settingScope, ValidationException validationException) { try { + if (url == null) { + return null; + } + return createUri(url); } catch (IllegalArgumentException ignored) { validationException.addValidationError(ServiceUtils.invalidUrlErrorMsg(url, settingName, settingScope)); @@ -125,6 +144,14 @@ public static URI createUri(String url) throws IllegalArgumentException { } } + public static URI createOptionalUri(String url) { + if (url == null) { + return null; + } + + return createUri(url); + } + public static SecureString extractRequiredSecureString( Map map, String settingName, @@ -194,6 +221,29 @@ public static String extractOptionalString( return optionalField; } + public static T extractOptionalEnum( + Map map, + String settingName, + String scope, + CheckedFunction converter, + T[] validTypes, + ValidationException validationException + ) { + var enumString = extractOptionalString(map, settingName, scope, validationException); + if (enumString == null) { + return null; + } + + var validTypesAsStrings = Arrays.stream(validTypes).map(type -> type.toString().toLowerCase(Locale.ROOT)).toArray(String[]::new); + try { + return converter.apply(enumString); + } catch (IllegalArgumentException e) { + validationException.addValidationError(invalidValue(settingName, scope, enumString, validTypesAsStrings)); + } + + return null; + } + public static String parsePersistedConfigErrorMsg(String modelId, String serviceName) { return format("Failed to parse stored model [%s] for [%s] service, please delete and add the service again", modelId, serviceName); } @@ -219,16 +269,11 @@ public static void getEmbeddingSize(Model model, InferenceService service, Actio assert model.getTaskType() == TaskType.TEXT_EMBEDDING; service.infer(model, List.of(TEST_EMBEDDING_INPUT), Map.of(), listener.delegateFailureAndWrap((delegate, r) -> { - if (r instanceof TextEmbeddingResults embeddingResults) { - if (embeddingResults.embeddings().isEmpty()) { - delegate.onFailure( - new ElasticsearchStatusException( - "Could not determine embedding size, no embeddings were returned in test call", - RestStatus.BAD_REQUEST - ) - ); - } else { - delegate.onResponse(embeddingResults.embeddings().get(0).values().size()); + if (r instanceof TextEmbedding embeddingResults) { + try { + delegate.onResponse(embeddingResults.getFirstEmbeddingSize()); + } catch (Exception e) { + delegate.onFailure(new ElasticsearchStatusException("Could not determine embedding size", RestStatus.BAD_REQUEST, e)); } } else { delegate.onFailure( diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereModel.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereModel.java new file mode 100644 index 0000000000000..1b4843e441248 --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereModel.java @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.services.cohere; + +import org.elasticsearch.inference.Model; +import org.elasticsearch.inference.ModelConfigurations; +import org.elasticsearch.inference.ModelSecrets; +import org.elasticsearch.inference.ServiceSettings; +import org.elasticsearch.inference.TaskSettings; +import org.elasticsearch.xpack.inference.external.action.ExecutableAction; +import org.elasticsearch.xpack.inference.external.action.cohere.CohereActionVisitor; + +import java.util.Map; + +public abstract class CohereModel extends Model { + public CohereModel(ModelConfigurations configurations, ModelSecrets secrets) { + super(configurations, secrets); + } + + protected CohereModel(CohereModel model, TaskSettings taskSettings) { + super(model, taskSettings); + } + + protected CohereModel(CohereModel model, ServiceSettings serviceSettings) { + super(model, serviceSettings); + } + + public abstract ExecutableAction accept(CohereActionVisitor creator, Map taskSettings); +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereService.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereService.java new file mode 100644 index 0000000000000..8783f12852ec8 --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereService.java @@ -0,0 +1,179 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.services.cohere; + +import org.apache.lucene.util.SetOnce; +import org.elasticsearch.ElasticsearchStatusException; +import org.elasticsearch.TransportVersion; +import org.elasticsearch.TransportVersions; +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.core.Nullable; +import org.elasticsearch.inference.InferenceServiceResults; +import org.elasticsearch.inference.Model; +import org.elasticsearch.inference.ModelConfigurations; +import org.elasticsearch.inference.ModelSecrets; +import org.elasticsearch.inference.TaskType; +import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.xpack.inference.common.SimilarityMeasure; +import org.elasticsearch.xpack.inference.external.action.cohere.CohereActionCreator; +import org.elasticsearch.xpack.inference.external.http.sender.HttpRequestSenderFactory; +import org.elasticsearch.xpack.inference.services.SenderService; +import org.elasticsearch.xpack.inference.services.ServiceComponents; +import org.elasticsearch.xpack.inference.services.ServiceUtils; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsModel; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsServiceSettings; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.elasticsearch.xpack.inference.services.ServiceUtils.createInvalidModelException; +import static org.elasticsearch.xpack.inference.services.ServiceUtils.parsePersistedConfigErrorMsg; +import static org.elasticsearch.xpack.inference.services.ServiceUtils.removeFromMapOrThrowIfNull; +import static org.elasticsearch.xpack.inference.services.ServiceUtils.throwIfNotEmptyMap; + +public class CohereService extends SenderService { + public static final String NAME = "cohere"; + + public CohereService(SetOnce factory, SetOnce serviceComponents) { + super(factory, serviceComponents); + } + + @Override + public String name() { + return NAME; + } + + @Override + public CohereModel parseRequestConfig( + String modelId, + TaskType taskType, + Map config, + Set platformArchitectures + ) { + Map serviceSettingsMap = removeFromMapOrThrowIfNull(config, ModelConfigurations.SERVICE_SETTINGS); + Map taskSettingsMap = removeFromMapOrThrowIfNull(config, ModelConfigurations.TASK_SETTINGS); + + CohereModel model = createModel( + modelId, + taskType, + serviceSettingsMap, + taskSettingsMap, + serviceSettingsMap, + TaskType.unsupportedTaskTypeErrorMsg(taskType, NAME) + ); + + throwIfNotEmptyMap(config, NAME); + throwIfNotEmptyMap(serviceSettingsMap, NAME); + throwIfNotEmptyMap(taskSettingsMap, NAME); + + return model; + } + + private static CohereModel createModel( + String modelId, + TaskType taskType, + Map serviceSettings, + Map taskSettings, + @Nullable Map secretSettings, + String failureMessage + ) { + return switch (taskType) { + case TEXT_EMBEDDING -> new CohereEmbeddingsModel(modelId, taskType, NAME, serviceSettings, taskSettings, secretSettings); + default -> throw new ElasticsearchStatusException(failureMessage, RestStatus.BAD_REQUEST); + }; + } + + @Override + public CohereModel parsePersistedConfigWithSecrets( + String modelId, + TaskType taskType, + Map config, + Map secrets + ) { + Map serviceSettingsMap = removeFromMapOrThrowIfNull(config, ModelConfigurations.SERVICE_SETTINGS); + Map taskSettingsMap = removeFromMapOrThrowIfNull(config, ModelConfigurations.TASK_SETTINGS); + Map secretSettingsMap = removeFromMapOrThrowIfNull(secrets, ModelSecrets.SECRET_SETTINGS); + + return createModel( + modelId, + taskType, + serviceSettingsMap, + taskSettingsMap, + secretSettingsMap, + parsePersistedConfigErrorMsg(modelId, NAME) + ); + } + + @Override + public CohereModel parsePersistedConfig(String modelId, TaskType taskType, Map config) { + Map serviceSettingsMap = removeFromMapOrThrowIfNull(config, ModelConfigurations.SERVICE_SETTINGS); + Map taskSettingsMap = removeFromMapOrThrowIfNull(config, ModelConfigurations.TASK_SETTINGS); + + return createModel(modelId, taskType, serviceSettingsMap, taskSettingsMap, null, parsePersistedConfigErrorMsg(modelId, NAME)); + } + + @Override + public void doInfer( + Model model, + List input, + Map taskSettings, + ActionListener listener + ) { + if (model instanceof CohereModel == false) { + listener.onFailure(createInvalidModelException(model)); + return; + } + + CohereModel cohereModel = (CohereModel) model; + var actionCreator = new CohereActionCreator(getSender(), getServiceComponents()); + + var action = cohereModel.accept(actionCreator, taskSettings); + action.execute(input, listener); + } + + /** + * For text embedding models get the embedding size and + * update the service settings. + * + * @param model The new model + * @param listener The listener + */ + @Override + public void checkModelConfig(Model model, ActionListener listener) { + if (model instanceof CohereEmbeddingsModel embeddingsModel) { + ServiceUtils.getEmbeddingSize( + model, + this, + listener.delegateFailureAndWrap((l, size) -> l.onResponse(updateModelWithEmbeddingDetails(embeddingsModel, size))) + ); + } else { + listener.onResponse(model); + } + } + + private CohereEmbeddingsModel updateModelWithEmbeddingDetails(CohereEmbeddingsModel model, int embeddingSize) { + CohereEmbeddingsServiceSettings serviceSettings = new CohereEmbeddingsServiceSettings( + new CohereServiceSettings( + model.getServiceSettings().getCommonSettings().getUri(), + SimilarityMeasure.DOT_PRODUCT, + embeddingSize, + model.getServiceSettings().getCommonSettings().getMaxInputTokens(), + model.getServiceSettings().getCommonSettings().getModel() + ), + model.getServiceSettings().getEmbeddingType() + ); + + return new CohereEmbeddingsModel(model, serviceSettings); + } + + @Override + public TransportVersion getMinimalSupportedVersion() { + return TransportVersions.ML_INFERENCE_COHERE_EMBEDDINGS_ADDED; + } +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereServiceFields.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereServiceFields.java new file mode 100644 index 0000000000000..807520637f971 --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereServiceFields.java @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.services.cohere; + +public class CohereServiceFields { + public static final String TRUNCATE = "truncate"; +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereServiceSettings.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereServiceSettings.java new file mode 100644 index 0000000000000..7964741d90343 --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereServiceSettings.java @@ -0,0 +1,182 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.services.cohere; + +import org.elasticsearch.TransportVersion; +import org.elasticsearch.TransportVersions; +import org.elasticsearch.common.ValidationException; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.core.Nullable; +import org.elasticsearch.inference.ModelConfigurations; +import org.elasticsearch.inference.ServiceSettings; +import org.elasticsearch.xcontent.XContentBuilder; +import org.elasticsearch.xpack.inference.common.SimilarityMeasure; + +import java.io.IOException; +import java.net.URI; +import java.util.Map; +import java.util.Objects; + +import static org.elasticsearch.xpack.inference.services.ServiceFields.DIMENSIONS; +import static org.elasticsearch.xpack.inference.services.ServiceFields.MAX_INPUT_TOKENS; +import static org.elasticsearch.xpack.inference.services.ServiceFields.SIMILARITY; +import static org.elasticsearch.xpack.inference.services.ServiceFields.URL; +import static org.elasticsearch.xpack.inference.services.ServiceUtils.convertToUri; +import static org.elasticsearch.xpack.inference.services.ServiceUtils.createOptionalUri; +import static org.elasticsearch.xpack.inference.services.ServiceUtils.extractOptionalString; +import static org.elasticsearch.xpack.inference.services.ServiceUtils.extractSimilarity; +import static org.elasticsearch.xpack.inference.services.ServiceUtils.removeAsType; + +public class CohereServiceSettings implements ServiceSettings { + public static final String NAME = "cohere_service_settings"; + public static final String MODEL = "model"; + + public static CohereServiceSettings fromMap(Map map) { + ValidationException validationException = new ValidationException(); + + String url = extractOptionalString(map, URL, ModelConfigurations.SERVICE_SETTINGS, validationException); + + SimilarityMeasure similarity = extractSimilarity(map, ModelConfigurations.SERVICE_SETTINGS, validationException); + Integer dims = removeAsType(map, DIMENSIONS, Integer.class); + Integer maxInputTokens = removeAsType(map, MAX_INPUT_TOKENS, Integer.class); + URI uri = convertToUri(url, URL, ModelConfigurations.SERVICE_SETTINGS, validationException); + String model = extractOptionalString(map, MODEL, ModelConfigurations.SERVICE_SETTINGS, validationException); + + if (validationException.validationErrors().isEmpty() == false) { + throw validationException; + } + + return new CohereServiceSettings(uri, similarity, dims, maxInputTokens, model); + } + + private final URI uri; + private final SimilarityMeasure similarity; + private final Integer dimensions; + private final Integer maxInputTokens; + private final String model; + + public CohereServiceSettings( + @Nullable URI uri, + @Nullable SimilarityMeasure similarity, + @Nullable Integer dimensions, + @Nullable Integer maxInputTokens, + @Nullable String model + ) { + this.uri = uri; + this.similarity = similarity; + this.dimensions = dimensions; + this.maxInputTokens = maxInputTokens; + this.model = model; + } + + public CohereServiceSettings( + @Nullable String url, + @Nullable SimilarityMeasure similarity, + @Nullable Integer dimensions, + @Nullable Integer maxInputTokens, + @Nullable String model + ) { + this(createOptionalUri(url), similarity, dimensions, maxInputTokens, model); + } + + public CohereServiceSettings(StreamInput in) throws IOException { + uri = createOptionalUri(in.readOptionalString()); + similarity = in.readOptionalEnum(SimilarityMeasure.class); + dimensions = in.readOptionalVInt(); + maxInputTokens = in.readOptionalVInt(); + model = in.readOptionalString(); + } + + public URI getUri() { + return uri; + } + + public SimilarityMeasure getSimilarity() { + return similarity; + } + + public Integer getDimensions() { + return dimensions; + } + + public Integer getMaxInputTokens() { + return maxInputTokens; + } + + public String getModel() { + return model; + } + + @Override + public String getWriteableName() { + return NAME; + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + + toXContentFragment(builder); + + builder.endObject(); + return builder; + } + + public XContentBuilder toXContentFragment(XContentBuilder builder) throws IOException { + if (uri != null) { + builder.field(URL, uri.toString()); + } + if (similarity != null) { + builder.field(SIMILARITY, similarity); + } + if (dimensions != null) { + builder.field(DIMENSIONS, dimensions); + } + if (maxInputTokens != null) { + builder.field(MAX_INPUT_TOKENS, maxInputTokens); + } + if (model != null) { + builder.field(MODEL, model); + } + + return builder; + } + + @Override + public TransportVersion getMinimalSupportedVersion() { + return TransportVersions.ML_INFERENCE_COHERE_EMBEDDINGS_ADDED; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + var uriToWrite = uri != null ? uri.toString() : null; + out.writeOptionalString(uriToWrite); + out.writeOptionalEnum(similarity); + out.writeOptionalVInt(dimensions); + out.writeOptionalVInt(maxInputTokens); + out.writeOptionalString(model); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CohereServiceSettings that = (CohereServiceSettings) o; + return Objects.equals(uri, that.uri) + && Objects.equals(similarity, that.similarity) + && Objects.equals(dimensions, that.dimensions) + && Objects.equals(maxInputTokens, that.maxInputTokens) + && Objects.equals(model, that.model); + } + + @Override + public int hashCode() { + return Objects.hash(uri, similarity, dimensions, maxInputTokens, model); + } +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereTruncation.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereTruncation.java new file mode 100644 index 0000000000000..e7c9a0247bb1a --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/CohereTruncation.java @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.services.cohere; + +import java.util.Locale; + +/** + * Defines the type of truncation for a cohere request. The specified value determines how the Cohere API will handle inputs + * longer than the maximum token length. + * + *

+ * See api docs for details. + *

+ */ +public enum CohereTruncation { + /** + * When the input exceeds the maximum input token length an error will be returned. + */ + NONE, + /** + * Discard the start of the input + */ + START, + /** + * Discard the end of the input + */ + END; + + @Override + public String toString() { + return name().toLowerCase(Locale.ROOT); + } + + public static CohereTruncation fromString(String name) { + return valueOf(name.trim().toUpperCase(Locale.ROOT)); + } +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingType.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingType.java new file mode 100644 index 0000000000000..82d57cfb92381 --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingType.java @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.services.cohere.embeddings; + +import java.util.Locale; + +/** + * Defines the type of embedding that the cohere api should return for a request. + * + *

+ * See api docs for details. + *

+ */ +public enum CohereEmbeddingType { + /** + * Use this when you want to get back the default float embeddings. Valid for all models. + */ + FLOAT, + /** + * Use this when you want to get back signed int8 embeddings. Valid for only v3 models. + */ + INT8; + + @Override + public String toString() { + return name().toLowerCase(Locale.ROOT); + } + + public static String toLowerCase(CohereEmbeddingType type) { + return type.toString().toLowerCase(Locale.ROOT); + } + + public static CohereEmbeddingType fromString(String name) { + return valueOf(name.trim().toUpperCase(Locale.ROOT)); + } +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsModel.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsModel.java new file mode 100644 index 0000000000000..c92700e87cd96 --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsModel.java @@ -0,0 +1,88 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.services.cohere.embeddings; + +import org.elasticsearch.core.Nullable; +import org.elasticsearch.inference.ModelConfigurations; +import org.elasticsearch.inference.ModelSecrets; +import org.elasticsearch.inference.TaskType; +import org.elasticsearch.xpack.inference.external.action.ExecutableAction; +import org.elasticsearch.xpack.inference.external.action.cohere.CohereActionVisitor; +import org.elasticsearch.xpack.inference.services.cohere.CohereModel; +import org.elasticsearch.xpack.inference.services.settings.DefaultSecretSettings; + +import java.util.Map; + +public class CohereEmbeddingsModel extends CohereModel { + public CohereEmbeddingsModel( + String modelId, + TaskType taskType, + String service, + Map serviceSettings, + Map taskSettings, + @Nullable Map secrets + ) { + this( + modelId, + taskType, + service, + CohereEmbeddingsServiceSettings.fromMap(serviceSettings), + CohereEmbeddingsTaskSettings.fromMap(taskSettings), + DefaultSecretSettings.fromMap(secrets) + ); + } + + // should only be used for testing + CohereEmbeddingsModel( + String modelId, + TaskType taskType, + String service, + CohereEmbeddingsServiceSettings serviceSettings, + CohereEmbeddingsTaskSettings taskSettings, + @Nullable DefaultSecretSettings secretSettings + ) { + super(new ModelConfigurations(modelId, taskType, service, serviceSettings, taskSettings), new ModelSecrets(secretSettings)); + } + + private CohereEmbeddingsModel(CohereEmbeddingsModel model, CohereEmbeddingsTaskSettings taskSettings) { + super(model, taskSettings); + } + + public CohereEmbeddingsModel(CohereEmbeddingsModel model, CohereEmbeddingsServiceSettings serviceSettings) { + super(model, serviceSettings); + } + + @Override + public CohereEmbeddingsServiceSettings getServiceSettings() { + return (CohereEmbeddingsServiceSettings) super.getServiceSettings(); + } + + @Override + public CohereEmbeddingsTaskSettings getTaskSettings() { + return (CohereEmbeddingsTaskSettings) super.getTaskSettings(); + } + + @Override + public DefaultSecretSettings getSecretSettings() { + return (DefaultSecretSettings) super.getSecretSettings(); + } + + @Override + public ExecutableAction accept(CohereActionVisitor visitor, Map taskSettings) { + return visitor.create(this, taskSettings); + } + + public CohereEmbeddingsModel overrideWith(Map taskSettings) { + if (taskSettings == null || taskSettings.isEmpty()) { + return this; + } + + var requestTaskSettings = CohereEmbeddingsTaskSettings.fromMap(taskSettings); + return new CohereEmbeddingsModel(this, getTaskSettings().overrideWith(requestTaskSettings)); + } +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsServiceSettings.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsServiceSettings.java new file mode 100644 index 0000000000000..5327bcbcf22dd --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsServiceSettings.java @@ -0,0 +1,111 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.services.cohere.embeddings; + +import org.elasticsearch.TransportVersion; +import org.elasticsearch.TransportVersions; +import org.elasticsearch.common.ValidationException; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.core.Nullable; +import org.elasticsearch.inference.ModelConfigurations; +import org.elasticsearch.inference.ServiceSettings; +import org.elasticsearch.xcontent.XContentBuilder; +import org.elasticsearch.xpack.inference.services.cohere.CohereServiceSettings; + +import java.io.IOException; +import java.util.Map; +import java.util.Objects; + +import static org.elasticsearch.xpack.inference.services.ServiceUtils.extractOptionalEnum; + +public class CohereEmbeddingsServiceSettings implements ServiceSettings { + public static final String NAME = "cohere_embeddings_service_settings"; + + static final String EMBEDDING_TYPE = "embedding_type"; + + public static CohereEmbeddingsServiceSettings fromMap(Map map) { + ValidationException validationException = new ValidationException(); + var commonServiceSettings = CohereServiceSettings.fromMap(map); + CohereEmbeddingType embeddingTypes = extractOptionalEnum( + map, + EMBEDDING_TYPE, + ModelConfigurations.SERVICE_SETTINGS, + CohereEmbeddingType::fromString, + CohereEmbeddingType.values(), + validationException + ); + + if (validationException.validationErrors().isEmpty() == false) { + throw validationException; + } + + return new CohereEmbeddingsServiceSettings(commonServiceSettings, embeddingTypes); + } + + private final CohereServiceSettings commonSettings; + private final CohereEmbeddingType embeddingType; + + public CohereEmbeddingsServiceSettings(CohereServiceSettings commonSettings, @Nullable CohereEmbeddingType embeddingType) { + this.commonSettings = commonSettings; + this.embeddingType = embeddingType; + } + + public CohereEmbeddingsServiceSettings(StreamInput in) throws IOException { + commonSettings = new CohereServiceSettings(in); + embeddingType = in.readOptionalEnum(CohereEmbeddingType.class); + } + + public CohereServiceSettings getCommonSettings() { + return commonSettings; + } + + public CohereEmbeddingType getEmbeddingType() { + return embeddingType; + } + + @Override + public String getWriteableName() { + return NAME; + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + + commonSettings.toXContentFragment(builder); + builder.field(EMBEDDING_TYPE, embeddingType); + + builder.endObject(); + return builder; + } + + @Override + public TransportVersion getMinimalSupportedVersion() { + return TransportVersions.ML_INFERENCE_COHERE_EMBEDDINGS_ADDED; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + commonSettings.writeTo(out); + out.writeOptionalEnum(embeddingType); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CohereEmbeddingsServiceSettings that = (CohereEmbeddingsServiceSettings) o; + return Objects.equals(commonSettings, that.commonSettings) && Objects.equals(embeddingType, that.embeddingType); + } + + @Override + public int hashCode() { + return Objects.hash(commonSettings, embeddingType); + } +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsTaskSettings.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsTaskSettings.java new file mode 100644 index 0000000000000..858efdb0d1ace --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsTaskSettings.java @@ -0,0 +1,115 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.services.cohere.embeddings; + +import org.elasticsearch.TransportVersion; +import org.elasticsearch.TransportVersions; +import org.elasticsearch.common.ValidationException; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.core.Nullable; +import org.elasticsearch.inference.InputType; +import org.elasticsearch.inference.ModelConfigurations; +import org.elasticsearch.inference.TaskSettings; +import org.elasticsearch.xcontent.XContentBuilder; +import org.elasticsearch.xpack.inference.services.cohere.CohereTruncation; + +import java.io.IOException; +import java.util.Map; + +import static org.elasticsearch.xpack.inference.services.ServiceUtils.extractOptionalEnum; +import static org.elasticsearch.xpack.inference.services.cohere.CohereServiceFields.TRUNCATE; + +/** + * Defines the task settings for the cohere text embeddings service. + * + *

+ * See api docs for details. + *

+ * + * @param inputType Specifies the type of input you're giving to the model + * @param truncation Specifies how the API will handle inputs longer than the maximum token length + */ +public record CohereEmbeddingsTaskSettings(@Nullable InputType inputType, @Nullable CohereTruncation truncation) implements TaskSettings { + + public static final String NAME = "cohere_embeddings_task_settings"; + public static final CohereEmbeddingsTaskSettings EMPTY_SETTINGS = new CohereEmbeddingsTaskSettings(null, null); + static final String INPUT_TYPE = "input_type"; + + public static CohereEmbeddingsTaskSettings fromMap(Map map) { + if (map.isEmpty()) { + return EMPTY_SETTINGS; + } + + ValidationException validationException = new ValidationException(); + + InputType inputType = extractOptionalEnum( + map, + INPUT_TYPE, + ModelConfigurations.TASK_SETTINGS, + InputType::fromString, + InputType.values(), + validationException + ); + CohereTruncation truncation = extractOptionalEnum( + map, + TRUNCATE, + ModelConfigurations.TASK_SETTINGS, + CohereTruncation::fromString, + CohereTruncation.values(), + validationException + ); + + if (validationException.validationErrors().isEmpty() == false) { + throw validationException; + } + + return new CohereEmbeddingsTaskSettings(inputType, truncation); + } + + public CohereEmbeddingsTaskSettings(StreamInput in) throws IOException { + this(in.readOptionalEnum(InputType.class), in.readOptionalEnum(CohereTruncation.class)); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + if (inputType != null) { + builder.field(INPUT_TYPE, inputType); + } + + if (truncation != null) { + builder.field(TRUNCATE, truncation); + } + builder.endObject(); + return builder; + } + + @Override + public String getWriteableName() { + return NAME; + } + + @Override + public TransportVersion getMinimalSupportedVersion() { + return TransportVersions.ML_INFERENCE_COHERE_EMBEDDINGS_ADDED; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeOptionalEnum(inputType); + out.writeOptionalEnum(truncation); + } + + public CohereEmbeddingsTaskSettings overrideWith(CohereEmbeddingsTaskSettings requestTaskSettings) { + var inputTypeToUse = requestTaskSettings.inputType() == null ? inputType : requestTaskSettings.inputType(); + var truncationToUse = requestTaskSettings.truncation() == null ? truncation : requestTaskSettings.truncation(); + + return new CohereEmbeddingsTaskSettings(inputTypeToUse, truncationToUse); + } +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/huggingface/HuggingFaceServiceSettings.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/huggingface/HuggingFaceServiceSettings.java index 6464ca0e0fda8..b3b130b22a1fa 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/huggingface/HuggingFaceServiceSettings.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/huggingface/HuggingFaceServiceSettings.java @@ -52,9 +52,7 @@ public static HuggingFaceServiceSettings fromMap(Map map) { public static URI extractUri(Map map, String fieldName, ValidationException validationException) { String parsedUrl = extractRequiredString(map, fieldName, ModelConfigurations.SERVICE_SETTINGS, validationException); - if (parsedUrl == null) { - return null; - } + return convertToUri(parsedUrl, fieldName, ModelConfigurations.SERVICE_SETTINGS, validationException); } diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/openai/OpenAiModel.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/openai/OpenAiModel.java index 97823e3bc9079..1e158725f531d 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/openai/OpenAiModel.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/openai/OpenAiModel.java @@ -10,6 +10,8 @@ import org.elasticsearch.inference.Model; import org.elasticsearch.inference.ModelConfigurations; import org.elasticsearch.inference.ModelSecrets; +import org.elasticsearch.inference.ServiceSettings; +import org.elasticsearch.inference.TaskSettings; import org.elasticsearch.xpack.inference.external.action.ExecutableAction; import org.elasticsearch.xpack.inference.external.action.openai.OpenAiActionVisitor; @@ -21,5 +23,13 @@ public OpenAiModel(ModelConfigurations configurations, ModelSecrets secrets) { super(configurations, secrets); } + protected OpenAiModel(OpenAiModel model, TaskSettings taskSettings) { + super(model, taskSettings); + } + + protected OpenAiModel(OpenAiModel model, ServiceSettings serviceSettings) { + super(model, serviceSettings); + } + public abstract ExecutableAction accept(OpenAiActionVisitor creator, Map taskSettings); } diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/openai/OpenAiServiceSettings.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/openai/OpenAiServiceSettings.java index 5ade2aad0acb4..4e96ac73157ad 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/openai/OpenAiServiceSettings.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/openai/OpenAiServiceSettings.java @@ -28,7 +28,7 @@ import static org.elasticsearch.xpack.inference.services.ServiceFields.SIMILARITY; import static org.elasticsearch.xpack.inference.services.ServiceFields.URL; import static org.elasticsearch.xpack.inference.services.ServiceUtils.convertToUri; -import static org.elasticsearch.xpack.inference.services.ServiceUtils.createUri; +import static org.elasticsearch.xpack.inference.services.ServiceUtils.createOptionalUri; import static org.elasticsearch.xpack.inference.services.ServiceUtils.extractOptionalString; import static org.elasticsearch.xpack.inference.services.ServiceUtils.extractSimilarity; import static org.elasticsearch.xpack.inference.services.ServiceUtils.removeAsType; @@ -50,17 +50,6 @@ public static OpenAiServiceSettings fromMap(Map map) { SimilarityMeasure similarity = extractSimilarity(map, ModelConfigurations.SERVICE_SETTINGS, validationException); Integer dims = removeAsType(map, DIMENSIONS, Integer.class); Integer maxInputTokens = removeAsType(map, MAX_INPUT_TOKENS, Integer.class); - - // Throw if any of the settings were empty strings or invalid - if (validationException.validationErrors().isEmpty() == false) { - throw validationException; - } - - // the url is optional and only for testing - if (url == null) { - return new OpenAiServiceSettings((URI) null, organizationId, similarity, dims, maxInputTokens); - } - URI uri = convertToUri(url, URL, ModelConfigurations.SERVICE_SETTINGS, validationException); if (validationException.validationErrors().isEmpty() == false) { @@ -100,14 +89,6 @@ public OpenAiServiceSettings( this(createOptionalUri(uri), organizationId, similarity, dimensions, maxInputTokens); } - private static URI createOptionalUri(String url) { - if (url == null) { - return null; - } - - return createUri(url); - } - public OpenAiServiceSettings(StreamInput in) throws IOException { uri = createOptionalUri(in.readOptionalString()); organizationId = in.readOptionalString(); diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/openai/embeddings/OpenAiEmbeddingsModel.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/openai/embeddings/OpenAiEmbeddingsModel.java index 250837d895590..0df3d126402c7 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/openai/embeddings/OpenAiEmbeddingsModel.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/openai/embeddings/OpenAiEmbeddingsModel.java @@ -52,29 +52,11 @@ public OpenAiEmbeddingsModel( } private OpenAiEmbeddingsModel(OpenAiEmbeddingsModel originalModel, OpenAiEmbeddingsTaskSettings taskSettings) { - super( - new ModelConfigurations( - originalModel.getConfigurations().getModelId(), - originalModel.getConfigurations().getTaskType(), - originalModel.getConfigurations().getService(), - originalModel.getServiceSettings(), - taskSettings - ), - new ModelSecrets(originalModel.getSecretSettings()) - ); + super(originalModel, taskSettings); } public OpenAiEmbeddingsModel(OpenAiEmbeddingsModel originalModel, OpenAiServiceSettings serviceSettings) { - super( - new ModelConfigurations( - originalModel.getConfigurations().getModelId(), - originalModel.getConfigurations().getTaskType(), - originalModel.getConfigurations().getService(), - serviceSettings, - originalModel.getTaskSettings() - ), - new ModelSecrets(originalModel.getSecretSettings()) - ); + super(originalModel, serviceSettings); } @Override diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereActionCreatorTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereActionCreatorTests.java new file mode 100644 index 0000000000000..67a95265f093d --- /dev/null +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereActionCreatorTests.java @@ -0,0 +1,149 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.action.cohere; + +import org.apache.http.HttpHeaders; +import org.elasticsearch.action.support.PlainActionFuture; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.core.TimeValue; +import org.elasticsearch.inference.InferenceServiceResults; +import org.elasticsearch.inference.InputType; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.test.http.MockResponse; +import org.elasticsearch.test.http.MockWebServer; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.xcontent.XContentType; +import org.elasticsearch.xpack.inference.external.http.HttpClientManager; +import org.elasticsearch.xpack.inference.external.http.sender.HttpRequestSenderFactory; +import org.elasticsearch.xpack.inference.logging.ThrottlerManager; +import org.elasticsearch.xpack.inference.services.cohere.CohereTruncation; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingType; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsModelTests; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsTaskSettings; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsTaskSettingsTests; +import org.hamcrest.MatcherAssert; +import org.junit.After; +import org.junit.Before; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import static org.elasticsearch.xpack.inference.Utils.inferenceUtilityPool; +import static org.elasticsearch.xpack.inference.Utils.mockClusterServiceEmpty; +import static org.elasticsearch.xpack.inference.external.http.Utils.entityAsMap; +import static org.elasticsearch.xpack.inference.external.http.Utils.getUrl; +import static org.elasticsearch.xpack.inference.results.TextEmbeddingResultsTests.buildExpectation; +import static org.elasticsearch.xpack.inference.services.ServiceComponentsTests.createWithEmptySettings; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; + +public class CohereActionCreatorTests extends ESTestCase { + private static final TimeValue TIMEOUT = new TimeValue(30, TimeUnit.SECONDS); + private final MockWebServer webServer = new MockWebServer(); + private ThreadPool threadPool; + private HttpClientManager clientManager; + + @Before + public void init() throws Exception { + webServer.start(); + threadPool = createThreadPool(inferenceUtilityPool()); + clientManager = HttpClientManager.create(Settings.EMPTY, threadPool, mockClusterServiceEmpty(), mock(ThrottlerManager.class)); + } + + @After + public void shutdown() throws IOException { + clientManager.close(); + terminate(threadPool); + webServer.close(); + } + + public void testCreate_CohereEmbeddingsModel() throws IOException { + var senderFactory = new HttpRequestSenderFactory(threadPool, clientManager, mockClusterServiceEmpty(), Settings.EMPTY); + + try (var sender = senderFactory.createSender("test_service")) { + sender.start(); + + String responseJson = """ + { + "id": "de37399c-5df6-47cb-bc57-e3c5680c977b", + "texts": [ + "hello" + ], + "embeddings": { + "float": [ + [ + 0.123, + -0.123 + ] + ] + }, + "meta": { + "api_version": { + "version": "1" + }, + "billed_units": { + "input_tokens": 1 + } + }, + "response_type": "embeddings_by_type" + } + """; + webServer.enqueue(new MockResponse().setResponseCode(200).setBody(responseJson)); + + var model = CohereEmbeddingsModelTests.createModel( + getUrl(webServer), + "secret", + new CohereEmbeddingsTaskSettings(InputType.INGEST, CohereTruncation.START), + 1024, + 1024, + "model", + CohereEmbeddingType.FLOAT + ); + var actionCreator = new CohereActionCreator(sender, createWithEmptySettings(threadPool)); + var overriddenTaskSettings = CohereEmbeddingsTaskSettingsTests.getTaskSettingsMap(InputType.SEARCH, CohereTruncation.END); + var action = actionCreator.create(model, overriddenTaskSettings); + + PlainActionFuture listener = new PlainActionFuture<>(); + action.execute(List.of("abc"), listener); + + var result = listener.actionGet(TIMEOUT); + + MatcherAssert.assertThat(result.asMap(), is(buildExpectation(List.of(List.of(0.123F, -0.123F))))); + MatcherAssert.assertThat(webServer.requests(), hasSize(1)); + assertNull(webServer.requests().get(0).getUri().getQuery()); + MatcherAssert.assertThat( + webServer.requests().get(0).getHeader(HttpHeaders.CONTENT_TYPE), + equalTo(XContentType.JSON.mediaType()) + ); + MatcherAssert.assertThat(webServer.requests().get(0).getHeader(HttpHeaders.AUTHORIZATION), equalTo("Bearer secret")); + + var requestMap = entityAsMap(webServer.requests().get(0).getBody()); + MatcherAssert.assertThat( + requestMap, + is( + Map.of( + "texts", + List.of("abc"), + "model", + "model", + "input_type", + "search_query", + "embedding_types", + List.of("float"), + "truncate", + "end" + ) + ) + ); + } + } +} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereEmbeddingsActionTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereEmbeddingsActionTests.java new file mode 100644 index 0000000000000..501d5a5e42bfe --- /dev/null +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/action/cohere/CohereEmbeddingsActionTests.java @@ -0,0 +1,348 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.action.cohere; + +import org.apache.http.HttpHeaders; +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.support.PlainActionFuture; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.core.Nullable; +import org.elasticsearch.core.TimeValue; +import org.elasticsearch.inference.InferenceServiceResults; +import org.elasticsearch.inference.InputType; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.test.http.MockResponse; +import org.elasticsearch.test.http.MockWebServer; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.xcontent.XContentType; +import org.elasticsearch.xpack.inference.external.http.HttpClientManager; +import org.elasticsearch.xpack.inference.external.http.HttpResult; +import org.elasticsearch.xpack.inference.external.http.sender.HttpRequestSenderFactory; +import org.elasticsearch.xpack.inference.external.http.sender.Sender; +import org.elasticsearch.xpack.inference.logging.ThrottlerManager; +import org.elasticsearch.xpack.inference.results.TextEmbeddingByteResultsTests; +import org.elasticsearch.xpack.inference.services.cohere.CohereTruncation; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingType; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsModelTests; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsTaskSettings; +import org.hamcrest.MatcherAssert; +import org.junit.After; +import org.junit.Before; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import static org.elasticsearch.core.Strings.format; +import static org.elasticsearch.xpack.inference.Utils.inferenceUtilityPool; +import static org.elasticsearch.xpack.inference.Utils.mockClusterServiceEmpty; +import static org.elasticsearch.xpack.inference.external.http.Utils.entityAsMap; +import static org.elasticsearch.xpack.inference.external.http.Utils.getUrl; +import static org.elasticsearch.xpack.inference.results.TextEmbeddingResultsTests.buildExpectation; +import static org.elasticsearch.xpack.inference.services.ServiceComponentsTests.createWithEmptySettings; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; + +public class CohereEmbeddingsActionTests extends ESTestCase { + private static final TimeValue TIMEOUT = new TimeValue(30, TimeUnit.SECONDS); + private final MockWebServer webServer = new MockWebServer(); + private ThreadPool threadPool; + private HttpClientManager clientManager; + + @Before + public void init() throws Exception { + webServer.start(); + threadPool = createThreadPool(inferenceUtilityPool()); + clientManager = HttpClientManager.create(Settings.EMPTY, threadPool, mockClusterServiceEmpty(), mock(ThrottlerManager.class)); + } + + @After + public void shutdown() throws IOException { + clientManager.close(); + terminate(threadPool); + webServer.close(); + } + + public void testExecute_ReturnsSuccessfulResponse() throws IOException { + var senderFactory = new HttpRequestSenderFactory(threadPool, clientManager, mockClusterServiceEmpty(), Settings.EMPTY); + + try (var sender = senderFactory.createSender("test_service")) { + sender.start(); + + String responseJson = """ + { + "id": "de37399c-5df6-47cb-bc57-e3c5680c977b", + "texts": [ + "hello" + ], + "embeddings": { + "float": [ + [ + 0.123, + -0.123 + ] + ] + }, + "meta": { + "api_version": { + "version": "1" + }, + "billed_units": { + "input_tokens": 1 + } + }, + "response_type": "embeddings_by_type" + } + """; + webServer.enqueue(new MockResponse().setResponseCode(200).setBody(responseJson)); + + var action = createAction( + getUrl(webServer), + "secret", + new CohereEmbeddingsTaskSettings(InputType.INGEST, CohereTruncation.START), + "model", + CohereEmbeddingType.FLOAT, + sender + ); + + PlainActionFuture listener = new PlainActionFuture<>(); + action.execute(List.of("abc"), listener); + + var result = listener.actionGet(TIMEOUT); + + MatcherAssert.assertThat(result.asMap(), is(buildExpectation(List.of(List.of(0.123F, -0.123F))))); + MatcherAssert.assertThat(webServer.requests(), hasSize(1)); + assertNull(webServer.requests().get(0).getUri().getQuery()); + MatcherAssert.assertThat( + webServer.requests().get(0).getHeader(HttpHeaders.CONTENT_TYPE), + equalTo(XContentType.JSON.mediaType()) + ); + MatcherAssert.assertThat(webServer.requests().get(0).getHeader(HttpHeaders.AUTHORIZATION), equalTo("Bearer secret")); + + var requestMap = entityAsMap(webServer.requests().get(0).getBody()); + MatcherAssert.assertThat( + requestMap, + is( + Map.of( + "texts", + List.of("abc"), + "model", + "model", + "input_type", + "search_document", + "embedding_types", + List.of("float"), + "truncate", + "start" + ) + ) + ); + } + } + + public void testExecute_ReturnsSuccessfulResponse_ForInt8ResponseType() throws IOException { + var senderFactory = new HttpRequestSenderFactory(threadPool, clientManager, mockClusterServiceEmpty(), Settings.EMPTY); + + try (var sender = senderFactory.createSender("test_service")) { + sender.start(); + + String responseJson = """ + { + "id": "de37399c-5df6-47cb-bc57-e3c5680c977b", + "texts": [ + "hello" + ], + "embeddings": { + "int8": [ + [ + 0, + -1 + ] + ] + }, + "meta": { + "api_version": { + "version": "1" + }, + "billed_units": { + "input_tokens": 1 + } + }, + "response_type": "embeddings_by_type" + } + """; + webServer.enqueue(new MockResponse().setResponseCode(200).setBody(responseJson)); + + var action = createAction( + getUrl(webServer), + "secret", + new CohereEmbeddingsTaskSettings(InputType.INGEST, CohereTruncation.START), + "model", + CohereEmbeddingType.INT8, + sender + ); + + PlainActionFuture listener = new PlainActionFuture<>(); + action.execute(List.of("abc"), listener); + + var result = listener.actionGet(TIMEOUT); + + MatcherAssert.assertThat( + result.asMap(), + is(TextEmbeddingByteResultsTests.buildExpectation(List.of(List.of((byte) 0, (byte) -1)))) + ); + MatcherAssert.assertThat(webServer.requests(), hasSize(1)); + assertNull(webServer.requests().get(0).getUri().getQuery()); + MatcherAssert.assertThat( + webServer.requests().get(0).getHeader(HttpHeaders.CONTENT_TYPE), + equalTo(XContentType.JSON.mediaType()) + ); + MatcherAssert.assertThat(webServer.requests().get(0).getHeader(HttpHeaders.AUTHORIZATION), equalTo("Bearer secret")); + + var requestMap = entityAsMap(webServer.requests().get(0).getBody()); + MatcherAssert.assertThat( + requestMap, + is( + Map.of( + "texts", + List.of("abc"), + "model", + "model", + "input_type", + "search_document", + "embedding_types", + List.of("int8"), + "truncate", + "start" + ) + ) + ); + } + } + + public void testExecute_ThrowsURISyntaxException_ForInvalidUrl() throws IOException { + try (var sender = mock(Sender.class)) { + var thrownException = expectThrows( + IllegalArgumentException.class, + () -> createAction("^^", "secret", CohereEmbeddingsTaskSettings.EMPTY_SETTINGS, null, null, sender) + ); + MatcherAssert.assertThat(thrownException.getMessage(), is("unable to parse url [^^]")); + } + } + + public void testExecute_ThrowsElasticsearchException() { + var sender = mock(Sender.class); + doThrow(new ElasticsearchException("failed")).when(sender).send(any(), any()); + + var action = createAction(getUrl(webServer), "secret", CohereEmbeddingsTaskSettings.EMPTY_SETTINGS, null, null, sender); + + PlainActionFuture listener = new PlainActionFuture<>(); + action.execute(List.of("abc"), listener); + + var thrownException = expectThrows(ElasticsearchException.class, () -> listener.actionGet(TIMEOUT)); + + MatcherAssert.assertThat(thrownException.getMessage(), is("failed")); + } + + public void testExecute_ThrowsElasticsearchException_WhenSenderOnFailureIsCalled() { + var sender = mock(Sender.class); + + doAnswer(invocation -> { + @SuppressWarnings("unchecked") + ActionListener listener = (ActionListener) invocation.getArguments()[1]; + listener.onFailure(new IllegalStateException("failed")); + + return Void.TYPE; + }).when(sender).send(any(), any()); + + var action = createAction(getUrl(webServer), "secret", CohereEmbeddingsTaskSettings.EMPTY_SETTINGS, null, null, sender); + + PlainActionFuture listener = new PlainActionFuture<>(); + action.execute(List.of("abc"), listener); + + var thrownException = expectThrows(ElasticsearchException.class, () -> listener.actionGet(TIMEOUT)); + + MatcherAssert.assertThat( + thrownException.getMessage(), + is(format("Failed to send Cohere embeddings request to [%s]", getUrl(webServer))) + ); + } + + public void testExecute_ThrowsElasticsearchException_WhenSenderOnFailureIsCalled_WhenUrlIsNull() { + var sender = mock(Sender.class); + + doAnswer(invocation -> { + @SuppressWarnings("unchecked") + ActionListener listener = (ActionListener) invocation.getArguments()[1]; + listener.onFailure(new IllegalStateException("failed")); + + return Void.TYPE; + }).when(sender).send(any(), any()); + + var action = createAction(null, "secret", CohereEmbeddingsTaskSettings.EMPTY_SETTINGS, null, null, sender); + + PlainActionFuture listener = new PlainActionFuture<>(); + action.execute(List.of("abc"), listener); + + var thrownException = expectThrows(ElasticsearchException.class, () -> listener.actionGet(TIMEOUT)); + + MatcherAssert.assertThat(thrownException.getMessage(), is("Failed to send Cohere embeddings request")); + } + + public void testExecute_ThrowsException() { + var sender = mock(Sender.class); + doThrow(new IllegalArgumentException("failed")).when(sender).send(any(), any()); + + var action = createAction(getUrl(webServer), "secret", CohereEmbeddingsTaskSettings.EMPTY_SETTINGS, null, null, sender); + + PlainActionFuture listener = new PlainActionFuture<>(); + action.execute(List.of("abc"), listener); + + var thrownException = expectThrows(ElasticsearchException.class, () -> listener.actionGet(TIMEOUT)); + + MatcherAssert.assertThat( + thrownException.getMessage(), + is(format("Failed to send Cohere embeddings request to [%s]", getUrl(webServer))) + ); + } + + public void testExecute_ThrowsExceptionWithNullUrl() { + var sender = mock(Sender.class); + doThrow(new IllegalArgumentException("failed")).when(sender).send(any(), any()); + + var action = createAction(null, "secret", CohereEmbeddingsTaskSettings.EMPTY_SETTINGS, null, null, sender); + + PlainActionFuture listener = new PlainActionFuture<>(); + action.execute(List.of("abc"), listener); + + var thrownException = expectThrows(ElasticsearchException.class, () -> listener.actionGet(TIMEOUT)); + + MatcherAssert.assertThat(thrownException.getMessage(), is("Failed to send Cohere embeddings request")); + } + + private CohereEmbeddingsAction createAction( + String url, + String apiKey, + CohereEmbeddingsTaskSettings taskSettings, + @Nullable String modelName, + @Nullable CohereEmbeddingType embeddingType, + Sender sender + ) { + var model = CohereEmbeddingsModelTests.createModel(url, apiKey, taskSettings, 1024, 1024, modelName, embeddingType); + + return new CohereEmbeddingsAction(sender, model, createWithEmptySettings(threadPool)); + } + +} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/cohere/CohereResponseHandlerTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/cohere/CohereResponseHandlerTests.java new file mode 100644 index 0000000000000..8873f603dd082 --- /dev/null +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/cohere/CohereResponseHandlerTests.java @@ -0,0 +1,126 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.cohere; + +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.HttpResponse; +import org.apache.http.StatusLine; +import org.apache.http.client.methods.HttpRequestBase; +import org.elasticsearch.ElasticsearchStatusException; +import org.elasticsearch.common.Strings; +import org.elasticsearch.core.Nullable; +import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.inference.external.http.HttpResult; +import org.elasticsearch.xpack.inference.external.http.retry.RetryException; +import org.hamcrest.MatcherAssert; + +import java.nio.charset.StandardCharsets; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.core.Is.is; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class CohereResponseHandlerTests extends ESTestCase { + public void testCheckForFailureStatusCode_DoesNotThrowFor200() { + callCheckForFailureStatusCode(200); + } + + public void testCheckForFailureStatusCode_ThrowsFor503() { + var exception = expectThrows(RetryException.class, () -> callCheckForFailureStatusCode(503)); + assertFalse(exception.shouldRetry()); + MatcherAssert.assertThat( + exception.getCause().getMessage(), + containsString("Received a server error status code for request [null] status [503]") + ); + MatcherAssert.assertThat(((ElasticsearchStatusException) exception.getCause()).status(), is(RestStatus.BAD_REQUEST)); + } + + public void testCheckForFailureStatusCode_ThrowsFor429() { + var exception = expectThrows(RetryException.class, () -> callCheckForFailureStatusCode(429)); + assertTrue(exception.shouldRetry()); + MatcherAssert.assertThat( + exception.getCause().getMessage(), + containsString("Received a rate limit status code for request [null] status [429]") + ); + MatcherAssert.assertThat(((ElasticsearchStatusException) exception.getCause()).status(), is(RestStatus.TOO_MANY_REQUESTS)); + } + + public void testCheckForFailureStatusCode_ThrowsFor400() { + var exception = expectThrows(RetryException.class, () -> callCheckForFailureStatusCode(400)); + assertFalse(exception.shouldRetry()); + MatcherAssert.assertThat( + exception.getCause().getMessage(), + containsString("Received an unsuccessful status code for request [null] status [400]") + ); + MatcherAssert.assertThat(((ElasticsearchStatusException) exception.getCause()).status(), is(RestStatus.BAD_REQUEST)); + } + + public void testCheckForFailureStatusCode_ThrowsFor400_TextsTooLarge() { + var exception = expectThrows( + RetryException.class, + () -> callCheckForFailureStatusCode(400, "invalid request: total number of texts must be at most 96 - received 100") + ); + assertFalse(exception.shouldRetry()); + MatcherAssert.assertThat( + exception.getCause().getMessage(), + containsString("Received a texts array too large response for request [null] status [400]") + ); + MatcherAssert.assertThat(((ElasticsearchStatusException) exception.getCause()).status(), is(RestStatus.BAD_REQUEST)); + } + + public void testCheckForFailureStatusCode_ThrowsFor401() { + var exception = expectThrows(RetryException.class, () -> callCheckForFailureStatusCode(401)); + assertFalse(exception.shouldRetry()); + MatcherAssert.assertThat( + exception.getCause().getMessage(), + containsString("Received an authentication error status code for request [null] status [401]") + ); + MatcherAssert.assertThat(((ElasticsearchStatusException) exception.getCause()).status(), is(RestStatus.UNAUTHORIZED)); + } + + public void testCheckForFailureStatusCode_ThrowsFor300() { + var exception = expectThrows(RetryException.class, () -> callCheckForFailureStatusCode(300)); + assertFalse(exception.shouldRetry()); + MatcherAssert.assertThat( + exception.getCause().getMessage(), + containsString("Unhandled redirection for request [null] status [300]") + ); + MatcherAssert.assertThat(((ElasticsearchStatusException) exception.getCause()).status(), is(RestStatus.MULTIPLE_CHOICES)); + } + + private static void callCheckForFailureStatusCode(int statusCode) { + callCheckForFailureStatusCode(statusCode, null); + } + + private static void callCheckForFailureStatusCode(int statusCode, @Nullable String errorMessage) { + var statusLine = mock(StatusLine.class); + when(statusLine.getStatusCode()).thenReturn(statusCode); + + var httpResponse = mock(HttpResponse.class); + when(httpResponse.getStatusLine()).thenReturn(statusLine); + var header = mock(Header.class); + when(header.getElements()).thenReturn(new HeaderElement[] {}); + when(httpResponse.getFirstHeader(anyString())).thenReturn(header); + + String responseJson = Strings.format(""" + { + "message": "%s" + } + """, errorMessage); + + var httpRequest = mock(HttpRequestBase.class); + var httpResult = new HttpResult(httpResponse, errorMessage == null ? new byte[] {} : responseJson.getBytes(StandardCharsets.UTF_8)); + var handler = new CohereResponseHandler("", (request, result) -> null); + + handler.checkForFailureStatusCode(httpRequest, httpResult); + } +} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereEmbeddingsRequestEntityTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereEmbeddingsRequestEntityTests.java new file mode 100644 index 0000000000000..8ef9ea4b0316b --- /dev/null +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereEmbeddingsRequestEntityTests.java @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.request.cohere; + +import org.elasticsearch.common.Strings; +import org.elasticsearch.inference.InputType; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xcontent.XContentBuilder; +import org.elasticsearch.xcontent.XContentFactory; +import org.elasticsearch.xcontent.XContentType; +import org.elasticsearch.xpack.inference.services.cohere.CohereTruncation; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingType; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsTaskSettings; +import org.hamcrest.MatcherAssert; + +import java.io.IOException; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; + +public class CohereEmbeddingsRequestEntityTests extends ESTestCase { + public void testXContent_WritesAllFields_WhenTheyAreDefined() throws IOException { + var entity = new CohereEmbeddingsRequestEntity( + List.of("abc"), + new CohereEmbeddingsTaskSettings(InputType.INGEST, CohereTruncation.START), + "model", + CohereEmbeddingType.FLOAT + ); + + XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON); + entity.toXContent(builder, null); + String xContentResult = Strings.toString(builder); + + MatcherAssert.assertThat(xContentResult, is(""" + {"texts":["abc"],"model":"model","input_type":"search_document","embedding_types":["float"],"truncate":"start"}""")); + } + + public void testXContent_InputTypeSearch_EmbeddingTypesInt8_TruncateNone() throws IOException { + var entity = new CohereEmbeddingsRequestEntity( + List.of("abc"), + new CohereEmbeddingsTaskSettings(InputType.SEARCH, CohereTruncation.NONE), + "model", + CohereEmbeddingType.INT8 + ); + + XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON); + entity.toXContent(builder, null); + String xContentResult = Strings.toString(builder); + + MatcherAssert.assertThat(xContentResult, is(""" + {"texts":["abc"],"model":"model","input_type":"search_query","embedding_types":["int8"],"truncate":"none"}""")); + } + + public void testXContent_WritesNoOptionalFields_WhenTheyAreNotDefined() throws IOException { + var entity = new CohereEmbeddingsRequestEntity(List.of("abc"), CohereEmbeddingsTaskSettings.EMPTY_SETTINGS, null, null); + + XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON); + entity.toXContent(builder, null); + String xContentResult = Strings.toString(builder); + + MatcherAssert.assertThat(xContentResult, is(""" + {"texts":["abc"]}""")); + } +} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereEmbeddingsRequestTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereEmbeddingsRequestTests.java new file mode 100644 index 0000000000000..a8a661149b120 --- /dev/null +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/request/cohere/CohereEmbeddingsRequestTests.java @@ -0,0 +1,164 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.request.cohere; + +import org.apache.http.HttpHeaders; +import org.apache.http.client.methods.HttpPost; +import org.elasticsearch.common.settings.SecureString; +import org.elasticsearch.core.Nullable; +import org.elasticsearch.inference.InputType; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xcontent.XContentType; +import org.elasticsearch.xpack.inference.external.cohere.CohereAccount; +import org.elasticsearch.xpack.inference.services.cohere.CohereTruncation; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingType; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsTaskSettings; +import org.hamcrest.MatcherAssert; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Map; + +import static org.elasticsearch.xpack.inference.external.http.Utils.entityAsMap; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; + +public class CohereEmbeddingsRequestTests extends ESTestCase { + public void testCreateRequest_UrlDefined() throws URISyntaxException, IOException { + var request = createRequest("url", "secret", List.of("abc"), CohereEmbeddingsTaskSettings.EMPTY_SETTINGS, null, null); + + var httpRequest = request.createRequest(); + MatcherAssert.assertThat(httpRequest, instanceOf(HttpPost.class)); + + var httpPost = (HttpPost) httpRequest; + + MatcherAssert.assertThat(httpPost.getURI().toString(), is("url")); + MatcherAssert.assertThat(httpPost.getLastHeader(HttpHeaders.CONTENT_TYPE).getValue(), is(XContentType.JSON.mediaType())); + MatcherAssert.assertThat(httpPost.getLastHeader(HttpHeaders.AUTHORIZATION).getValue(), is("Bearer secret")); + + var requestMap = entityAsMap(httpPost.getEntity().getContent()); + MatcherAssert.assertThat(requestMap, is(Map.of("texts", List.of("abc")))); + } + + public void testCreateRequest_AllOptionsDefined() throws URISyntaxException, IOException { + var request = createRequest( + "url", + "secret", + List.of("abc"), + new CohereEmbeddingsTaskSettings(InputType.INGEST, CohereTruncation.START), + "model", + CohereEmbeddingType.FLOAT + ); + + var httpRequest = request.createRequest(); + MatcherAssert.assertThat(httpRequest, instanceOf(HttpPost.class)); + + var httpPost = (HttpPost) httpRequest; + + MatcherAssert.assertThat(httpPost.getURI().toString(), is("url")); + MatcherAssert.assertThat(httpPost.getLastHeader(HttpHeaders.CONTENT_TYPE).getValue(), is(XContentType.JSON.mediaType())); + MatcherAssert.assertThat(httpPost.getLastHeader(HttpHeaders.AUTHORIZATION).getValue(), is("Bearer secret")); + + var requestMap = entityAsMap(httpPost.getEntity().getContent()); + MatcherAssert.assertThat( + requestMap, + is( + Map.of( + "texts", + List.of("abc"), + "model", + "model", + "input_type", + "search_document", + "embedding_types", + List.of("float"), + "truncate", + "start" + ) + ) + ); + } + + public void testCreateRequest_InputTypeSearch_EmbeddingTypeInt8_TruncateEnd() throws URISyntaxException, IOException { + var request = createRequest( + "url", + "secret", + List.of("abc"), + new CohereEmbeddingsTaskSettings(InputType.SEARCH, CohereTruncation.END), + "model", + CohereEmbeddingType.INT8 + ); + + var httpRequest = request.createRequest(); + MatcherAssert.assertThat(httpRequest, instanceOf(HttpPost.class)); + + var httpPost = (HttpPost) httpRequest; + + MatcherAssert.assertThat(httpPost.getURI().toString(), is("url")); + MatcherAssert.assertThat(httpPost.getLastHeader(HttpHeaders.CONTENT_TYPE).getValue(), is(XContentType.JSON.mediaType())); + MatcherAssert.assertThat(httpPost.getLastHeader(HttpHeaders.AUTHORIZATION).getValue(), is("Bearer secret")); + + var requestMap = entityAsMap(httpPost.getEntity().getContent()); + MatcherAssert.assertThat( + requestMap, + is( + Map.of( + "texts", + List.of("abc"), + "model", + "model", + "input_type", + "search_query", + "embedding_types", + List.of("int8"), + "truncate", + "end" + ) + ) + ); + } + + public void testCreateRequest_TruncateNone() throws URISyntaxException, IOException { + var request = createRequest( + "url", + "secret", + List.of("abc"), + new CohereEmbeddingsTaskSettings(null, CohereTruncation.NONE), + null, + null + ); + + var httpRequest = request.createRequest(); + MatcherAssert.assertThat(httpRequest, instanceOf(HttpPost.class)); + + var httpPost = (HttpPost) httpRequest; + + MatcherAssert.assertThat(httpPost.getURI().toString(), is("url")); + MatcherAssert.assertThat(httpPost.getLastHeader(HttpHeaders.CONTENT_TYPE).getValue(), is(XContentType.JSON.mediaType())); + MatcherAssert.assertThat(httpPost.getLastHeader(HttpHeaders.AUTHORIZATION).getValue(), is("Bearer secret")); + + var requestMap = entityAsMap(httpPost.getEntity().getContent()); + MatcherAssert.assertThat(requestMap, is(Map.of("texts", List.of("abc"), "truncate", "none"))); + } + + public static CohereEmbeddingsRequest createRequest( + @Nullable String url, + String apiKey, + List input, + CohereEmbeddingsTaskSettings taskSettings, + @Nullable String model, + @Nullable CohereEmbeddingType embeddingType + ) throws URISyntaxException { + var uri = url == null ? null : new URI(url); + + var account = new CohereAccount(uri, new SecureString(apiKey.toCharArray())); + return new CohereEmbeddingsRequest(account, input, taskSettings, model, embeddingType); + } +} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/response/cohere/CohereEmbeddingsResponseEntityTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/response/cohere/CohereEmbeddingsResponseEntityTests.java new file mode 100644 index 0000000000000..f04715be0838f --- /dev/null +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/response/cohere/CohereEmbeddingsResponseEntityTests.java @@ -0,0 +1,476 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.response.cohere; + +import org.apache.http.HttpResponse; +import org.elasticsearch.inference.InferenceServiceResults; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.core.inference.results.TextEmbeddingByteResults; +import org.elasticsearch.xpack.core.inference.results.TextEmbeddingResults; +import org.elasticsearch.xpack.inference.external.http.HttpResult; +import org.elasticsearch.xpack.inference.external.request.Request; +import org.hamcrest.MatcherAssert; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.List; + +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; + +public class CohereEmbeddingsResponseEntityTests extends ESTestCase { + public void testFromResponse_CreatesResultsForASingleItem() throws IOException { + String responseJson = """ + { + "id": "3198467e-399f-4d4a-aa2c-58af93bd6dc4", + "texts": [ + "hello" + ], + "embeddings": [ + [ + -0.0018434525, + 0.01777649 + ] + ], + "meta": { + "api_version": { + "version": "1" + }, + "billed_units": { + "input_tokens": 1 + } + }, + "response_type": "embeddings_floats" + } + """; + + InferenceServiceResults parsedResults = CohereEmbeddingsResponseEntity.fromResponse( + mock(Request.class), + new HttpResult(mock(HttpResponse.class), responseJson.getBytes(StandardCharsets.UTF_8)) + ); + + MatcherAssert.assertThat(parsedResults, instanceOf(TextEmbeddingResults.class)); + MatcherAssert.assertThat( + ((TextEmbeddingResults) parsedResults).embeddings(), + is(List.of(new TextEmbeddingResults.Embedding(List.of(-0.0018434525F, 0.01777649F)))) + ); + } + + public void testFromResponse_CreatesResultsForASingleItem_ObjectFormat() throws IOException { + String responseJson = """ + { + "id": "3198467e-399f-4d4a-aa2c-58af93bd6dc4", + "texts": [ + "hello" + ], + "embeddings": { + "float": [ + [ + -0.0018434525, + 0.01777649 + ] + ] + }, + "meta": { + "api_version": { + "version": "1" + }, + "billed_units": { + "input_tokens": 1 + } + }, + "response_type": "embeddings_floats" + } + """; + + TextEmbeddingResults parsedResults = (TextEmbeddingResults) CohereEmbeddingsResponseEntity.fromResponse( + mock(Request.class), + new HttpResult(mock(HttpResponse.class), responseJson.getBytes(StandardCharsets.UTF_8)) + ); + + MatcherAssert.assertThat( + parsedResults.embeddings(), + is(List.of(new TextEmbeddingResults.Embedding(List.of(-0.0018434525F, 0.01777649F)))) + ); + } + + public void testFromResponse_UsesTheFirstValidEmbeddingsEntry() throws IOException { + String responseJson = """ + { + "id": "3198467e-399f-4d4a-aa2c-58af93bd6dc4", + "texts": [ + "hello" + ], + "embeddings": { + "float": [ + [ + -0.0018434525, + 0.01777649 + ] + ], + "int8": [ + [ + -1, + 0 + ] + ] + }, + "meta": { + "api_version": { + "version": "1" + }, + "billed_units": { + "input_tokens": 1 + } + }, + "response_type": "embeddings_floats" + } + """; + + TextEmbeddingResults parsedResults = (TextEmbeddingResults) CohereEmbeddingsResponseEntity.fromResponse( + mock(Request.class), + new HttpResult(mock(HttpResponse.class), responseJson.getBytes(StandardCharsets.UTF_8)) + ); + + MatcherAssert.assertThat( + parsedResults.embeddings(), + is(List.of(new TextEmbeddingResults.Embedding(List.of(-0.0018434525F, 0.01777649F)))) + ); + } + + public void testFromResponse_UsesTheFirstValidEmbeddingsEntryInt8_WithInvalidFirst() throws IOException { + String responseJson = """ + { + "id": "3198467e-399f-4d4a-aa2c-58af93bd6dc4", + "texts": [ + "hello" + ], + "embeddings": { + "invalid_type": [ + [ + -0.0018434525, + 0.01777649 + ] + ], + "int8": [ + [ + -1, + 0 + ] + ] + }, + "meta": { + "api_version": { + "version": "1" + }, + "billed_units": { + "input_tokens": 1 + } + }, + "response_type": "embeddings_floats" + } + """; + + TextEmbeddingByteResults parsedResults = (TextEmbeddingByteResults) CohereEmbeddingsResponseEntity.fromResponse( + mock(Request.class), + new HttpResult(mock(HttpResponse.class), responseJson.getBytes(StandardCharsets.UTF_8)) + ); + + MatcherAssert.assertThat( + parsedResults.embeddings(), + is(List.of(new TextEmbeddingByteResults.Embedding(List.of((byte) -1, (byte) 0)))) + ); + } + + public void testFromResponse_ParsesBytes() throws IOException { + String responseJson = """ + { + "id": "3198467e-399f-4d4a-aa2c-58af93bd6dc4", + "texts": [ + "hello" + ], + "embeddings": { + "int8": [ + [ + -1, + 0 + ] + ] + }, + "meta": { + "api_version": { + "version": "1" + }, + "billed_units": { + "input_tokens": 1 + } + }, + "response_type": "embeddings_floats" + } + """; + + TextEmbeddingByteResults parsedResults = (TextEmbeddingByteResults) CohereEmbeddingsResponseEntity.fromResponse( + mock(Request.class), + new HttpResult(mock(HttpResponse.class), responseJson.getBytes(StandardCharsets.UTF_8)) + ); + + MatcherAssert.assertThat( + parsedResults.embeddings(), + is(List.of(new TextEmbeddingByteResults.Embedding(List.of((byte) -1, (byte) 0)))) + ); + } + + public void testFromResponse_CreatesResultsForMultipleItems() throws IOException { + String responseJson = """ + { + "id": "3198467e-399f-4d4a-aa2c-58af93bd6dc4", + "texts": [ + "hello" + ], + "embeddings": [ + [ + -0.0018434525, + 0.01777649 + ], + [ + -0.123, + 0.123 + ] + ], + "meta": { + "api_version": { + "version": "1" + }, + "billed_units": { + "input_tokens": 1 + } + }, + "response_type": "embeddings_floats" + } + """; + + TextEmbeddingResults parsedResults = (TextEmbeddingResults) CohereEmbeddingsResponseEntity.fromResponse( + mock(Request.class), + new HttpResult(mock(HttpResponse.class), responseJson.getBytes(StandardCharsets.UTF_8)) + ); + + MatcherAssert.assertThat( + parsedResults.embeddings(), + is( + List.of( + new TextEmbeddingResults.Embedding(List.of(-0.0018434525F, 0.01777649F)), + new TextEmbeddingResults.Embedding(List.of(-0.123F, 0.123F)) + ) + ) + ); + } + + public void testFromResponse_CreatesResultsForMultipleItems_ObjectFormat() throws IOException { + String responseJson = """ + { + "id": "3198467e-399f-4d4a-aa2c-58af93bd6dc4", + "texts": [ + "hello" + ], + "embeddings": { + "float": [ + [ + -0.0018434525, + 0.01777649 + ], + [ + -0.123, + 0.123 + ] + ] + }, + "meta": { + "api_version": { + "version": "1" + }, + "billed_units": { + "input_tokens": 1 + } + }, + "response_type": "embeddings_floats" + } + """; + + TextEmbeddingResults parsedResults = (TextEmbeddingResults) CohereEmbeddingsResponseEntity.fromResponse( + mock(Request.class), + new HttpResult(mock(HttpResponse.class), responseJson.getBytes(StandardCharsets.UTF_8)) + ); + + MatcherAssert.assertThat( + parsedResults.embeddings(), + is( + List.of( + new TextEmbeddingResults.Embedding(List.of(-0.0018434525F, 0.01777649F)), + new TextEmbeddingResults.Embedding(List.of(-0.123F, 0.123F)) + ) + ) + ); + } + + public void testFromResponse_FailsWhenEmbeddingsFieldIsNotPresent() { + String responseJson = """ + { + "id": "3198467e-399f-4d4a-aa2c-58af93bd6dc4", + "texts": [ + "hello" + ], + "embeddings_not_here": [ + [ + -0.0018434525, + 0.01777649 + ] + ], + "meta": { + "api_version": { + "version": "1" + }, + "billed_units": { + "input_tokens": 1 + } + }, + "response_type": "embeddings_floats" + } + """; + + var thrownException = expectThrows( + IllegalStateException.class, + () -> CohereEmbeddingsResponseEntity.fromResponse( + mock(Request.class), + new HttpResult(mock(HttpResponse.class), responseJson.getBytes(StandardCharsets.UTF_8)) + ) + ); + + MatcherAssert.assertThat( + thrownException.getMessage(), + is("Failed to find required field [embeddings] in Cohere embeddings response") + ); + } + + public void testFromResponse_FailsWhenEmbeddingsByteValue_IsOutsideByteRange_Negative() { + String responseJson = """ + { + "id": "3198467e-399f-4d4a-aa2c-58af93bd6dc4", + "texts": [ + "hello" + ], + "embeddings": { + "int8": [ + [ + -129, + 127 + ] + ] + }, + "meta": { + "api_version": { + "version": "1" + }, + "billed_units": { + "input_tokens": 1 + } + }, + "response_type": "embeddings_floats" + } + """; + + var thrownException = expectThrows( + IllegalArgumentException.class, + () -> CohereEmbeddingsResponseEntity.fromResponse( + mock(Request.class), + new HttpResult(mock(HttpResponse.class), responseJson.getBytes(StandardCharsets.UTF_8)) + ) + ); + + MatcherAssert.assertThat(thrownException.getMessage(), is("Value [-129] is out of range for a byte")); + } + + public void testFromResponse_FailsWhenEmbeddingsByteValue_IsOutsideByteRange_Positive() { + String responseJson = """ + { + "id": "3198467e-399f-4d4a-aa2c-58af93bd6dc4", + "texts": [ + "hello" + ], + "embeddings": { + "int8": [ + [ + -128, + 128 + ] + ] + }, + "meta": { + "api_version": { + "version": "1" + }, + "billed_units": { + "input_tokens": 1 + } + }, + "response_type": "embeddings_floats" + } + """; + + var thrownException = expectThrows( + IllegalArgumentException.class, + () -> CohereEmbeddingsResponseEntity.fromResponse( + mock(Request.class), + new HttpResult(mock(HttpResponse.class), responseJson.getBytes(StandardCharsets.UTF_8)) + ) + ); + + MatcherAssert.assertThat(thrownException.getMessage(), is("Value [128] is out of range for a byte")); + } + + public void testFromResponse_FailsToFindAValidEmbeddingType() { + String responseJson = """ + { + "id": "3198467e-399f-4d4a-aa2c-58af93bd6dc4", + "texts": [ + "hello" + ], + "embeddings": { + "invalid_type": [ + [ + -0.0018434525, + 0.01777649 + ] + ] + }, + "meta": { + "api_version": { + "version": "1" + }, + "billed_units": { + "input_tokens": 1 + } + }, + "response_type": "embeddings_floats" + } + """; + + var thrownException = expectThrows( + IllegalStateException.class, + () -> CohereEmbeddingsResponseEntity.fromResponse( + mock(Request.class), + new HttpResult(mock(HttpResponse.class), responseJson.getBytes(StandardCharsets.UTF_8)) + ) + ); + + MatcherAssert.assertThat( + thrownException.getMessage(), + is("Failed to find a supported embedding type in the Cohere embeddings response. Supported types are [float, int8]") + ); + } +} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/response/cohere/CohereErrorResponseEntityTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/response/cohere/CohereErrorResponseEntityTests.java new file mode 100644 index 0000000000000..a2b1c26b2b3d5 --- /dev/null +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/external/response/cohere/CohereErrorResponseEntityTests.java @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.external.response.cohere; + +import org.apache.http.HttpResponse; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.inference.external.http.HttpResult; +import org.hamcrest.MatcherAssert; + +import java.nio.charset.StandardCharsets; + +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; + +public class CohereErrorResponseEntityTests extends ESTestCase { + public void testFromResponse() { + String responseJson = """ + { + "message": "invalid request: total number of texts must be at most 96 - received 97" + } + """; + + CohereErrorResponseEntity errorMessage = CohereErrorResponseEntity.fromResponse( + new HttpResult(mock(HttpResponse.class), responseJson.getBytes(StandardCharsets.UTF_8)) + ); + assertNotNull(errorMessage); + MatcherAssert.assertThat( + errorMessage.getErrorMessage(), + is("invalid request: total number of texts must be at most 96 - received 97") + ); + } + + public void testFromResponse_noMessage() { + String responseJson = """ + { + "error": "abc" + } + """; + + CohereErrorResponseEntity errorMessage = CohereErrorResponseEntity.fromResponse( + new HttpResult(mock(HttpResponse.class), responseJson.getBytes(StandardCharsets.UTF_8)) + ); + assertNull(errorMessage); + } +} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/results/TextEmbeddingByteResultsTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/results/TextEmbeddingByteResultsTests.java new file mode 100644 index 0000000000000..b9318db6ece34 --- /dev/null +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/results/TextEmbeddingByteResultsTests.java @@ -0,0 +1,165 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.results; + +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.test.AbstractWireSerializingTestCase; +import org.elasticsearch.xpack.core.inference.results.TextEmbeddingByteResults; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.hamcrest.Matchers.is; + +public class TextEmbeddingByteResultsTests extends AbstractWireSerializingTestCase { + public static TextEmbeddingByteResults createRandomResults() { + int embeddings = randomIntBetween(1, 10); + List embeddingResults = new ArrayList<>(embeddings); + + for (int i = 0; i < embeddings; i++) { + embeddingResults.add(createRandomEmbedding()); + } + + return new TextEmbeddingByteResults(embeddingResults); + } + + private static TextEmbeddingByteResults.Embedding createRandomEmbedding() { + int columns = randomIntBetween(1, 10); + List floats = new ArrayList<>(columns); + + for (int i = 0; i < columns; i++) { + floats.add(randomByte()); + } + + return new TextEmbeddingByteResults.Embedding(floats); + } + + public void testToXContent_CreatesTheRightFormatForASingleEmbedding() throws IOException { + var entity = new TextEmbeddingByteResults(List.of(new TextEmbeddingByteResults.Embedding(List.of((byte) 23)))); + + assertThat( + entity.asMap(), + is( + Map.of( + TextEmbeddingByteResults.TEXT_EMBEDDING, + List.of(Map.of(TextEmbeddingByteResults.Embedding.EMBEDDING, List.of((byte) 23))) + ) + ) + ); + + String xContentResult = Strings.toString(entity, true, true); + assertThat(xContentResult, is(""" + { + "text_embedding" : [ + { + "embedding" : [ + 23 + ] + } + ] + }""")); + } + + public void testToXContent_CreatesTheRightFormatForMultipleEmbeddings() throws IOException { + var entity = new TextEmbeddingByteResults( + List.of(new TextEmbeddingByteResults.Embedding(List.of((byte) 23)), new TextEmbeddingByteResults.Embedding(List.of((byte) 24))) + + ); + + assertThat( + entity.asMap(), + is( + Map.of( + TextEmbeddingByteResults.TEXT_EMBEDDING, + List.of( + Map.of(TextEmbeddingByteResults.Embedding.EMBEDDING, List.of((byte) 23)), + Map.of(TextEmbeddingByteResults.Embedding.EMBEDDING, List.of((byte) 24)) + ) + ) + ) + ); + + String xContentResult = Strings.toString(entity, true, true); + assertThat(xContentResult, is(""" + { + "text_embedding" : [ + { + "embedding" : [ + 23 + ] + }, + { + "embedding" : [ + 24 + ] + } + ] + }""")); + } + + public void testTransformToCoordinationFormat() { + var results = new TextEmbeddingByteResults( + List.of( + new TextEmbeddingByteResults.Embedding(List.of((byte) 23, (byte) 24)), + new TextEmbeddingByteResults.Embedding(List.of((byte) 25, (byte) 26)) + ) + ).transformToCoordinationFormat(); + + assertThat( + results, + is( + List.of( + new org.elasticsearch.xpack.core.ml.inference.results.TextEmbeddingResults( + TextEmbeddingByteResults.TEXT_EMBEDDING, + new double[] { 23F, 24F }, + false + ), + new org.elasticsearch.xpack.core.ml.inference.results.TextEmbeddingResults( + TextEmbeddingByteResults.TEXT_EMBEDDING, + new double[] { 25F, 26F }, + false + ) + ) + ) + ); + } + + @Override + protected Writeable.Reader instanceReader() { + return TextEmbeddingByteResults::new; + } + + @Override + protected TextEmbeddingByteResults createTestInstance() { + return createRandomResults(); + } + + @Override + protected TextEmbeddingByteResults mutateInstance(TextEmbeddingByteResults instance) throws IOException { + // if true we reduce the embeddings list by a random amount, if false we add an embedding to the list + if (randomBoolean()) { + // -1 to remove at least one item from the list + int end = randomInt(instance.embeddings().size() - 1); + return new TextEmbeddingByteResults(instance.embeddings().subList(0, end)); + } else { + List embeddings = new ArrayList<>(instance.embeddings()); + embeddings.add(createRandomEmbedding()); + return new TextEmbeddingByteResults(embeddings); + } + } + + public static Map buildExpectation(List> embeddings) { + return Map.of( + TextEmbeddingByteResults.TEXT_EMBEDDING, + embeddings.stream().map(embedding -> Map.of(TextEmbeddingByteResults.Embedding.EMBEDDING, embedding)).toList() + ); + } +} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/ServiceUtilsTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/ServiceUtilsTests.java index eb54745806a68..b935c5a8c64b3 100644 --- a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/ServiceUtilsTests.java +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/ServiceUtilsTests.java @@ -8,24 +8,45 @@ package org.elasticsearch.xpack.inference.services; import org.elasticsearch.ElasticsearchStatusException; +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.common.ValidationException; +import org.elasticsearch.core.TimeValue; +import org.elasticsearch.inference.InferenceService; +import org.elasticsearch.inference.InferenceServiceResults; +import org.elasticsearch.inference.InputType; +import org.elasticsearch.inference.Model; +import org.elasticsearch.inference.TaskType; import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.core.inference.results.TextEmbeddingByteResults; +import org.elasticsearch.xpack.core.inference.results.TextEmbeddingResults; +import org.elasticsearch.xpack.inference.results.TextEmbeddingByteResultsTests; +import org.elasticsearch.xpack.inference.results.TextEmbeddingResultsTests; import java.util.HashMap; +import java.util.List; import java.util.Map; import static org.elasticsearch.xpack.inference.services.ServiceUtils.convertToUri; import static org.elasticsearch.xpack.inference.services.ServiceUtils.createUri; +import static org.elasticsearch.xpack.inference.services.ServiceUtils.extractOptionalEnum; import static org.elasticsearch.xpack.inference.services.ServiceUtils.extractOptionalString; import static org.elasticsearch.xpack.inference.services.ServiceUtils.extractRequiredSecureString; import static org.elasticsearch.xpack.inference.services.ServiceUtils.extractRequiredString; +import static org.elasticsearch.xpack.inference.services.ServiceUtils.getEmbeddingSize; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class ServiceUtilsTests extends ESTestCase { + private static final TimeValue TIMEOUT = TimeValue.timeValueSeconds(30); + public void testRemoveAsTypeWithTheCorrectType() { Map map = new HashMap<>(Map.of("a", 5, "b", "a string", "c", Boolean.TRUE, "d", 1.0)); @@ -105,10 +126,11 @@ public void testConvertToUri_CreatesUri() { assertThat(uri.toString(), is("www.elastic.co")); } - public void testConvertToUri_ThrowsNullPointerException_WhenPassedNull() { + public void testConvertToUri_DoesNotThrowNullPointerException_WhenPassedNull() { var validation = new ValidationException(); - expectThrows(NullPointerException.class, () -> convertToUri(null, "name", "scope", validation)); + var uri = convertToUri(null, "name", "scope", validation); + assertNull(uri); assertTrue(validation.validationErrors().isEmpty()); } @@ -236,6 +258,124 @@ public void testExtractOptionalString_AddsException_WhenFieldIsEmpty() { assertThat(validation.validationErrors().get(0), is("[scope] Invalid value empty string. [key] must be a non-empty string")); } + public void testExtractOptionalEnum_ReturnsNull_WhenFieldDoesNotExist() { + var validation = new ValidationException(); + Map map = modifiableMap(Map.of("key", "value")); + var createdEnum = extractOptionalEnum(map, "abc", "scope", InputType::fromString, InputType.values(), validation); + + assertNull(createdEnum); + assertTrue(validation.validationErrors().isEmpty()); + assertThat(map.size(), is(1)); + } + + public void testExtractOptionalEnum_ReturnsNullAndAddsException_WhenAnInvalidValueExists() { + var validation = new ValidationException(); + Map map = modifiableMap(Map.of("key", "invalid_value")); + var createdEnum = extractOptionalEnum(map, "key", "scope", InputType::fromString, InputType.values(), validation); + + assertNull(createdEnum); + assertFalse(validation.validationErrors().isEmpty()); + assertTrue(map.isEmpty()); + assertThat( + validation.validationErrors().get(0), + is("[scope] Invalid value [invalid_value] received. [key] must be one of [ingest, search]") + ); + } + + public void testGetEmbeddingSize_ReturnsError_WhenTextEmbeddingResults_IsEmpty() { + var service = mock(InferenceService.class); + + var model = mock(Model.class); + when(model.getTaskType()).thenReturn(TaskType.TEXT_EMBEDDING); + + doAnswer(invocation -> { + @SuppressWarnings("unchecked") + ActionListener listener = (ActionListener) invocation.getArguments()[3]; + listener.onResponse(new TextEmbeddingResults(List.of())); + + return Void.TYPE; + }).when(service).infer(any(), any(), any(), any()); + + PlainActionFuture listener = new PlainActionFuture<>(); + getEmbeddingSize(model, service, listener); + + var thrownException = expectThrows(ElasticsearchStatusException.class, () -> listener.actionGet(TIMEOUT)); + + assertThat(thrownException.getMessage(), is("Could not determine embedding size")); + assertThat(thrownException.getCause().getMessage(), is("Embeddings list is empty")); + } + + public void testGetEmbeddingSize_ReturnsError_WhenTextEmbeddingByteResults_IsEmpty() { + var service = mock(InferenceService.class); + + var model = mock(Model.class); + when(model.getTaskType()).thenReturn(TaskType.TEXT_EMBEDDING); + + doAnswer(invocation -> { + @SuppressWarnings("unchecked") + ActionListener listener = (ActionListener) invocation.getArguments()[3]; + listener.onResponse(new TextEmbeddingByteResults(List.of())); + + return Void.TYPE; + }).when(service).infer(any(), any(), any(), any()); + + PlainActionFuture listener = new PlainActionFuture<>(); + getEmbeddingSize(model, service, listener); + + var thrownException = expectThrows(ElasticsearchStatusException.class, () -> listener.actionGet(TIMEOUT)); + + assertThat(thrownException.getMessage(), is("Could not determine embedding size")); + assertThat(thrownException.getCause().getMessage(), is("Embeddings list is empty")); + } + + public void testGetEmbeddingSize_ReturnsSize_ForTextEmbeddingResults() { + var service = mock(InferenceService.class); + + var model = mock(Model.class); + when(model.getTaskType()).thenReturn(TaskType.TEXT_EMBEDDING); + + var textEmbedding = TextEmbeddingResultsTests.createRandomResults(); + + doAnswer(invocation -> { + @SuppressWarnings("unchecked") + ActionListener listener = (ActionListener) invocation.getArguments()[3]; + listener.onResponse(textEmbedding); + + return Void.TYPE; + }).when(service).infer(any(), any(), any(), any()); + + PlainActionFuture listener = new PlainActionFuture<>(); + getEmbeddingSize(model, service, listener); + + var size = listener.actionGet(TIMEOUT); + + assertThat(size, is(textEmbedding.embeddings().get(0).values().size())); + } + + public void testGetEmbeddingSize_ReturnsSize_ForTextEmbeddingByteResults() { + var service = mock(InferenceService.class); + + var model = mock(Model.class); + when(model.getTaskType()).thenReturn(TaskType.TEXT_EMBEDDING); + + var textEmbedding = TextEmbeddingByteResultsTests.createRandomResults(); + + doAnswer(invocation -> { + @SuppressWarnings("unchecked") + ActionListener listener = (ActionListener) invocation.getArguments()[3]; + listener.onResponse(textEmbedding); + + return Void.TYPE; + }).when(service).infer(any(), any(), any(), any()); + + PlainActionFuture listener = new PlainActionFuture<>(); + getEmbeddingSize(model, service, listener); + + var size = listener.actionGet(TIMEOUT); + + assertThat(size, is(textEmbedding.embeddings().get(0).values().size())); + } + private static Map modifiableMap(Map aMap) { return new HashMap<>(aMap); } diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/CohereServiceSettingsTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/CohereServiceSettingsTests.java new file mode 100644 index 0000000000000..6f47d5c74d81c --- /dev/null +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/CohereServiceSettingsTests.java @@ -0,0 +1,160 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.services.cohere; + +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.ValidationException; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.core.Nullable; +import org.elasticsearch.test.AbstractWireSerializingTestCase; +import org.elasticsearch.xpack.inference.common.SimilarityMeasure; +import org.elasticsearch.xpack.inference.services.ServiceFields; +import org.elasticsearch.xpack.inference.services.ServiceUtils; +import org.hamcrest.MatcherAssert; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; + +public class CohereServiceSettingsTests extends AbstractWireSerializingTestCase { + + public static CohereServiceSettings createRandomWithNonNullUrl() { + return createRandom(randomAlphaOfLength(15)); + } + + /** + * The created settings can have a url set to null. + */ + public static CohereServiceSettings createRandom() { + var url = randomBoolean() ? randomAlphaOfLength(15) : null; + return createRandom(url); + } + + private static CohereServiceSettings createRandom(String url) { + SimilarityMeasure similarityMeasure = null; + Integer dims = null; + var isTextEmbeddingModel = randomBoolean(); + if (isTextEmbeddingModel) { + similarityMeasure = SimilarityMeasure.DOT_PRODUCT; + dims = 1536; + } + Integer maxInputTokens = randomBoolean() ? null : randomIntBetween(128, 256); + var model = randomBoolean() ? randomAlphaOfLength(15) : null; + + return new CohereServiceSettings(ServiceUtils.createOptionalUri(url), similarityMeasure, dims, maxInputTokens, model); + } + + public void testFromMap() { + var url = "https://www.abc.com"; + var similarity = SimilarityMeasure.DOT_PRODUCT.toString(); + var dims = 1536; + var maxInputTokens = 512; + var model = "model"; + var serviceSettings = CohereServiceSettings.fromMap( + new HashMap<>( + Map.of( + ServiceFields.URL, + url, + ServiceFields.SIMILARITY, + similarity, + ServiceFields.DIMENSIONS, + dims, + ServiceFields.MAX_INPUT_TOKENS, + maxInputTokens, + CohereServiceSettings.MODEL, + model + ) + ) + ); + + MatcherAssert.assertThat( + serviceSettings, + is(new CohereServiceSettings(ServiceUtils.createUri(url), SimilarityMeasure.DOT_PRODUCT, dims, maxInputTokens, model)) + ); + } + + public void testFromMap_MissingUrl_DoesNotThrowException() { + var serviceSettings = CohereServiceSettings.fromMap(new HashMap<>(Map.of())); + assertNull(serviceSettings.getUri()); + } + + public void testFromMap_EmptyUrl_ThrowsError() { + var thrownException = expectThrows( + ValidationException.class, + () -> CohereServiceSettings.fromMap(new HashMap<>(Map.of(ServiceFields.URL, ""))) + ); + + MatcherAssert.assertThat( + thrownException.getMessage(), + containsString( + Strings.format( + "Validation Failed: 1: [service_settings] Invalid value empty string. [%s] must be a non-empty string;", + ServiceFields.URL + ) + ) + ); + } + + public void testFromMap_InvalidUrl_ThrowsError() { + var url = "https://www.abc^.com"; + var thrownException = expectThrows( + ValidationException.class, + () -> CohereServiceSettings.fromMap(new HashMap<>(Map.of(ServiceFields.URL, url))) + ); + + MatcherAssert.assertThat( + thrownException.getMessage(), + is(Strings.format("Validation Failed: 1: [service_settings] Invalid url [%s] received for field [%s];", url, ServiceFields.URL)) + ); + } + + public void testFromMap_InvalidSimilarity_ThrowsError() { + var similarity = "by_size"; + var thrownException = expectThrows( + ValidationException.class, + () -> CohereServiceSettings.fromMap(new HashMap<>(Map.of(ServiceFields.SIMILARITY, similarity))) + ); + + MatcherAssert.assertThat( + thrownException.getMessage(), + is("Validation Failed: 1: [service_settings] Unknown similarity measure [by_size];") + ); + } + + @Override + protected Writeable.Reader instanceReader() { + return CohereServiceSettings::new; + } + + @Override + protected CohereServiceSettings createTestInstance() { + return createRandomWithNonNullUrl(); + } + + @Override + protected CohereServiceSettings mutateInstance(CohereServiceSettings instance) throws IOException { + return null; + } + + public static Map getServiceSettingsMap(@Nullable String url, @Nullable String model) { + var map = new HashMap(); + + if (url != null) { + map.put(ServiceFields.URL, url); + } + + if (model != null) { + map.put(CohereServiceSettings.MODEL, model); + } + + return map; + } +} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/CohereServiceTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/CohereServiceTests.java new file mode 100644 index 0000000000000..0250e08a48452 --- /dev/null +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/CohereServiceTests.java @@ -0,0 +1,895 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.services.cohere; + +import org.apache.http.HttpHeaders; +import org.apache.lucene.util.SetOnce; +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.ElasticsearchStatusException; +import org.elasticsearch.action.support.PlainActionFuture; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.core.TimeValue; +import org.elasticsearch.inference.InferenceServiceResults; +import org.elasticsearch.inference.InputType; +import org.elasticsearch.inference.Model; +import org.elasticsearch.inference.ModelConfigurations; +import org.elasticsearch.inference.ModelSecrets; +import org.elasticsearch.inference.TaskType; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.test.http.MockResponse; +import org.elasticsearch.test.http.MockWebServer; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.xcontent.XContentType; +import org.elasticsearch.xpack.inference.external.http.HttpClientManager; +import org.elasticsearch.xpack.inference.external.http.sender.HttpRequestSenderFactory; +import org.elasticsearch.xpack.inference.external.http.sender.Sender; +import org.elasticsearch.xpack.inference.logging.ThrottlerManager; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingType; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsModel; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsModelTests; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsServiceSettingsTests; +import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsTaskSettings; +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; +import org.junit.After; +import org.junit.Before; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import static org.elasticsearch.xpack.inference.Utils.inferenceUtilityPool; +import static org.elasticsearch.xpack.inference.Utils.mockClusterServiceEmpty; +import static org.elasticsearch.xpack.inference.external.http.Utils.entityAsMap; +import static org.elasticsearch.xpack.inference.external.http.Utils.getUrl; +import static org.elasticsearch.xpack.inference.results.TextEmbeddingResultsTests.buildExpectation; +import static org.elasticsearch.xpack.inference.services.ServiceComponentsTests.createWithEmptySettings; +import static org.elasticsearch.xpack.inference.services.Utils.getInvalidModel; +import static org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsTaskSettingsTests.getTaskSettingsMap; +import static org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsTaskSettingsTests.getTaskSettingsMapEmpty; +import static org.elasticsearch.xpack.inference.services.settings.DefaultSecretSettingsTests.getSecretSettingsMap; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.instanceOf; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +public class CohereServiceTests extends ESTestCase { + private static final TimeValue TIMEOUT = new TimeValue(30, TimeUnit.SECONDS); + private final MockWebServer webServer = new MockWebServer(); + private ThreadPool threadPool; + private HttpClientManager clientManager; + + @Before + public void init() throws Exception { + webServer.start(); + threadPool = createThreadPool(inferenceUtilityPool()); + clientManager = HttpClientManager.create(Settings.EMPTY, threadPool, mockClusterServiceEmpty(), mock(ThrottlerManager.class)); + } + + @After + public void shutdown() throws IOException { + clientManager.close(); + terminate(threadPool); + webServer.close(); + } + + public void testParseRequestConfig_CreatesACohereEmbeddingsModel() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var model = service.parseRequestConfig( + "id", + TaskType.TEXT_EMBEDDING, + getRequestConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", "model", CohereEmbeddingType.FLOAT), + getTaskSettingsMap(InputType.INGEST, CohereTruncation.START), + getSecretSettingsMap("secret") + ), + Set.of() + ); + + MatcherAssert.assertThat(model, instanceOf(CohereEmbeddingsModel.class)); + + var embeddingsModel = (CohereEmbeddingsModel) model; + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getUri().toString(), is("url")); + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getModel(), is("model")); + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getEmbeddingType(), is(CohereEmbeddingType.FLOAT)); + MatcherAssert.assertThat( + embeddingsModel.getTaskSettings(), + is(new CohereEmbeddingsTaskSettings(InputType.INGEST, CohereTruncation.START)) + ); + MatcherAssert.assertThat(embeddingsModel.getSecretSettings().apiKey().toString(), is("secret")); + } + } + + public void testParseRequestConfig_ThrowsUnsupportedModelType() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var thrownException = expectThrows( + ElasticsearchStatusException.class, + () -> service.parseRequestConfig( + "id", + TaskType.SPARSE_EMBEDDING, + getRequestConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", null, null), + getTaskSettingsMapEmpty(), + getSecretSettingsMap("secret") + ), + Set.of() + ) + ); + + MatcherAssert.assertThat( + thrownException.getMessage(), + is("The [cohere] service does not support task type [sparse_embedding]") + ); + } + } + + public void testParseRequestConfig_ThrowsWhenAnExtraKeyExistsInConfig() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var config = getRequestConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", null, null), + getTaskSettingsMapEmpty(), + getSecretSettingsMap("secret") + ); + config.put("extra_key", "value"); + + var thrownException = expectThrows( + ElasticsearchStatusException.class, + () -> service.parseRequestConfig("id", TaskType.TEXT_EMBEDDING, config, Set.of()) + ); + + MatcherAssert.assertThat( + thrownException.getMessage(), + is("Model configuration contains settings [{extra_key=value}] unknown to the [cohere] service") + ); + } + } + + public void testParseRequestConfig_ThrowsWhenAnExtraKeyExistsInServiceSettingsMap() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var serviceSettings = CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", "model", null); + serviceSettings.put("extra_key", "value"); + + var config = getRequestConfigMap(serviceSettings, getTaskSettingsMap(null, null), getSecretSettingsMap("secret")); + + var thrownException = expectThrows( + ElasticsearchStatusException.class, + () -> service.parseRequestConfig("id", TaskType.TEXT_EMBEDDING, config, Set.of()) + ); + + MatcherAssert.assertThat( + thrownException.getMessage(), + is("Model configuration contains settings [{extra_key=value}] unknown to the [cohere] service") + ); + } + } + + public void testParseRequestConfig_ThrowsWhenAnExtraKeyExistsInTaskSettingsMap() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var taskSettingsMap = getTaskSettingsMap(InputType.INGEST, null); + taskSettingsMap.put("extra_key", "value"); + + var config = getRequestConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", "model", null), + taskSettingsMap, + getSecretSettingsMap("secret") + ); + + var thrownException = expectThrows( + ElasticsearchStatusException.class, + () -> service.parseRequestConfig("id", TaskType.TEXT_EMBEDDING, config, Set.of()) + ); + + MatcherAssert.assertThat( + thrownException.getMessage(), + is("Model configuration contains settings [{extra_key=value}] unknown to the [cohere] service") + ); + } + } + + public void testParseRequestConfig_ThrowsWhenAnExtraKeyExistsInSecretSettingsMap() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var secretSettingsMap = getSecretSettingsMap("secret"); + secretSettingsMap.put("extra_key", "value"); + + var config = getRequestConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", null, null), + getTaskSettingsMapEmpty(), + secretSettingsMap + ); + + var thrownException = expectThrows( + ElasticsearchStatusException.class, + () -> service.parseRequestConfig("id", TaskType.TEXT_EMBEDDING, config, Set.of()) + ); + + MatcherAssert.assertThat( + thrownException.getMessage(), + is("Model configuration contains settings [{extra_key=value}] unknown to the [cohere] service") + ); + } + } + + public void testParseRequestConfig_CreatesACohereEmbeddingsModelWithoutUrl() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var model = service.parseRequestConfig( + "id", + TaskType.TEXT_EMBEDDING, + getRequestConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap(null, null, null), + getTaskSettingsMapEmpty(), + getSecretSettingsMap("secret") + ), + Set.of() + ); + + MatcherAssert.assertThat(model, instanceOf(CohereEmbeddingsModel.class)); + + var embeddingsModel = (CohereEmbeddingsModel) model; + assertNull(embeddingsModel.getServiceSettings().getCommonSettings().getUri()); + MatcherAssert.assertThat(embeddingsModel.getTaskSettings(), is(CohereEmbeddingsTaskSettings.EMPTY_SETTINGS)); + MatcherAssert.assertThat(embeddingsModel.getSecretSettings().apiKey().toString(), is("secret")); + } + } + + public void testParsePersistedConfigWithSecrets_CreatesACohereEmbeddingsModel() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var persistedConfig = getPersistedConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", "model", null), + getTaskSettingsMap(null, null), + getSecretSettingsMap("secret") + ); + + var model = service.parsePersistedConfigWithSecrets( + "id", + TaskType.TEXT_EMBEDDING, + persistedConfig.config(), + persistedConfig.secrets() + ); + + MatcherAssert.assertThat(model, instanceOf(CohereEmbeddingsModel.class)); + + var embeddingsModel = (CohereEmbeddingsModel) model; + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getUri().toString(), is("url")); + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getModel(), is("model")); + MatcherAssert.assertThat(embeddingsModel.getTaskSettings(), is(new CohereEmbeddingsTaskSettings(null, null))); + MatcherAssert.assertThat(embeddingsModel.getSecretSettings().apiKey().toString(), is("secret")); + } + } + + public void testParsePersistedConfigWithSecrets_ThrowsErrorTryingToParseInvalidModel() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var persistedConfig = getPersistedConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", null, null), + getTaskSettingsMapEmpty(), + getSecretSettingsMap("secret") + ); + + var thrownException = expectThrows( + ElasticsearchStatusException.class, + () -> service.parsePersistedConfigWithSecrets( + "id", + TaskType.SPARSE_EMBEDDING, + persistedConfig.config(), + persistedConfig.secrets() + ) + ); + + MatcherAssert.assertThat( + thrownException.getMessage(), + is("Failed to parse stored model [id] for [cohere] service, please delete and add the service again") + ); + } + } + + public void testParsePersistedConfigWithSecrets_CreatesACohereEmbeddingsModelWithoutUrl() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var persistedConfig = getPersistedConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap(null, null, null), + getTaskSettingsMap(InputType.INGEST, null), + getSecretSettingsMap("secret") + ); + + var model = service.parsePersistedConfigWithSecrets( + "id", + TaskType.TEXT_EMBEDDING, + persistedConfig.config(), + persistedConfig.secrets() + ); + + MatcherAssert.assertThat(model, instanceOf(CohereEmbeddingsModel.class)); + + var embeddingsModel = (CohereEmbeddingsModel) model; + assertNull(embeddingsModel.getServiceSettings().getCommonSettings().getUri()); + MatcherAssert.assertThat(embeddingsModel.getTaskSettings(), is(new CohereEmbeddingsTaskSettings(InputType.INGEST, null))); + MatcherAssert.assertThat(embeddingsModel.getSecretSettings().apiKey().toString(), is("secret")); + } + } + + public void testParsePersistedConfigWithSecrets_DoesNotThrowWhenAnExtraKeyExistsInConfig() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var persistedConfig = getPersistedConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", "model", CohereEmbeddingType.INT8), + getTaskSettingsMap(InputType.SEARCH, CohereTruncation.NONE), + getSecretSettingsMap("secret") + ); + persistedConfig.config().put("extra_key", "value"); + + var model = service.parsePersistedConfigWithSecrets( + "id", + TaskType.TEXT_EMBEDDING, + persistedConfig.config(), + persistedConfig.secrets() + ); + + MatcherAssert.assertThat(model, instanceOf(CohereEmbeddingsModel.class)); + + var embeddingsModel = (CohereEmbeddingsModel) model; + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getUri().toString(), is("url")); + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getModel(), is("model")); + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getEmbeddingType(), is(CohereEmbeddingType.INT8)); + MatcherAssert.assertThat( + embeddingsModel.getTaskSettings(), + is(new CohereEmbeddingsTaskSettings(InputType.SEARCH, CohereTruncation.NONE)) + ); + MatcherAssert.assertThat(embeddingsModel.getSecretSettings().apiKey().toString(), is("secret")); + } + } + + public void testParsePersistedConfigWithSecrets_DoesNotThrowWhenAnExtraKeyExistsInSecretsSettings() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var secretSettingsMap = getSecretSettingsMap("secret"); + secretSettingsMap.put("extra_key", "value"); + + var persistedConfig = getPersistedConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", null, null), + getTaskSettingsMapEmpty(), + secretSettingsMap + ); + + var model = service.parsePersistedConfigWithSecrets( + "id", + TaskType.TEXT_EMBEDDING, + persistedConfig.config(), + persistedConfig.secrets() + ); + + MatcherAssert.assertThat(model, instanceOf(CohereEmbeddingsModel.class)); + + var embeddingsModel = (CohereEmbeddingsModel) model; + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getUri().toString(), is("url")); + MatcherAssert.assertThat(embeddingsModel.getTaskSettings(), is(CohereEmbeddingsTaskSettings.EMPTY_SETTINGS)); + MatcherAssert.assertThat(embeddingsModel.getSecretSettings().apiKey().toString(), is("secret")); + } + } + + public void testParsePersistedConfigWithSecrets_NotThrowWhenAnExtraKeyExistsInSecrets() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var persistedConfig = getPersistedConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", "model", null), + getTaskSettingsMap(null, null), + getSecretSettingsMap("secret") + ); + persistedConfig.secrets.put("extra_key", "value"); + + var model = service.parsePersistedConfigWithSecrets( + "id", + TaskType.TEXT_EMBEDDING, + persistedConfig.config(), + persistedConfig.secrets() + ); + + MatcherAssert.assertThat(model, instanceOf(CohereEmbeddingsModel.class)); + + var embeddingsModel = (CohereEmbeddingsModel) model; + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getUri().toString(), is("url")); + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getModel(), is("model")); + MatcherAssert.assertThat(embeddingsModel.getTaskSettings(), is(new CohereEmbeddingsTaskSettings(null, null))); + MatcherAssert.assertThat(embeddingsModel.getSecretSettings().apiKey().toString(), is("secret")); + } + } + + public void testParsePersistedConfigWithSecrets_NotThrowWhenAnExtraKeyExistsInServiceSettings() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var serviceSettingsMap = CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", null, null); + serviceSettingsMap.put("extra_key", "value"); + + var persistedConfig = getPersistedConfigMap(serviceSettingsMap, getTaskSettingsMapEmpty(), getSecretSettingsMap("secret")); + + var model = service.parsePersistedConfigWithSecrets( + "id", + TaskType.TEXT_EMBEDDING, + persistedConfig.config(), + persistedConfig.secrets() + ); + + MatcherAssert.assertThat(model, instanceOf(CohereEmbeddingsModel.class)); + + var embeddingsModel = (CohereEmbeddingsModel) model; + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getUri().toString(), is("url")); + MatcherAssert.assertThat(embeddingsModel.getTaskSettings(), is(CohereEmbeddingsTaskSettings.EMPTY_SETTINGS)); + MatcherAssert.assertThat(embeddingsModel.getSecretSettings().apiKey().toString(), is("secret")); + } + } + + public void testParsePersistedConfigWithSecrets_NotThrowWhenAnExtraKeyExistsInTaskSettings() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var taskSettingsMap = getTaskSettingsMap(InputType.SEARCH, null); + taskSettingsMap.put("extra_key", "value"); + + var persistedConfig = getPersistedConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", "model", null), + taskSettingsMap, + getSecretSettingsMap("secret") + ); + + var model = service.parsePersistedConfigWithSecrets( + "id", + TaskType.TEXT_EMBEDDING, + persistedConfig.config(), + persistedConfig.secrets() + ); + + MatcherAssert.assertThat(model, instanceOf(CohereEmbeddingsModel.class)); + + var embeddingsModel = (CohereEmbeddingsModel) model; + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getUri().toString(), is("url")); + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getModel(), is("model")); + MatcherAssert.assertThat(embeddingsModel.getTaskSettings(), is(new CohereEmbeddingsTaskSettings(InputType.SEARCH, null))); + MatcherAssert.assertThat(embeddingsModel.getSecretSettings().apiKey().toString(), is("secret")); + } + } + + public void testParsePersistedConfig_CreatesACohereEmbeddingsModel() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var persistedConfig = getPersistedConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", "model", null), + getTaskSettingsMap(null, CohereTruncation.NONE) + ); + + var model = service.parsePersistedConfig("id", TaskType.TEXT_EMBEDDING, persistedConfig.config()); + + MatcherAssert.assertThat(model, instanceOf(CohereEmbeddingsModel.class)); + + var embeddingsModel = (CohereEmbeddingsModel) model; + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getUri().toString(), is("url")); + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getModel(), is("model")); + MatcherAssert.assertThat(embeddingsModel.getTaskSettings(), is(new CohereEmbeddingsTaskSettings(null, CohereTruncation.NONE))); + assertNull(embeddingsModel.getSecretSettings()); + } + } + + public void testParsePersistedConfig_ThrowsErrorTryingToParseInvalidModel() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var persistedConfig = getPersistedConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", null, null), + getTaskSettingsMapEmpty() + ); + + var thrownException = expectThrows( + ElasticsearchStatusException.class, + () -> service.parsePersistedConfig("id", TaskType.SPARSE_EMBEDDING, persistedConfig.config()) + ); + + MatcherAssert.assertThat( + thrownException.getMessage(), + is("Failed to parse stored model [id] for [cohere] service, please delete and add the service again") + ); + } + } + + public void testParsePersistedConfig_CreatesACohereEmbeddingsModelWithoutUrl() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var persistedConfig = getPersistedConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap(null, "model", CohereEmbeddingType.FLOAT), + getTaskSettingsMap(null, null) + ); + + var model = service.parsePersistedConfig("id", TaskType.TEXT_EMBEDDING, persistedConfig.config()); + + MatcherAssert.assertThat(model, instanceOf(CohereEmbeddingsModel.class)); + + var embeddingsModel = (CohereEmbeddingsModel) model; + assertNull(embeddingsModel.getServiceSettings().getCommonSettings().getUri()); + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getModel(), is("model")); + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getEmbeddingType(), is(CohereEmbeddingType.FLOAT)); + MatcherAssert.assertThat(embeddingsModel.getTaskSettings(), is(new CohereEmbeddingsTaskSettings(null, null))); + assertNull(embeddingsModel.getSecretSettings()); + } + } + + public void testParsePersistedConfig_DoesNotThrowWhenAnExtraKeyExistsInConfig() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var persistedConfig = getPersistedConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", null, null), + getTaskSettingsMapEmpty() + ); + persistedConfig.config().put("extra_key", "value"); + + var model = service.parsePersistedConfig("id", TaskType.TEXT_EMBEDDING, persistedConfig.config()); + + MatcherAssert.assertThat(model, instanceOf(CohereEmbeddingsModel.class)); + + var embeddingsModel = (CohereEmbeddingsModel) model; + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getUri().toString(), is("url")); + MatcherAssert.assertThat(embeddingsModel.getTaskSettings(), is(CohereEmbeddingsTaskSettings.EMPTY_SETTINGS)); + assertNull(embeddingsModel.getSecretSettings()); + } + } + + public void testParsePersistedConfig_NotThrowWhenAnExtraKeyExistsInServiceSettings() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var serviceSettingsMap = CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", null, null); + serviceSettingsMap.put("extra_key", "value"); + + var persistedConfig = getPersistedConfigMap(serviceSettingsMap, getTaskSettingsMap(InputType.SEARCH, null)); + + var model = service.parsePersistedConfig("id", TaskType.TEXT_EMBEDDING, persistedConfig.config()); + + MatcherAssert.assertThat(model, instanceOf(CohereEmbeddingsModel.class)); + + var embeddingsModel = (CohereEmbeddingsModel) model; + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getUri().toString(), is("url")); + MatcherAssert.assertThat(embeddingsModel.getTaskSettings(), is(new CohereEmbeddingsTaskSettings(InputType.SEARCH, null))); + assertNull(embeddingsModel.getSecretSettings()); + } + } + + public void testParsePersistedConfig_NotThrowWhenAnExtraKeyExistsInTaskSettings() throws IOException { + try ( + var service = new CohereService( + new SetOnce<>(mock(HttpRequestSenderFactory.class)), + new SetOnce<>(createWithEmptySettings(threadPool)) + ) + ) { + var taskSettingsMap = getTaskSettingsMap(InputType.INGEST, null); + taskSettingsMap.put("extra_key", "value"); + + var persistedConfig = getPersistedConfigMap( + CohereEmbeddingsServiceSettingsTests.getServiceSettingsMap("url", "model", null), + taskSettingsMap + ); + + var model = service.parsePersistedConfig("id", TaskType.TEXT_EMBEDDING, persistedConfig.config()); + + MatcherAssert.assertThat(model, instanceOf(CohereEmbeddingsModel.class)); + + var embeddingsModel = (CohereEmbeddingsModel) model; + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getUri().toString(), is("url")); + MatcherAssert.assertThat(embeddingsModel.getServiceSettings().getCommonSettings().getModel(), is("model")); + MatcherAssert.assertThat(embeddingsModel.getTaskSettings(), is(new CohereEmbeddingsTaskSettings(InputType.INGEST, null))); + assertNull(embeddingsModel.getSecretSettings()); + } + } + + public void testInfer_ThrowsErrorWhenModelIsNotCohereModel() throws IOException { + var sender = mock(Sender.class); + + var factory = mock(HttpRequestSenderFactory.class); + when(factory.createSender(anyString())).thenReturn(sender); + + var mockModel = getInvalidModel("model_id", "service_name"); + + try (var service = new CohereService(new SetOnce<>(factory), new SetOnce<>(createWithEmptySettings(threadPool)))) { + PlainActionFuture listener = new PlainActionFuture<>(); + service.infer(mockModel, List.of(""), new HashMap<>(), listener); + + var thrownException = expectThrows(ElasticsearchStatusException.class, () -> listener.actionGet(TIMEOUT)); + MatcherAssert.assertThat( + thrownException.getMessage(), + is("The internal model was invalid, please delete the service [service_name] with id [model_id] and add it again.") + ); + + verify(factory, times(1)).createSender(anyString()); + verify(sender, times(1)).start(); + } + + verify(sender, times(1)).close(); + verifyNoMoreInteractions(factory); + verifyNoMoreInteractions(sender); + } + + public void testInfer_SendsRequest() throws IOException { + var senderFactory = new HttpRequestSenderFactory(threadPool, clientManager, mockClusterServiceEmpty(), Settings.EMPTY); + + try (var service = new CohereService(new SetOnce<>(senderFactory), new SetOnce<>(createWithEmptySettings(threadPool)))) { + + String responseJson = """ + { + "id": "de37399c-5df6-47cb-bc57-e3c5680c977b", + "texts": [ + "hello" + ], + "embeddings": { + "float": [ + [ + 0.123, + -0.123 + ] + ] + }, + "meta": { + "api_version": { + "version": "1" + }, + "billed_units": { + "input_tokens": 1 + } + }, + "response_type": "embeddings_by_type" + } + """; + webServer.enqueue(new MockResponse().setResponseCode(200).setBody(responseJson)); + + var model = CohereEmbeddingsModelTests.createModel( + getUrl(webServer), + "secret", + new CohereEmbeddingsTaskSettings(InputType.INGEST, null), + 1024, + 1024, + "model", + null + ); + PlainActionFuture listener = new PlainActionFuture<>(); + service.infer(model, List.of("abc"), new HashMap<>(), listener); + + var result = listener.actionGet(TIMEOUT); + + MatcherAssert.assertThat(result.asMap(), Matchers.is(buildExpectation(List.of(List.of(0.123F, -0.123F))))); + MatcherAssert.assertThat(webServer.requests(), hasSize(1)); + assertNull(webServer.requests().get(0).getUri().getQuery()); + MatcherAssert.assertThat( + webServer.requests().get(0).getHeader(HttpHeaders.CONTENT_TYPE), + equalTo(XContentType.JSON.mediaType()) + ); + MatcherAssert.assertThat(webServer.requests().get(0).getHeader(HttpHeaders.AUTHORIZATION), equalTo("Bearer secret")); + + var requestMap = entityAsMap(webServer.requests().get(0).getBody()); + MatcherAssert.assertThat(requestMap, is(Map.of("texts", List.of("abc"), "model", "model", "input_type", "search_document"))); + } + } + + public void testCheckModelConfig_UpdatesDimensions() throws IOException { + var senderFactory = new HttpRequestSenderFactory(threadPool, clientManager, mockClusterServiceEmpty(), Settings.EMPTY); + + try (var service = new CohereService(new SetOnce<>(senderFactory), new SetOnce<>(createWithEmptySettings(threadPool)))) { + + String responseJson = """ + { + "id": "de37399c-5df6-47cb-bc57-e3c5680c977b", + "texts": [ + "hello" + ], + "embeddings": { + "float": [ + [ + 0.123, + -0.123 + ] + ] + }, + "meta": { + "api_version": { + "version": "1" + }, + "billed_units": { + "input_tokens": 1 + } + }, + "response_type": "embeddings_by_type" + } + """; + webServer.enqueue(new MockResponse().setResponseCode(200).setBody(responseJson)); + + var model = CohereEmbeddingsModelTests.createModel( + getUrl(webServer), + "secret", + CohereEmbeddingsTaskSettings.EMPTY_SETTINGS, + 10, + 1, + null, + null + ); + PlainActionFuture listener = new PlainActionFuture<>(); + service.checkModelConfig(model, listener); + var result = listener.actionGet(TIMEOUT); + + MatcherAssert.assertThat( + result, + // the dimension is set to 2 because there are 2 embeddings returned from the mock server + is( + CohereEmbeddingsModelTests.createModel( + getUrl(webServer), + "secret", + CohereEmbeddingsTaskSettings.EMPTY_SETTINGS, + 10, + 2, + null, + null + ) + ) + ); + } + } + + public void testInfer_UnauthorisedResponse() throws IOException { + var senderFactory = new HttpRequestSenderFactory(threadPool, clientManager, mockClusterServiceEmpty(), Settings.EMPTY); + + try (var service = new CohereService(new SetOnce<>(senderFactory), new SetOnce<>(createWithEmptySettings(threadPool)))) { + + String responseJson = """ + { + "message": "invalid api token" + } + """; + webServer.enqueue(new MockResponse().setResponseCode(401).setBody(responseJson)); + + var model = CohereEmbeddingsModelTests.createModel( + getUrl(webServer), + "secret", + CohereEmbeddingsTaskSettings.EMPTY_SETTINGS, + 1024, + 1024, + null, + null + ); + PlainActionFuture listener = new PlainActionFuture<>(); + service.infer(model, List.of("abc"), new HashMap<>(), listener); + + var error = expectThrows(ElasticsearchException.class, () -> listener.actionGet(TIMEOUT)); + MatcherAssert.assertThat(error.getMessage(), containsString("Received an authentication error status code for request")); + MatcherAssert.assertThat(error.getMessage(), containsString("Error message: [invalid api token]")); + MatcherAssert.assertThat(webServer.requests(), hasSize(1)); + } + } + + private Map getRequestConfigMap( + Map serviceSettings, + Map taskSettings, + Map secretSettings + ) { + var builtServiceSettings = new HashMap<>(); + builtServiceSettings.putAll(serviceSettings); + builtServiceSettings.putAll(secretSettings); + + return new HashMap<>( + Map.of(ModelConfigurations.SERVICE_SETTINGS, builtServiceSettings, ModelConfigurations.TASK_SETTINGS, taskSettings) + ); + } + + private PeristedConfig getPersistedConfigMap( + Map serviceSettings, + Map taskSettings, + Map secretSettings + ) { + + return new PeristedConfig( + new HashMap<>(Map.of(ModelConfigurations.SERVICE_SETTINGS, serviceSettings, ModelConfigurations.TASK_SETTINGS, taskSettings)), + new HashMap<>(Map.of(ModelSecrets.SECRET_SETTINGS, secretSettings)) + ); + } + + private PeristedConfig getPersistedConfigMap(Map serviceSettings, Map taskSettings) { + + return new PeristedConfig( + new HashMap<>(Map.of(ModelConfigurations.SERVICE_SETTINGS, serviceSettings, ModelConfigurations.TASK_SETTINGS, taskSettings)), + null + ); + } + + private record PeristedConfig(Map config, Map secrets) {} +} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsModelTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsModelTests.java new file mode 100644 index 0000000000000..1961d6b168d54 --- /dev/null +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsModelTests.java @@ -0,0 +1,108 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.services.cohere.embeddings; + +import org.elasticsearch.common.settings.SecureString; +import org.elasticsearch.core.Nullable; +import org.elasticsearch.inference.InputType; +import org.elasticsearch.inference.TaskType; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.inference.common.SimilarityMeasure; +import org.elasticsearch.xpack.inference.services.cohere.CohereServiceSettings; +import org.elasticsearch.xpack.inference.services.settings.DefaultSecretSettings; +import org.hamcrest.MatcherAssert; + +import java.util.Map; + +import static org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingsTaskSettingsTests.getTaskSettingsMap; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.sameInstance; + +public class CohereEmbeddingsModelTests extends ESTestCase { + + public void testOverrideWith_OverridesInputType_WithSearch() { + var model = createModel( + "url", + "api_key", + new CohereEmbeddingsTaskSettings(InputType.INGEST, null), + null, + null, + "model", + CohereEmbeddingType.FLOAT + ); + + var overriddenModel = model.overrideWith(getTaskSettingsMap(InputType.SEARCH, null)); + var expectedModel = createModel( + "url", + "api_key", + new CohereEmbeddingsTaskSettings(InputType.SEARCH, null), + null, + null, + "model", + CohereEmbeddingType.FLOAT + ); + MatcherAssert.assertThat(overriddenModel, is(expectedModel)); + } + + public void testOverrideWith_DoesNotOverride_WhenSettingsAreEmpty() { + var model = createModel("url", "api_key", null, null, null); + + var overriddenModel = model.overrideWith(Map.of()); + MatcherAssert.assertThat(overriddenModel, sameInstance(model)); + } + + public void testOverrideWith_DoesNotOverride_WhenSettingsAreNull() { + var model = createModel("url", "api_key", null, null, null); + + var overriddenModel = model.overrideWith(null); + MatcherAssert.assertThat(overriddenModel, sameInstance(model)); + } + + public static CohereEmbeddingsModel createModel( + String url, + String apiKey, + @Nullable Integer tokenLimit, + @Nullable String model, + @Nullable CohereEmbeddingType embeddingType + ) { + return createModel(url, apiKey, CohereEmbeddingsTaskSettings.EMPTY_SETTINGS, tokenLimit, null, model, embeddingType); + } + + public static CohereEmbeddingsModel createModel( + String url, + String apiKey, + @Nullable Integer tokenLimit, + @Nullable Integer dimensions, + @Nullable String model, + @Nullable CohereEmbeddingType embeddingType + ) { + return createModel(url, apiKey, CohereEmbeddingsTaskSettings.EMPTY_SETTINGS, tokenLimit, dimensions, model, embeddingType); + } + + public static CohereEmbeddingsModel createModel( + String url, + String apiKey, + CohereEmbeddingsTaskSettings taskSettings, + @Nullable Integer tokenLimit, + @Nullable Integer dimensions, + @Nullable String model, + @Nullable CohereEmbeddingType embeddingType + ) { + return new CohereEmbeddingsModel( + "id", + TaskType.TEXT_EMBEDDING, + "service", + new CohereEmbeddingsServiceSettings( + new CohereServiceSettings(url, SimilarityMeasure.DOT_PRODUCT, dimensions, tokenLimit, model), + embeddingType + ), + taskSettings, + new DefaultSecretSettings(new SecureString(apiKey.toCharArray())) + ); + } +} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsServiceSettingsTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsServiceSettingsTests.java new file mode 100644 index 0000000000000..e0b29ce9c34da --- /dev/null +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsServiceSettingsTests.java @@ -0,0 +1,167 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.services.cohere.embeddings; + +import org.elasticsearch.ElasticsearchStatusException; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.ValidationException; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.core.Nullable; +import org.elasticsearch.test.AbstractWireSerializingTestCase; +import org.elasticsearch.xpack.core.ml.inference.MlInferenceNamedXContentProvider; +import org.elasticsearch.xpack.inference.InferenceNamedWriteablesProvider; +import org.elasticsearch.xpack.inference.common.SimilarityMeasure; +import org.elasticsearch.xpack.inference.services.ServiceFields; +import org.elasticsearch.xpack.inference.services.ServiceUtils; +import org.elasticsearch.xpack.inference.services.cohere.CohereServiceSettings; +import org.elasticsearch.xpack.inference.services.cohere.CohereServiceSettingsTests; +import org.hamcrest.MatcherAssert; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; + +public class CohereEmbeddingsServiceSettingsTests extends AbstractWireSerializingTestCase { + public static CohereEmbeddingsServiceSettings createRandom() { + var commonSettings = CohereServiceSettingsTests.createRandom(); + var embeddingType = randomBoolean() ? randomFrom(CohereEmbeddingType.values()) : null; + + return new CohereEmbeddingsServiceSettings(commonSettings, embeddingType); + } + + public void testFromMap() { + var url = "https://www.abc.com"; + var similarity = SimilarityMeasure.DOT_PRODUCT.toString(); + var dims = 1536; + var maxInputTokens = 512; + var model = "model"; + var serviceSettings = CohereEmbeddingsServiceSettings.fromMap( + new HashMap<>( + Map.of( + ServiceFields.URL, + url, + ServiceFields.SIMILARITY, + similarity, + ServiceFields.DIMENSIONS, + dims, + ServiceFields.MAX_INPUT_TOKENS, + maxInputTokens, + CohereServiceSettings.MODEL, + model, + CohereEmbeddingsServiceSettings.EMBEDDING_TYPE, + CohereEmbeddingType.INT8.toString() + ) + ) + ); + + MatcherAssert.assertThat( + serviceSettings, + is( + new CohereEmbeddingsServiceSettings( + new CohereServiceSettings(ServiceUtils.createUri(url), SimilarityMeasure.DOT_PRODUCT, dims, maxInputTokens, model), + CohereEmbeddingType.INT8 + ) + ) + ); + } + + public void testFromMap_MissingEmbeddingType_DoesNotThrowException() { + var serviceSettings = CohereEmbeddingsServiceSettings.fromMap(new HashMap<>(Map.of())); + assertNull(serviceSettings.getEmbeddingType()); + } + + public void testFromMap_EmptyEmbeddingType_ThrowsError() { + var thrownException = expectThrows( + ValidationException.class, + () -> CohereEmbeddingsServiceSettings.fromMap(new HashMap<>(Map.of(CohereEmbeddingsServiceSettings.EMBEDDING_TYPE, ""))) + ); + + MatcherAssert.assertThat( + thrownException.getMessage(), + containsString( + Strings.format( + "Validation Failed: 1: [service_settings] Invalid value empty string. [%s] must be a non-empty string;", + CohereEmbeddingsServiceSettings.EMBEDDING_TYPE + ) + ) + ); + } + + public void testFromMap_InvalidEmbeddingType_ThrowsError() { + var thrownException = expectThrows( + ValidationException.class, + () -> CohereEmbeddingsServiceSettings.fromMap(new HashMap<>(Map.of(CohereEmbeddingsServiceSettings.EMBEDDING_TYPE, "abc"))) + ); + + MatcherAssert.assertThat( + thrownException.getMessage(), + is( + Strings.format( + "Validation Failed: 1: [service_settings] Invalid value [abc] received. [embedding_type] must be one of [float, int8];" + ) + ) + ); + } + + public void testFromMap_ReturnsFailure_WhenEmbeddingTypesAreNotValid() { + var exception = expectThrows( + ElasticsearchStatusException.class, + () -> CohereEmbeddingsServiceSettings.fromMap( + new HashMap<>(Map.of(CohereEmbeddingsServiceSettings.EMBEDDING_TYPE, List.of("abc"))) + ) + ); + + MatcherAssert.assertThat( + exception.getMessage(), + is("field [embedding_type] is not of the expected type. The value [[abc]] cannot be converted to a [String]") + ); + } + + @Override + protected Writeable.Reader instanceReader() { + return CohereEmbeddingsServiceSettings::new; + } + + @Override + protected CohereEmbeddingsServiceSettings createTestInstance() { + return createRandom(); + } + + @Override + protected CohereEmbeddingsServiceSettings mutateInstance(CohereEmbeddingsServiceSettings instance) throws IOException { + return null; + } + + @Override + protected NamedWriteableRegistry getNamedWriteableRegistry() { + List entries = new ArrayList<>(); + entries.addAll(new MlInferenceNamedXContentProvider().getNamedWriteables()); + entries.addAll(InferenceNamedWriteablesProvider.getNamedWriteables()); + return new NamedWriteableRegistry(entries); + } + + public static Map getServiceSettingsMap( + @Nullable String url, + @Nullable String model, + @Nullable CohereEmbeddingType embeddingType + ) { + var map = new HashMap<>(CohereServiceSettingsTests.getServiceSettingsMap(url, model)); + + if (embeddingType != null) { + map.put(CohereEmbeddingsServiceSettings.EMBEDDING_TYPE, embeddingType.toString()); + } + + return map; + } +} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsTaskSettingsTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsTaskSettingsTests.java new file mode 100644 index 0000000000000..164d3998f138f --- /dev/null +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/cohere/embeddings/CohereEmbeddingsTaskSettingsTests.java @@ -0,0 +1,124 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.inference.services.cohere.embeddings; + +import org.elasticsearch.common.ValidationException; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.core.Nullable; +import org.elasticsearch.inference.InputType; +import org.elasticsearch.test.AbstractWireSerializingTestCase; +import org.elasticsearch.xpack.inference.services.cohere.CohereServiceFields; +import org.elasticsearch.xpack.inference.services.cohere.CohereServiceSettings; +import org.elasticsearch.xpack.inference.services.cohere.CohereTruncation; +import org.hamcrest.MatcherAssert; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static org.hamcrest.Matchers.is; + +public class CohereEmbeddingsTaskSettingsTests extends AbstractWireSerializingTestCase { + + public static CohereEmbeddingsTaskSettings createRandom() { + var inputType = randomBoolean() ? randomFrom(InputType.values()) : null; + var truncation = randomBoolean() ? randomFrom(CohereTruncation.values()) : null; + + return new CohereEmbeddingsTaskSettings(inputType, truncation); + } + + public void testFromMap_CreatesEmptySettings_WhenAllFieldsAreNull() { + MatcherAssert.assertThat( + CohereEmbeddingsTaskSettings.fromMap(new HashMap<>(Map.of())), + is(new CohereEmbeddingsTaskSettings(null, null)) + ); + } + + public void testFromMap_CreatesSettings_WhenAllFieldsOfSettingsArePresent() { + MatcherAssert.assertThat( + CohereEmbeddingsTaskSettings.fromMap( + new HashMap<>( + Map.of( + CohereEmbeddingsTaskSettings.INPUT_TYPE, + InputType.INGEST.toString(), + CohereServiceFields.TRUNCATE, + CohereTruncation.END.toString() + ) + ) + ), + is(new CohereEmbeddingsTaskSettings(InputType.INGEST, CohereTruncation.END)) + ); + } + + public void testFromMap_ReturnsFailure_WhenInputTypeIsInvalid() { + var exception = expectThrows( + ValidationException.class, + () -> CohereEmbeddingsTaskSettings.fromMap(new HashMap<>(Map.of(CohereEmbeddingsTaskSettings.INPUT_TYPE, "abc"))) + ); + + MatcherAssert.assertThat( + exception.getMessage(), + is("Validation Failed: 1: [task_settings] Invalid value [abc] received. [input_type] must be one of [ingest, search];") + ); + } + + public void testOverrideWith_KeepsOriginalValuesWhenOverridesAreNull() { + var taskSettings = CohereEmbeddingsTaskSettings.fromMap( + new HashMap<>(Map.of(CohereServiceSettings.MODEL, "model", CohereServiceFields.TRUNCATE, CohereTruncation.END.toString())) + ); + + var overriddenTaskSettings = taskSettings.overrideWith(CohereEmbeddingsTaskSettings.EMPTY_SETTINGS); + MatcherAssert.assertThat(overriddenTaskSettings, is(taskSettings)); + } + + public void testOverrideWith_UsesOverriddenSettings() { + var taskSettings = CohereEmbeddingsTaskSettings.fromMap( + new HashMap<>(Map.of(CohereServiceFields.TRUNCATE, CohereTruncation.END.toString())) + ); + + var requestTaskSettings = CohereEmbeddingsTaskSettings.fromMap( + new HashMap<>(Map.of(CohereServiceFields.TRUNCATE, CohereTruncation.START.toString())) + ); + + var overriddenTaskSettings = taskSettings.overrideWith(requestTaskSettings); + MatcherAssert.assertThat(overriddenTaskSettings, is(new CohereEmbeddingsTaskSettings(null, CohereTruncation.START))); + } + + @Override + protected Writeable.Reader instanceReader() { + return CohereEmbeddingsTaskSettings::new; + } + + @Override + protected CohereEmbeddingsTaskSettings createTestInstance() { + return createRandom(); + } + + @Override + protected CohereEmbeddingsTaskSettings mutateInstance(CohereEmbeddingsTaskSettings instance) throws IOException { + return null; + } + + public static Map getTaskSettingsMapEmpty() { + return new HashMap<>(); + } + + public static Map getTaskSettingsMap(@Nullable InputType inputType, @Nullable CohereTruncation truncation) { + var map = new HashMap(); + + if (inputType != null) { + map.put(CohereEmbeddingsTaskSettings.INPUT_TYPE, inputType.toString()); + } + + if (truncation != null) { + map.put(CohereServiceFields.TRUNCATE, truncation.toString()); + } + + return map; + } +} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/openai/embeddings/OpenAiEmbeddingsTaskSettingsTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/openai/embeddings/OpenAiEmbeddingsTaskSettingsTests.java index d33ec12016cad..f297eb622c421 100644 --- a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/openai/embeddings/OpenAiEmbeddingsTaskSettingsTests.java +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/openai/embeddings/OpenAiEmbeddingsTaskSettingsTests.java @@ -12,6 +12,7 @@ import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.core.Nullable; import org.elasticsearch.test.AbstractWireSerializingTestCase; +import org.hamcrest.MatcherAssert; import java.io.IOException; import java.util.HashMap; @@ -39,7 +40,7 @@ public void testFromMap_MissingModel_ThrowException() { () -> OpenAiEmbeddingsTaskSettings.fromMap(new HashMap<>(Map.of(OpenAiEmbeddingsTaskSettings.USER, "user"))) ); - assertThat( + MatcherAssert.assertThat( thrownException.getMessage(), is( Strings.format( @@ -55,14 +56,14 @@ public void testFromMap_CreatesWithModelAndUser() { new HashMap<>(Map.of(OpenAiEmbeddingsTaskSettings.MODEL, "model", OpenAiEmbeddingsTaskSettings.USER, "user")) ); - assertThat(taskSettings.model(), is("model")); - assertThat(taskSettings.user(), is("user")); + MatcherAssert.assertThat(taskSettings.model(), is("model")); + MatcherAssert.assertThat(taskSettings.user(), is("user")); } public void testFromMap_MissingUser_DoesNotThrowException() { var taskSettings = OpenAiEmbeddingsTaskSettings.fromMap(new HashMap<>(Map.of(OpenAiEmbeddingsTaskSettings.MODEL, "model"))); - assertThat(taskSettings.model(), is("model")); + MatcherAssert.assertThat(taskSettings.model(), is("model")); assertNull(taskSettings.user()); } @@ -72,7 +73,7 @@ public void testOverrideWith_KeepsOriginalValuesWithOverridesAreNull() { ); var overriddenTaskSettings = taskSettings.overrideWith(OpenAiEmbeddingsRequestTaskSettings.EMPTY_SETTINGS); - assertThat(overriddenTaskSettings, is(taskSettings)); + MatcherAssert.assertThat(overriddenTaskSettings, is(taskSettings)); } public void testOverrideWith_UsesOverriddenSettings() { @@ -85,7 +86,7 @@ public void testOverrideWith_UsesOverriddenSettings() { ); var overriddenTaskSettings = taskSettings.overrideWith(requestTaskSettings); - assertThat(overriddenTaskSettings, is(new OpenAiEmbeddingsTaskSettings("model2", "user2"))); + MatcherAssert.assertThat(overriddenTaskSettings, is(new OpenAiEmbeddingsTaskSettings("model2", "user2"))); } public void testOverrideWith_UsesOnlyNonNullModelSetting() { @@ -98,7 +99,7 @@ public void testOverrideWith_UsesOnlyNonNullModelSetting() { ); var overriddenTaskSettings = taskSettings.overrideWith(requestTaskSettings); - assertThat(overriddenTaskSettings, is(new OpenAiEmbeddingsTaskSettings("model2", "user"))); + MatcherAssert.assertThat(overriddenTaskSettings, is(new OpenAiEmbeddingsTaskSettings("model2", "user"))); } @Override From 9b4647cfc6d39987cc3fd4f44514bca403d4808f Mon Sep 17 00:00:00 2001 From: Mark Vieira Date: Wed, 24 Jan 2024 13:35:31 -0800 Subject: [PATCH 16/37] AwaitsFix #104728 --- .../http/netty4/Netty4HttpPipeliningHandlerTests.java | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/transport-netty4/src/test/java/org/elasticsearch/http/netty4/Netty4HttpPipeliningHandlerTests.java b/modules/transport-netty4/src/test/java/org/elasticsearch/http/netty4/Netty4HttpPipeliningHandlerTests.java index db59da8076b0a..cc73d0fa7349e 100644 --- a/modules/transport-netty4/src/test/java/org/elasticsearch/http/netty4/Netty4HttpPipeliningHandlerTests.java +++ b/modules/transport-netty4/src/test/java/org/elasticsearch/http/netty4/Netty4HttpPipeliningHandlerTests.java @@ -232,6 +232,7 @@ public void testSmallFullResponsesAreSentDirectly() { assertSame(response, messagesSeen.get(0)); } + @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/104728") public void testLargeFullResponsesAreSplit() { final List messagesSeen = new ArrayList<>(); final var embeddedChannel = new EmbeddedChannel(capturingHandler(messagesSeen), getTestHttpHandler()); From d1e5f725673f6e11a19c5b48bf3ad2ceb5f874af Mon Sep 17 00:00:00 2001 From: Luigi Dell'Aquila Date: Thu, 25 Jan 2024 09:05:57 +0100 Subject: [PATCH 17/37] ESQL: Fix replacement of nested expressions in aggs with multiple parameters (#104718) --- docs/changelog/104718.yaml | 6 ++++++ .../src/main/resources/stats.csv-spec | 15 +++++++++++++++ .../main/resources/stats_count_distinct.csv-spec | 13 +++++++++++++ .../esql/optimizer/LogicalPlanOptimizer.java | 4 +++- 4 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 docs/changelog/104718.yaml diff --git a/docs/changelog/104718.yaml b/docs/changelog/104718.yaml new file mode 100644 index 0000000000000..ffe889bb28a3e --- /dev/null +++ b/docs/changelog/104718.yaml @@ -0,0 +1,6 @@ +pr: 104718 +summary: "ESQL: Fix replacement of nested expressions in aggs with multiple parameters" +area: ES|QL +type: bug +issues: + - 104706 diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/stats.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/stats.csv-spec index b3743d53e1975..0dd2f4f937421 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/stats.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/stats.csv-spec @@ -929,6 +929,21 @@ sum(sal):l | sum(salary + 10000):l | left(first_name, 1):s | concat(gender, t 43370 | 43370 | B | F2 ; +nestedExpressionMultipleParams#[skip:-8.12.99,reason:supported in 8.13+] +FROM employees +| STATS p = percentile(emp_no + 10, 50), m = median(emp_no + 10) BY languages +| SORT languages +; + +p:double | m:double | languages:integer +10053.0 | 10053.0 | 1 +10069.0 | 10069.0 | 2 +10068.0 | 10068.0 | 3 +10060.5 | 10060.5 | 4 +10076.0 | 10076.0 | 5 +10034.5 | 10034.5 | null +; + groupByNull#[skip:-8.12.99,reason:bug fixed in 8.13+] ROW a = 1, c = null | STATS COUNT(a) BY c; diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/stats_count_distinct.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/stats_count_distinct.csv-spec index e0e8ca351cfe5..8f926fd8f6ed7 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/stats_count_distinct.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/stats_count_distinct.csv-spec @@ -152,3 +152,16 @@ m:long | languages:i 20 | 5 10 | null ; + + +countDistinctWithGroupPrecisionAndNestedExpression#[skip:-8.12.99,reason:supported in 8.13+] +from employees | stats m = count_distinct(height + 5, 9876) by languages | sort languages; + +m:long | languages:i +13 | 1 +16 | 2 +14 | 3 +15 | 4 +20 | 5 +10 | null +; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizer.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizer.java index b0b5ec37dbcc7..81f712ae0408a 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizer.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizer.java @@ -1141,7 +1141,9 @@ protected LogicalPlan rule(Aggregate aggregate) { return newAlias.toAttribute(); }); // replace field with attribute - result = af.replaceChildren(Collections.singletonList(attr)); + List newChildren = new ArrayList<>(af.children()); + newChildren.set(0, attr); + result = af.replaceChildren(newChildren); } return result; }); From e0ddb828c87c5b8c334c308034061fec4a7e40af Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Thu, 25 Jan 2024 19:14:52 +1100 Subject: [PATCH 18/37] [CI] Ensure large response can fit into 3 messages (#104729) Lower the upper bound of large response size from 2 times of suggestedMaxAllocationSize to 1.5 so that it be sent over with 3 messages. This is because the split threshold is 0.99 of suggestedMaxAllocationSize. Resolves: #104728 --- .../http/netty4/Netty4HttpPipeliningHandlerTests.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/transport-netty4/src/test/java/org/elasticsearch/http/netty4/Netty4HttpPipeliningHandlerTests.java b/modules/transport-netty4/src/test/java/org/elasticsearch/http/netty4/Netty4HttpPipeliningHandlerTests.java index cc73d0fa7349e..dd71fb62c1106 100644 --- a/modules/transport-netty4/src/test/java/org/elasticsearch/http/netty4/Netty4HttpPipeliningHandlerTests.java +++ b/modules/transport-netty4/src/test/java/org/elasticsearch/http/netty4/Netty4HttpPipeliningHandlerTests.java @@ -232,14 +232,13 @@ public void testSmallFullResponsesAreSentDirectly() { assertSame(response, messagesSeen.get(0)); } - @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/104728") public void testLargeFullResponsesAreSplit() { final List messagesSeen = new ArrayList<>(); final var embeddedChannel = new EmbeddedChannel(capturingHandler(messagesSeen), getTestHttpHandler()); embeddedChannel.writeInbound(createHttpRequest("/test")); final Netty4HttpRequest request = embeddedChannel.readInbound(); final var minSize = (int) NettyAllocator.suggestedMaxAllocationSize(); - final var content = new ZeroBytesReference(between(minSize, minSize * 2)); + final var content = new ZeroBytesReference(between(minSize, (int) (minSize * 1.5))); final var response = request.createResponse(RestStatus.OK, content); assertThat(response, instanceOf(FullHttpResponse.class)); final var promise = embeddedChannel.newPromise(); From a7f2e2daaf03ca8253bdd6bda9163ec03fb2b2d2 Mon Sep 17 00:00:00 2001 From: Ievgen Degtiarenko Date: Thu, 25 Jan 2024 09:20:59 +0100 Subject: [PATCH 19/37] Fix testRestoreSnapshotAllocationDoesNotExceedWatermarkWithMultipleShards (#104709) Remove +1L that allows the third-smallest shard to be also allocated on the node in case it is only 1b bigger than second-smallest --- .../routing/allocation/decider/DiskThresholdDeciderIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDeciderIT.java b/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDeciderIT.java index df23f8b9fd983..a998fafd517ed 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDeciderIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDeciderIT.java @@ -196,7 +196,7 @@ public void testRestoreSnapshotAllocationDoesNotExceedWatermarkWithMultipleShard // reduce disk size of node 0 so that only 1 of 2 smallest shards can be allocated var usableSpace = shardSizes.sizes().get(1).size(); - getTestFileStore(dataNodeName).setTotalSpace(usableSpace + WATERMARK_BYTES + 1L); + getTestFileStore(dataNodeName).setTotalSpace(usableSpace + WATERMARK_BYTES); refreshDiskUsage(); final RestoreSnapshotResponse restoreSnapshotResponse = clusterAdmin().prepareRestoreSnapshot("repo", "snap") From 1116889819ab7a8e416699a57e78bf65632b479e Mon Sep 17 00:00:00 2001 From: David Turner Date: Thu, 25 Jan 2024 08:28:32 +0000 Subject: [PATCH 20/37] Remove unused arg from `ActionType` ctor (#104650) `ActionType` represents an action which runs on the local node, there's no need for implementations to define a `Reader`. This commit removes the unused constructor argument. --- .../elasticsearch/plugin/noop/NoopPlugin.java | 4 +-- .../DeleteDataStreamLifecycleAction.java | 2 +- .../ExplainDataStreamLifecycleAction.java | 3 +-- .../action/GetDataStreamLifecycleAction.java | 3 +-- .../GetDataStreamLifecycleStatsAction.java | 2 +- .../action/PutDataStreamLifecycleAction.java | 2 +- .../ingest/common/GrokProcessorGetAction.java | 5 +--- .../stats/GeoIpDownloaderStatsAction.java | 2 +- .../script/mustache/MustachePlugin.java | 8 ++---- .../action/PainlessContextAction.java | 2 +- .../action/PainlessExecuteAction.java | 2 +- .../index/rankeval/RankEvalPlugin.java | 2 +- .../elasticsearch/reindex/ReindexPlugin.java | 5 +--- .../rest/root/MainRestPlugin.java | 2 +- .../node/tasks/CancellableTasksIT.java | 2 +- .../admin/cluster/tasks/ListTasksIT.java | 2 +- ...tReplicationActionRetryOnClosedNodeIT.java | 2 +- .../org/elasticsearch/action/ActionType.java | 26 +++---------------- ...ansportClusterAllocationExplainAction.java | 5 +--- .../TransportDeleteDesiredBalanceAction.java | 2 +- .../TransportGetDesiredBalanceAction.java | 5 +--- ...nsportAddVotingConfigExclusionsAction.java | 2 +- ...portClearVotingConfigExclusionsAction.java | 2 +- .../ClusterFormationInfoAction.java | 2 +- .../CoordinationDiagnosticsAction.java | 2 +- .../coordination/MasterHistoryAction.java | 2 +- .../desirednodes/GetDesiredNodesAction.java | 2 +- .../TransportDeleteDesiredNodesAction.java | 2 +- .../UpdateDesiredNodesAction.java | 2 +- .../health/TransportClusterHealthAction.java | 2 +- .../GetFeatureUpgradeStatusAction.java | 2 +- .../migration/PostFeatureUpgradeAction.java | 2 +- .../TransportNodesHotThreadsAction.java | 2 +- .../node/info/TransportNodesInfoAction.java | 2 +- ...nsportNodesReloadSecureSettingsAction.java | 4 +-- .../PrevalidateNodeRemovalAction.java | 2 +- .../TransportPrevalidateShardPathAction.java | 3 +-- .../node/stats/TransportNodesStatsAction.java | 2 +- .../node/tasks/cancel/CancelTasksAction.java | 2 +- .../cluster/node/tasks/get/GetTaskAction.java | 2 +- .../tasks/list/TransportListTasksAction.java | 2 +- .../node/usage/TransportNodesUsageAction.java | 2 +- .../remote/RemoteClusterNodesAction.java | 2 +- .../remote/TransportRemoteInfoAction.java | 2 +- .../cleanup/CleanupRepositoryAction.java | 2 +- .../TransportDeleteRepositoryAction.java | 2 +- .../get/GetRepositoriesAction.java | 2 +- .../put/TransportPutRepositoryAction.java | 2 +- .../verify/VerifyRepositoryAction.java | 2 +- .../cluster/reroute/ClusterRerouteAction.java | 2 +- .../settings/ClusterGetSettingsAction.java | 2 +- .../settings/ClusterUpdateSettingsAction.java | 2 +- .../shards/ClusterSearchShardsAction.java | 2 +- .../clone/TransportCloneSnapshotAction.java | 2 +- .../create/CreateSnapshotAction.java | 2 +- .../delete/TransportDeleteSnapshotAction.java | 2 +- .../features/ResetFeatureStateAction.java | 2 +- .../features/SnapshottableFeaturesAction.java | 2 +- .../snapshots/get/GetSnapshotsAction.java | 2 +- .../get/shard/GetShardSnapshotAction.java | 2 +- .../restore/RestoreSnapshotAction.java | 2 +- .../status/SnapshotsStatusAction.java | 2 +- .../status/TransportNodesSnapshotsStatus.java | 3 +-- .../cluster/state/ClusterStateAction.java | 3 +-- .../cluster/stats/ClusterStatsAction.java | 3 +-- .../storedscripts/GetScriptContextAction.java | 2 +- .../GetScriptLanguageAction.java | 2 +- .../storedscripts/GetStoredScriptAction.java | 2 +- .../TransportDeleteStoredScriptAction.java | 2 +- .../TransportPutStoredScriptAction.java | 2 +- .../TransportPendingClusterTasksAction.java | 5 +--- .../alias/TransportIndicesAliasesAction.java | 2 +- .../indices/alias/get/GetAliasesAction.java | 3 +-- .../admin/indices/analyze/AnalyzeAction.java | 2 +- .../TransportReloadAnalyzersAction.java | 5 +--- .../cache/clear/ClearIndicesCacheAction.java | 2 +- .../close/TransportCloseIndexAction.java | 2 +- ...TransportVerifyShardBeforeCloseAction.java | 2 +- .../indices/create/AutoCreateAction.java | 2 +- .../indices/create/CreateIndexAction.java | 2 +- .../TransportDeleteDanglingIndexAction.java | 2 +- .../TransportFindDanglingIndexAction.java | 2 +- .../TransportImportDanglingIndexAction.java | 2 +- .../TransportListDanglingIndicesAction.java | 2 +- .../delete/TransportDeleteIndexAction.java | 2 +- .../AnalyzeIndexDiskUsageAction.java | 2 +- .../admin/indices/flush/FlushAction.java | 2 +- .../flush/TransportShardFlushAction.java | 2 +- .../indices/forcemerge/ForceMergeAction.java | 2 +- .../admin/indices/get/GetIndexAction.java | 3 +-- .../mapping/get/GetFieldMappingsAction.java | 2 +- .../mapping/get/GetMappingsAction.java | 2 +- .../TransportGetFieldMappingsIndexAction.java | 2 +- .../put/TransportAutoPutMappingAction.java | 2 +- .../put/TransportPutMappingAction.java | 2 +- .../admin/indices/open/OpenIndexAction.java | 2 +- .../indices/readonly/AddIndexBlockAction.java | 2 +- .../TransportVerifyShardIndexBlockAction.java | 2 +- .../indices/recovery/RecoveryAction.java | 2 +- .../admin/indices/refresh/RefreshAction.java | 2 +- .../refresh/TransportShardRefreshAction.java | 2 +- .../indices/resolve/ResolveIndexAction.java | 2 +- .../indices/rollover/RolloverAction.java | 2 +- .../segments/IndicesSegmentsAction.java | 2 +- .../settings/get/GetSettingsAction.java | 2 +- .../put/TransportUpdateSettingsAction.java | 2 +- .../TransportIndicesShardStoresAction.java | 2 +- .../admin/indices/shrink/ResizeAction.java | 2 +- .../admin/indices/shrink/ShrinkAction.java | 2 +- .../indices/stats/FieldUsageStatsAction.java | 2 +- .../indices/stats/IndicesStatsAction.java | 3 +-- ...ransportDeleteComponentTemplateAction.java | 2 +- ...rtDeleteComposableIndexTemplateAction.java | 2 +- .../TransportDeleteIndexTemplateAction.java | 2 +- .../get/GetComponentTemplateAction.java | 2 +- .../get/GetComposableIndexTemplateAction.java | 2 +- .../template/get/GetIndexTemplatesAction.java | 2 +- .../post/SimulateIndexTemplateAction.java | 2 +- .../template/post/SimulateTemplateAction.java | 2 +- .../put/PutComponentTemplateAction.java | 2 +- ...sportPutComposableIndexTemplateAction.java | 2 +- .../put/TransportPutIndexTemplateAction.java | 2 +- .../validate/query/ValidateQueryAction.java | 2 +- .../elasticsearch/action/bulk/BulkAction.java | 2 +- .../action/bulk/SimulateBulkAction.java | 2 +- .../action/bulk/TransportShardBulkAction.java | 2 +- .../datastreams/CreateDataStreamAction.java | 2 +- .../datastreams/DataStreamsStatsAction.java | 2 +- .../datastreams/DeleteDataStreamAction.java | 2 +- .../datastreams/GetDataStreamAction.java | 2 +- .../MigrateToDataStreamAction.java | 2 +- .../datastreams/ModifyDataStreamsAction.java | 2 +- .../datastreams/PromoteDataStreamAction.java | 2 +- .../action/delete/TransportDeleteAction.java | 2 +- .../action/downsample/DownsampleAction.java | 2 +- .../explain/TransportExplainAction.java | 2 +- .../TransportFieldCapabilitiesAction.java | 2 +- .../action/get/TransportGetAction.java | 2 +- .../action/get/TransportMultiGetAction.java | 2 +- .../get/TransportShardMultiGetAction.java | 2 +- .../action/index/TransportIndexAction.java | 5 +--- .../ingest/DeletePipelineTransportAction.java | 2 +- .../action/ingest/GetPipelineAction.java | 2 +- .../ingest/PutPipelineTransportAction.java | 2 +- .../action/ingest/SimulatePipelineAction.java | 2 +- .../search/TransportClearScrollAction.java | 2 +- .../TransportClosePointInTimeAction.java | 5 +--- .../search/TransportMultiSearchAction.java | 2 +- .../TransportOpenPointInTimeAction.java | 5 +--- .../action/search/TransportSearchAction.java | 2 +- .../search/TransportSearchScrollAction.java | 2 +- .../search/TransportSearchShardsAction.java | 2 +- .../action/support/TransportAction.java | 3 +-- .../AbstractSynonymsPagedResultAction.java | 2 +- .../synonyms/DeleteSynonymRuleAction.java | 2 +- .../action/synonyms/DeleteSynonymsAction.java | 2 +- .../action/synonyms/GetSynonymRuleAction.java | 2 +- .../action/synonyms/PutSynonymRuleAction.java | 2 +- .../action/synonyms/PutSynonymsAction.java | 2 +- .../termvectors/MultiTermVectorsAction.java | 2 +- .../action/termvectors/TermVectorsAction.java | 2 +- .../TransportShardMultiTermsVectorAction.java | 2 +- .../action/update/TransportUpdateAction.java | 2 +- .../common/io/stream/Writeable.java | 12 +-------- ...ransportNodesListGatewayStartedShards.java | 3 +-- .../elasticsearch/health/GetHealthAction.java | 3 +-- .../node/FetchHealthInfoCacheAction.java | 2 +- .../node/UpdateHealthInfoCacheAction.java | 2 +- .../health/stats/HealthApiStatsAction.java | 3 +-- .../index/reindex/DeleteByQueryAction.java | 2 +- .../index/reindex/ReindexAction.java | 2 +- .../index/reindex/UpdateByQueryAction.java | 2 +- .../seqno/GlobalCheckpointSyncAction.java | 2 +- .../index/seqno/RetentionLeaseActions.java | 6 ++--- .../StatelessPrimaryRelocationAction.java | 2 +- .../TransportNodesListShardStoreMetadata.java | 2 +- .../CompletionPersistentTaskAction.java | 2 +- .../RemovePersistentTaskAction.java | 2 +- .../persistent/StartPersistentTaskAction.java | 2 +- .../UpdatePersistentTaskStatusAction.java | 2 +- .../action/ActionModuleTests.java | 2 +- .../org/elasticsearch/action/ActionTests.java | 6 ++--- .../cluster/node/tasks/TestTaskPlugin.java | 7 ++--- ...portActionFilterChainRefCountingTests.java | 2 +- .../InternalOrPrivateSettingsPlugin.java | 5 +--- .../persistent/TestPersistentTasksPlugin.java | 5 +--- .../test/seektracker/SeekTrackerPlugin.java | 2 +- ...rectToLocalClusterRemoteClusterClient.java | 3 ++- .../action/DeleteAutoscalingPolicyAction.java | 2 +- .../action/GetAutoscalingCapacityAction.java | 2 +- .../action/GetAutoscalingPolicyAction.java | 2 +- .../action/PutAutoscalingPolicyAction.java | 2 +- .../xpack/ccr/action/ShardChangesAction.java | 2 +- .../bulk/BulkShardOperationsAction.java | 2 +- .../ClearCcrRestoreSessionAction.java | 2 +- .../DeleteInternalCcrRepositoryAction.java | 3 +-- .../GetCcrRestoreFileChunkAction.java | 2 +- .../PutCcrRestoreSessionAction.java | 4 +-- .../PutInternalCcrRepositoryAction.java | 3 +-- .../license/GetBasicStatusAction.java | 2 +- .../license/GetLicenseAction.java | 2 +- .../license/GetTrialStatusAction.java | 2 +- .../license/PostStartBasicAction.java | 2 +- .../license/PostStartTrialAction.java | 2 +- .../license/PutLicenseAction.java | 2 +- .../license/TransportDeleteLicenseAction.java | 2 +- .../TransportGetFeatureUsageAction.java | 5 +--- .../action/MigrateToDataTiersAction.java | 2 +- .../xpack/core/action/XPackInfoAction.java | 3 +-- .../core/action/XPackInfoFeatureAction.java | 2 +- .../xpack/core/action/XPackUsageAction.java | 2 +- .../core/action/XPackUsageFeatureAction.java | 2 +- .../action/AnalyticsStatsAction.java | 2 +- .../TransportDeleteAsyncResultAction.java | 2 +- .../ActivateAutoFollowPatternAction.java | 2 +- .../xpack/core/ccr/action/CcrStatsAction.java | 2 +- .../action/DeleteAutoFollowPatternAction.java | 2 +- .../core/ccr/action/FollowInfoAction.java | 2 +- .../core/ccr/action/FollowStatsAction.java | 2 +- .../core/ccr/action/ForgetFollowerAction.java | 2 +- .../action/GetAutoFollowPatternAction.java | 2 +- .../core/ccr/action/PauseFollowAction.java | 2 +- .../action/PutAutoFollowPatternAction.java | 2 +- .../core/ccr/action/PutFollowAction.java | 2 +- .../core/ccr/action/ResumeFollowAction.java | 2 +- .../xpack/core/ccr/action/UnfollowAction.java | 2 +- .../NodesDataTiersUsageTransportAction.java | 2 +- .../downsample/DownsampleIndexerAction.java | 2 +- .../action/DeleteEnrichPolicyAction.java | 2 +- .../core/enrich/action/EnrichStatsAction.java | 2 +- .../action/ExecuteEnrichPolicyAction.java | 2 +- .../enrich/action/GetEnrichPolicyAction.java | 2 +- .../enrich/action/PutEnrichPolicyAction.java | 2 +- .../core/frozen/action/FreezeIndexAction.java | 2 +- .../core/graph/action/GraphExploreAction.java | 2 +- .../ilm/action/DeleteLifecycleAction.java | 2 +- .../ilm/action/ExplainLifecycleAction.java | 2 +- .../core/ilm/action/GetLifecycleAction.java | 2 +- .../core/ilm/action/GetStatusAction.java | 2 +- .../xpack/core/ilm/action/ILMActions.java | 10 +++---- .../RemoveIndexLifecyclePolicyAction.java | 2 +- .../action/DeleteInferenceModelAction.java | 2 +- .../action/GetInferenceModelAction.java | 2 +- .../inference/action/InferenceAction.java | 2 +- .../action/PutInferenceModelAction.java | 2 +- .../ml/action/AuditMlNotificationAction.java | 2 +- .../CancelJobModelSnapshotUpgradeAction.java | 2 +- .../ml/action/ClearDeploymentCacheAction.java | 2 +- .../xpack/core/ml/action/CloseJobAction.java | 2 +- .../ml/action/CoordinatedInferenceAction.java | 2 +- .../CreateTrainedModelAssignmentAction.java | 2 +- .../core/ml/action/DeleteCalendarAction.java | 2 +- .../ml/action/DeleteCalendarEventAction.java | 2 +- .../DeleteDataFrameAnalyticsAction.java | 2 +- .../core/ml/action/DeleteDatafeedAction.java | 2 +- .../ml/action/DeleteExpiredDataAction.java | 2 +- .../core/ml/action/DeleteFilterAction.java | 2 +- .../core/ml/action/DeleteForecastAction.java | 2 +- .../xpack/core/ml/action/DeleteJobAction.java | 2 +- .../ml/action/DeleteModelSnapshotAction.java | 2 +- .../ml/action/DeleteTrainedModelAction.java | 2 +- .../action/DeleteTrainedModelAliasAction.java | 2 +- .../DeleteTrainedModelAssignmentAction.java | 2 +- .../ml/action/EstimateModelMemoryAction.java | 2 +- .../ml/action/EvaluateDataFrameAction.java | 2 +- .../ExplainDataFrameAnalyticsAction.java | 2 +- .../ml/action/FinalizeJobExecutionAction.java | 2 +- .../xpack/core/ml/action/FlushJobAction.java | 2 +- .../core/ml/action/ForecastJobAction.java | 2 +- .../core/ml/action/GetBucketsAction.java | 2 +- .../ml/action/GetCalendarEventsAction.java | 2 +- .../core/ml/action/GetCalendarsAction.java | 2 +- .../core/ml/action/GetCategoriesAction.java | 2 +- .../action/GetDataFrameAnalyticsAction.java | 2 +- .../GetDataFrameAnalyticsStatsAction.java | 2 +- .../action/GetDatafeedRunningStateAction.java | 2 +- .../core/ml/action/GetDatafeedsAction.java | 2 +- .../ml/action/GetDatafeedsStatsAction.java | 2 +- .../ml/action/GetDeploymentStatsAction.java | 2 +- .../core/ml/action/GetFiltersAction.java | 2 +- .../core/ml/action/GetInfluencersAction.java | 2 +- ...etJobModelSnapshotsUpgradeStatsAction.java | 2 +- .../xpack/core/ml/action/GetJobsAction.java | 2 +- .../core/ml/action/GetJobsStatsAction.java | 2 +- .../core/ml/action/GetMlAutoscalingStats.java | 2 +- .../ml/action/GetModelSnapshotsAction.java | 2 +- .../ml/action/GetOverallBucketsAction.java | 2 +- .../core/ml/action/GetRecordsAction.java | 2 +- .../ml/action/GetTrainedModelsAction.java | 2 +- .../action/GetTrainedModelsStatsAction.java | 2 +- .../core/ml/action/InferModelAction.java | 2 +- .../InferTrainedModelDeploymentAction.java | 2 +- .../core/ml/action/IsolateDatafeedAction.java | 2 +- .../core/ml/action/KillProcessAction.java | 2 +- .../xpack/core/ml/action/MlInfoAction.java | 2 +- .../xpack/core/ml/action/MlMemoryAction.java | 2 +- .../xpack/core/ml/action/OpenJobAction.java | 2 +- .../core/ml/action/PersistJobAction.java | 2 +- .../ml/action/PostCalendarEventsAction.java | 2 +- .../xpack/core/ml/action/PostDataAction.java | 2 +- .../PreviewDataFrameAnalyticsAction.java | 2 +- .../core/ml/action/PreviewDatafeedAction.java | 2 +- .../core/ml/action/PutCalendarAction.java | 2 +- .../action/PutDataFrameAnalyticsAction.java | 2 +- .../core/ml/action/PutDatafeedAction.java | 2 +- .../xpack/core/ml/action/PutFilterAction.java | 2 +- .../xpack/core/ml/action/PutJobAction.java | 2 +- .../core/ml/action/PutTrainedModelAction.java | 2 +- .../ml/action/PutTrainedModelAliasAction.java | 2 +- .../PutTrainedModelDefinitionPartAction.java | 2 +- .../PutTrainedModelVocabularyAction.java | 2 +- .../xpack/core/ml/action/ResetJobAction.java | 2 +- .../ml/action/RevertModelSnapshotAction.java | 2 +- .../core/ml/action/SetResetModeAction.java | 2 +- .../core/ml/action/SetUpgradeModeAction.java | 2 +- .../action/StartDataFrameAnalyticsAction.java | 2 +- .../core/ml/action/StartDatafeedAction.java | 2 +- .../StartTrainedModelDeploymentAction.java | 2 +- .../action/StopDataFrameAnalyticsAction.java | 2 +- .../core/ml/action/StopDatafeedAction.java | 2 +- .../StopTrainedModelDeploymentAction.java | 2 +- .../action/TrainedModelCacheInfoAction.java | 2 +- .../ml/action/UpdateCalendarJobAction.java | 2 +- .../UpdateDataFrameAnalyticsAction.java | 2 +- .../core/ml/action/UpdateDatafeedAction.java | 2 +- .../core/ml/action/UpdateFilterAction.java | 2 +- .../xpack/core/ml/action/UpdateJobAction.java | 2 +- .../ml/action/UpdateModelSnapshotAction.java | 2 +- .../core/ml/action/UpdateProcessAction.java | 2 +- ...ainedModelAssignmentRoutingInfoAction.java | 2 +- .../UpdateTrainedModelDeploymentAction.java | 2 +- .../action/UpgradeJobModelSnapshotAction.java | 2 +- .../ml/action/ValidateDetectorAction.java | 2 +- .../ml/action/ValidateJobConfigAction.java | 2 +- .../GetTrainedModelPackageConfigAction.java | 2 +- .../action/LoadTrainedModelPackageAction.java | 2 +- .../action/MonitoringBulkAction.java | 2 +- .../action/MonitoringMigrateAlertsAction.java | 2 +- .../rollup/action/DeleteRollupJobAction.java | 2 +- .../rollup/action/GetRollupCapsAction.java | 2 +- .../action/GetRollupIndexCapsAction.java | 2 +- .../rollup/action/GetRollupJobsAction.java | 2 +- .../rollup/action/PutRollupJobAction.java | 2 +- .../rollup/action/RollupSearchAction.java | 2 +- .../rollup/action/StartRollupJobAction.java | 2 +- .../rollup/action/StopRollupJobAction.java | 2 +- .../search/action/GetAsyncSearchAction.java | 2 +- .../search/action/GetAsyncStatusAction.java | 2 +- .../action/SubmitAsyncSearchAction.java | 2 +- .../MountSearchableSnapshotAction.java | 2 +- .../core/security/action/ActionTypes.java | 4 +-- .../action/ClearSecurityCacheAction.java | 3 +-- .../DelegatePkiAuthenticationAction.java | 2 +- .../action/apikey/BulkUpdateApiKeyAction.java | 2 +- .../action/apikey/CreateApiKeyAction.java | 2 +- .../CreateCrossClusterApiKeyAction.java | 2 +- .../action/apikey/GetApiKeyAction.java | 2 +- .../action/apikey/GrantApiKeyAction.java | 2 +- .../action/apikey/InvalidateApiKeyAction.java | 2 +- .../action/apikey/QueryApiKeyAction.java | 3 +-- .../action/apikey/UpdateApiKeyAction.java | 2 +- .../UpdateCrossClusterApiKeyAction.java | 2 +- .../enrollment/KibanaEnrollmentAction.java | 2 +- .../enrollment/NodeEnrollmentAction.java | 2 +- .../oidc/OpenIdConnectAuthenticateAction.java | 2 +- .../oidc/OpenIdConnectLogoutAction.java | 2 +- ...nIdConnectPrepareAuthenticationAction.java | 2 +- .../privilege/ClearPrivilegesCacheAction.java | 3 +-- .../privilege/DeletePrivilegesAction.java | 2 +- .../privilege/GetBuiltinPrivilegesAction.java | 2 +- .../action/privilege/GetPrivilegesAction.java | 2 +- .../action/privilege/PutPrivilegesAction.java | 2 +- .../action/profile/ActivateProfileAction.java | 2 +- .../action/profile/GetProfilesAction.java | 2 +- .../profile/SetProfileEnabledAction.java | 2 +- .../action/profile/SuggestProfilesAction.java | 2 +- .../profile/UpdateProfileDataAction.java | 2 +- .../action/realm/ClearRealmCacheAction.java | 3 +-- .../action/role/ClearRolesCacheAction.java | 3 +-- .../action/role/DeleteRoleAction.java | 2 +- .../security/action/role/GetRolesAction.java | 2 +- .../security/action/role/PutRoleAction.java | 2 +- .../rolemapping/DeleteRoleMappingAction.java | 2 +- .../rolemapping/GetRoleMappingsAction.java | 2 +- .../rolemapping/PutRoleMappingAction.java | 2 +- .../action/saml/SamlAuthenticateAction.java | 2 +- .../saml/SamlInvalidateSessionAction.java | 2 +- .../action/saml/SamlLogoutAction.java | 2 +- .../saml/SamlPrepareAuthenticationAction.java | 2 +- .../action/saml/SamlSpMetadataAction.java | 2 +- .../CreateServiceAccountTokenAction.java | 2 +- .../DeleteServiceAccountTokenAction.java | 2 +- .../service/GetServiceAccountAction.java | 2 +- .../GetServiceAccountCredentialsAction.java | 2 +- ...tServiceAccountNodesCredentialsAction.java | 3 +-- .../settings/GetSecuritySettingsAction.java | 2 +- .../UpdateSecuritySettingsAction.java | 2 +- .../action/token/CreateTokenAction.java | 2 +- .../action/token/InvalidateTokenAction.java | 2 +- .../action/token/RefreshTokenAction.java | 2 +- .../action/user/AuthenticateAction.java | 2 +- .../action/user/DeleteUserAction.java | 2 +- .../action/user/GetUserPrivilegesAction.java | 2 +- .../security/action/user/GetUsersAction.java | 2 +- .../action/user/HasPrivilegesAction.java | 3 +-- .../user/ProfileHasPrivilegesAction.java | 2 +- .../security/action/user/PutUserAction.java | 2 +- .../action/DeleteSnapshotLifecycleAction.java | 2 +- .../ExecuteSnapshotLifecycleAction.java | 2 +- .../ExecuteSnapshotRetentionAction.java | 2 +- .../core/slm/action/GetSLMStatusAction.java | 2 +- .../action/GetSnapshotLifecycleAction.java | 2 +- .../GetSnapshotLifecycleStatsAction.java | 2 +- .../action/PutSnapshotLifecycleAction.java | 2 +- .../xpack/core/slm/action/StartSLMAction.java | 2 +- .../xpack/core/slm/action/StopSLMAction.java | 2 +- .../spatial/action/SpatialStatsAction.java | 2 +- .../ssl/action/GetCertificateInfoAction.java | 2 +- .../termsenum/action/TermsEnumAction.java | 3 +-- .../action/FindStructureAction.java | 2 +- .../action/TestGrokPatternAction.java | 2 +- .../action/DeleteTransformAction.java | 2 +- .../transform/action/GetCheckpointAction.java | 3 +-- .../action/GetCheckpointNodeAction.java | 2 +- .../transform/action/GetTransformAction.java | 2 +- .../action/GetTransformStatsAction.java | 2 +- .../action/PreviewTransformAction.java | 2 +- .../transform/action/PutTransformAction.java | 2 +- .../action/ResetTransformAction.java | 2 +- .../action/ScheduleNowTransformAction.java | 2 +- .../transform/action/SetResetModeAction.java | 2 +- .../action/StartTransformAction.java | 2 +- .../transform/action/StopTransformAction.java | 2 +- .../action/UpdateTransformAction.java | 2 +- .../action/UpgradeTransformsAction.java | 2 +- .../action/ValidateTransformAction.java | 2 +- .../transport/actions/QueryWatchesAction.java | 2 +- .../transport/actions/ack/AckWatchAction.java | 2 +- .../actions/activate/ActivateWatchAction.java | 2 +- .../actions/delete/DeleteWatchAction.java | 2 +- .../actions/execute/ExecuteWatchAction.java | 2 +- .../transport/actions/get/GetWatchAction.java | 2 +- .../actions/put/GetWatcherSettingsAction.java | 2 +- .../transport/actions/put/PutWatchAction.java | 2 +- .../put/UpdateWatcherSettingsAction.java | 2 +- .../actions/service/WatcherServiceAction.java | 2 +- .../actions/stats/WatcherStatsAction.java | 3 +-- .../deprecation/DeprecationInfoAction.java | 2 +- .../NodesDeprecationCheckAction.java | 3 +-- .../logging/DeprecationCacheResetAction.java | 2 +- ...DownsampleShardPersistentTaskExecutor.java | 2 +- .../action/EnrichCoordinatorProxyAction.java | 2 +- .../action/EnrichCoordinatorStatsAction.java | 3 +-- .../enrich/action/EnrichReindexAction.java | 2 +- .../action/EnrichShardMultiSearchAction.java | 2 +- .../action/InternalExecutePolicyAction.java | 2 +- .../DeleteAnalyticsCollectionAction.java | 2 +- .../action/GetAnalyticsCollectionAction.java | 2 +- .../action/PostAnalyticsEventAction.java | 2 +- .../action/PutAnalyticsCollectionAction.java | 2 +- .../action/DeleteConnectorAction.java | 2 +- .../connector/action/GetConnectorAction.java | 2 +- .../connector/action/ListConnectorAction.java | 2 +- .../connector/action/PostConnectorAction.java | 2 +- .../connector/action/PutConnectorAction.java | 2 +- .../UpdateConnectorConfigurationAction.java | 2 +- .../action/UpdateConnectorErrorAction.java | 2 +- .../UpdateConnectorFilteringAction.java | 2 +- .../action/UpdateConnectorLastSeenAction.java | 2 +- .../UpdateConnectorLastSyncStatsAction.java | 2 +- .../action/UpdateConnectorNameAction.java | 2 +- .../action/UpdateConnectorNativeAction.java | 2 +- .../action/UpdateConnectorPipelineAction.java | 2 +- .../UpdateConnectorSchedulingAction.java | 2 +- .../UpdateConnectorServiceTypeAction.java | 2 +- .../action/CancelConnectorSyncJobAction.java | 2 +- .../action/CheckInConnectorSyncJobAction.java | 2 +- .../action/DeleteConnectorSyncJobAction.java | 2 +- .../action/GetConnectorSyncJobAction.java | 2 +- .../action/ListConnectorSyncJobsAction.java | 2 +- .../action/PostConnectorSyncJobAction.java | 2 +- .../UpdateConnectorSyncJobErrorAction.java | 2 +- ...eConnectorSyncJobIngestionStatsAction.java | 2 +- .../action/DeleteQueryRulesetAction.java | 2 +- .../rules/action/GetQueryRulesetAction.java | 2 +- .../rules/action/ListQueryRulesetsAction.java | 2 +- .../rules/action/PutQueryRulesetAction.java | 2 +- .../action/DeleteSearchApplicationAction.java | 2 +- .../action/GetSearchApplicationAction.java | 2 +- .../action/ListSearchApplicationAction.java | 2 +- .../action/PutSearchApplicationAction.java | 2 +- .../action/QuerySearchApplicationAction.java | 2 +- .../RenderSearchApplicationQueryAction.java | 2 +- .../xpack/eql/action/EqlSearchAction.java | 2 +- .../eql/plugin/EqlAsyncGetResultAction.java | 2 +- .../eql/plugin/EqlAsyncGetStatusAction.java | 2 +- .../xpack/eql/plugin/EqlStatsAction.java | 3 +-- .../esql/action/EsqlAsyncGetResultAction.java | 2 +- .../xpack/esql/action/EsqlQueryAction.java | 2 +- .../xpack/esql/plugin/EsqlStatsAction.java | 3 +-- .../fleet/action/DeleteSecretAction.java | 2 +- .../action/GetGlobalCheckpointsAction.java | 3 +-- .../GetGlobalCheckpointsShardAction.java | 2 +- .../xpack/fleet/action/GetSecretAction.java | 2 +- .../xpack/fleet/action/PostSecretAction.java | 2 +- .../DeleteSamlServiceProviderAction.java | 2 +- .../action/PutSamlServiceProviderAction.java | 2 +- .../SamlInitiateSingleSignOnAction.java | 2 +- .../xpack/idp/action/SamlMetadataAction.java | 2 +- .../SamlValidateAuthnRequestAction.java | 2 +- .../logstash/action/DeletePipelineAction.java | 2 +- .../logstash/action/GetPipelineAction.java | 2 +- .../logstash/action/PutPipelineAction.java | 2 +- .../xpack/profiling/GetFlamegraphAction.java | 3 +-- .../xpack/profiling/GetStackTracesAction.java | 3 +-- .../xpack/profiling/GetStatusAction.java | 2 +- ...learRepositoriesMeteringArchiveAction.java | 3 +-- .../action/RepositoriesMeteringAction.java | 3 +-- .../ClearSearchableSnapshotsCacheAction.java | 2 +- .../SearchableSnapshotsStatsAction.java | 2 +- .../action/cache/FrozenCacheInfoAction.java | 2 +- .../cache/FrozenCacheInfoNodeAction.java | 2 +- ...rtSearchableSnapshotCacheStoresAction.java | 3 +-- ...rchableSnapshotsNodeCachesStatsAction.java | 3 +-- .../TransportSamlCompleteLogoutAction.java | 4 +-- .../user/TransportChangePasswordAction.java | 4 +-- .../user/TransportSetEnabledAction.java | 2 +- .../shutdown/DeleteShutdownNodeAction.java | 2 +- .../shutdown/GetShutdownStatusAction.java | 2 +- .../xpack/shutdown/PutShutdownNodeAction.java | 2 +- ...TransportSLMGetExpiredSnapshotsAction.java | 2 +- .../testkit/RepositoryAnalyzeAction.java | 2 +- .../sql/action/SqlClearCursorAction.java | 2 +- .../xpack/sql/action/SqlQueryAction.java | 2 +- .../xpack/sql/action/SqlTranslateAction.java | 2 +- .../sql/plugin/SqlAsyncGetResultsAction.java | 2 +- .../sql/plugin/SqlAsyncGetStatusAction.java | 2 +- .../xpack/sql/plugin/SqlStatsAction.java | 3 +-- 538 files changed, 554 insertions(+), 670 deletions(-) diff --git a/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/NoopPlugin.java b/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/NoopPlugin.java index 81d6eaf690dbf..f587163b9324f 100644 --- a/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/NoopPlugin.java +++ b/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/NoopPlugin.java @@ -34,8 +34,8 @@ public class NoopPlugin extends Plugin implements ActionPlugin { - public static final ActionType NOOP_SEARCH_ACTION = new ActionType<>("mock:data/read/search", SearchResponse::new); - public static final ActionType NOOP_BULK_ACTION = new ActionType<>("mock:data/write/bulk", BulkResponse::new); + public static final ActionType NOOP_SEARCH_ACTION = new ActionType<>("mock:data/read/search"); + public static final ActionType NOOP_BULK_ACTION = new ActionType<>("mock:data/write/bulk"); @Override public List> getActions() { diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/DeleteDataStreamLifecycleAction.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/DeleteDataStreamLifecycleAction.java index 202279fcbdc80..3fe9ae0758a91 100644 --- a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/DeleteDataStreamLifecycleAction.java +++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/DeleteDataStreamLifecycleAction.java @@ -25,7 +25,7 @@ */ public class DeleteDataStreamLifecycleAction { - public static final ActionType INSTANCE = ActionType.localOnly("indices:admin/data_stream/lifecycle/delete"); + public static final ActionType INSTANCE = new ActionType<>("indices:admin/data_stream/lifecycle/delete"); private DeleteDataStreamLifecycleAction() {/* no instances */} diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/ExplainDataStreamLifecycleAction.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/ExplainDataStreamLifecycleAction.java index 9e13bd7e0a99b..676052f76d564 100644 --- a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/ExplainDataStreamLifecycleAction.java +++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/ExplainDataStreamLifecycleAction.java @@ -36,8 +36,7 @@ public class ExplainDataStreamLifecycleAction { public static final ActionType INSTANCE = new ActionType<>( - "indices:admin/data_stream/lifecycle/explain", - Response::new + "indices:admin/data_stream/lifecycle/explain" ); private ExplainDataStreamLifecycleAction() {/* no instances */} diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/GetDataStreamLifecycleAction.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/GetDataStreamLifecycleAction.java index d2e24479df347..8149e1a0df443 100644 --- a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/GetDataStreamLifecycleAction.java +++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/GetDataStreamLifecycleAction.java @@ -37,8 +37,7 @@ public class GetDataStreamLifecycleAction { public static final ActionType INSTANCE = new ActionType<>( - "indices:admin/data_stream/lifecycle/get", - Response::new + "indices:admin/data_stream/lifecycle/get" ); private GetDataStreamLifecycleAction() {/* no instances */} diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/GetDataStreamLifecycleStatsAction.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/GetDataStreamLifecycleStatsAction.java index c3444a67b847c..a30af402a9186 100644 --- a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/GetDataStreamLifecycleStatsAction.java +++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/GetDataStreamLifecycleStatsAction.java @@ -34,7 +34,7 @@ public class GetDataStreamLifecycleStatsAction extends ActionType { diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/PutDataStreamLifecycleAction.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/PutDataStreamLifecycleAction.java index 88ebfec89d442..c40988f1de6c7 100644 --- a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/PutDataStreamLifecycleAction.java +++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/PutDataStreamLifecycleAction.java @@ -39,7 +39,7 @@ */ public class PutDataStreamLifecycleAction { - public static final ActionType INSTANCE = ActionType.localOnly("indices:admin/data_stream/lifecycle/put"); + public static final ActionType INSTANCE = new ActionType<>("indices:admin/data_stream/lifecycle/put"); private PutDataStreamLifecycleAction() {/* no instances */} diff --git a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/GrokProcessorGetAction.java b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/GrokProcessorGetAction.java index 2fe666c5f208c..8add2b0d05535 100644 --- a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/GrokProcessorGetAction.java +++ b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/GrokProcessorGetAction.java @@ -42,10 +42,7 @@ public class GrokProcessorGetAction { - static final ActionType INSTANCE = new ActionType<>( - "cluster:admin/ingest/processor/grok/get", - Response::new - ); + static final ActionType INSTANCE = new ActionType<>("cluster:admin/ingest/processor/grok/get"); private GrokProcessorGetAction() {/* no instances */} diff --git a/modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/stats/GeoIpDownloaderStatsAction.java b/modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/stats/GeoIpDownloaderStatsAction.java index 9921b144afcac..f9b1d8c637f68 100644 --- a/modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/stats/GeoIpDownloaderStatsAction.java +++ b/modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/stats/GeoIpDownloaderStatsAction.java @@ -32,7 +32,7 @@ public class GeoIpDownloaderStatsAction { - public static final ActionType INSTANCE = new ActionType<>("cluster:monitor/ingest/geoip/stats", Response::new); + public static final ActionType INSTANCE = new ActionType<>("cluster:monitor/ingest/geoip/stats"); private GeoIpDownloaderStatsAction() {/* no instances */} diff --git a/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/MustachePlugin.java b/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/MustachePlugin.java index 310046cb11a20..b7f5035122dfe 100644 --- a/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/MustachePlugin.java +++ b/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/MustachePlugin.java @@ -34,13 +34,9 @@ public class MustachePlugin extends Plugin implements ScriptPlugin, ActionPlugin, SearchPlugin { - public static final ActionType SEARCH_TEMPLATE_ACTION = new ActionType<>( - "indices:data/read/search/template", - SearchTemplateResponse::new - ); + public static final ActionType SEARCH_TEMPLATE_ACTION = new ActionType<>("indices:data/read/search/template"); public static final ActionType MULTI_SEARCH_TEMPLATE_ACTION = new ActionType<>( - "indices:data/read/msearch/template", - MultiSearchTemplateResponse::new + "indices:data/read/msearch/template" ); @Override diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/action/PainlessContextAction.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/action/PainlessContextAction.java index 376278f8f0c52..6d88ff1e8db6a 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/action/PainlessContextAction.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/action/PainlessContextAction.java @@ -54,7 +54,7 @@ */ public class PainlessContextAction { - public static final ActionType INSTANCE = new ActionType<>("cluster:admin/scripts/painless/context", Response::new); + public static final ActionType INSTANCE = new ActionType<>("cluster:admin/scripts/painless/context"); private static final String SCRIPT_CONTEXT_NAME_PARAM = "context"; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/action/PainlessExecuteAction.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/action/PainlessExecuteAction.java index 2641f68bbc16e..3b67b76f59a31 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/action/PainlessExecuteAction.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/action/PainlessExecuteAction.java @@ -116,7 +116,7 @@ public class PainlessExecuteAction { - public static final ActionType INSTANCE = ActionType.localOnly("cluster:admin/scripts/painless/execute"); + public static final ActionType INSTANCE = new ActionType<>("cluster:admin/scripts/painless/execute"); public static final RemoteClusterActionType REMOTE_TYPE = new RemoteClusterActionType<>(INSTANCE.name(), Response::new); private PainlessExecuteAction() {/* no instances */} diff --git a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalPlugin.java b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalPlugin.java index 0d421d3d1619c..381fe2cd7a77e 100644 --- a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalPlugin.java +++ b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalPlugin.java @@ -32,7 +32,7 @@ public class RankEvalPlugin extends Plugin implements ActionPlugin { - public static final ActionType ACTION = new ActionType<>("indices:data/read/rank_eval", RankEvalResponse::new); + public static final ActionType ACTION = new ActionType<>("indices:data/read/rank_eval"); @Override public List> getActions() { diff --git a/modules/reindex/src/main/java/org/elasticsearch/reindex/ReindexPlugin.java b/modules/reindex/src/main/java/org/elasticsearch/reindex/ReindexPlugin.java index a5cfe8ce3ca11..42ff1fda6e74d 100644 --- a/modules/reindex/src/main/java/org/elasticsearch/reindex/ReindexPlugin.java +++ b/modules/reindex/src/main/java/org/elasticsearch/reindex/ReindexPlugin.java @@ -42,10 +42,7 @@ public class ReindexPlugin extends Plugin implements ActionPlugin { public static final String NAME = "reindex"; - public static final ActionType RETHROTTLE_ACTION = new ActionType<>( - "cluster:admin/reindex/rethrottle", - ListTasksResponse::new - ); + public static final ActionType RETHROTTLE_ACTION = new ActionType<>("cluster:admin/reindex/rethrottle"); @Override public List> getActions() { diff --git a/modules/rest-root/src/main/java/org/elasticsearch/rest/root/MainRestPlugin.java b/modules/rest-root/src/main/java/org/elasticsearch/rest/root/MainRestPlugin.java index 3045681483470..ad7b821c986c1 100644 --- a/modules/rest-root/src/main/java/org/elasticsearch/rest/root/MainRestPlugin.java +++ b/modules/rest-root/src/main/java/org/elasticsearch/rest/root/MainRestPlugin.java @@ -28,7 +28,7 @@ public class MainRestPlugin extends Plugin implements ActionPlugin { - public static final ActionType MAIN_ACTION = ActionType.localOnly("cluster:monitor/main"); + public static final ActionType MAIN_ACTION = new ActionType<>("cluster:monitor/main"); @Override public List getRestHandlers( diff --git a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/node/tasks/CancellableTasksIT.java b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/node/tasks/CancellableTasksIT.java index cb3eee3c60c23..e1804368c2cad 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/node/tasks/CancellableTasksIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/node/tasks/CancellableTasksIT.java @@ -504,7 +504,7 @@ public void writeTo(StreamOutput out) throws IOException { public static class TransportTestAction extends HandledTransportAction { - public static ActionType ACTION = new ActionType<>("internal::test_action", TestResponse::new); + public static ActionType ACTION = new ActionType<>("internal::test_action"); private final TransportService transportService; private final NodeClient client; diff --git a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/tasks/ListTasksIT.java b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/tasks/ListTasksIT.java index 955ec4a0bbc99..4a076cb3b6e66 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/tasks/ListTasksIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/tasks/ListTasksIT.java @@ -142,7 +142,7 @@ protected Collection> getPlugins() { return List.of(TestPlugin.class); } - private static final ActionType TEST_ACTION = ActionType.emptyResponse(TestTransportAction.NAME); + private static final ActionType TEST_ACTION = new ActionType<>(TestTransportAction.NAME); public static class TestPlugin extends Plugin implements ActionPlugin { volatile CyclicBarrier barrier; diff --git a/server/src/internalClusterTest/java/org/elasticsearch/action/support/replication/TransportReplicationActionRetryOnClosedNodeIT.java b/server/src/internalClusterTest/java/org/elasticsearch/action/support/replication/TransportReplicationActionRetryOnClosedNodeIT.java index 5ee25850fcc23..b89cea7dff089 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/action/support/replication/TransportReplicationActionRetryOnClosedNodeIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/action/support/replication/TransportReplicationActionRetryOnClosedNodeIT.java @@ -82,7 +82,7 @@ public Response(StreamInput in) throws IOException { public static class TestAction extends TransportReplicationAction { private static final String ACTION_NAME = "internal:test-replication-action"; - private static final ActionType TYPE = new ActionType<>(ACTION_NAME, Response::new); + private static final ActionType TYPE = new ActionType<>(ACTION_NAME); @Inject public TestAction( diff --git a/server/src/main/java/org/elasticsearch/action/ActionType.java b/server/src/main/java/org/elasticsearch/action/ActionType.java index 774699efca527..fa8cb0006d587 100644 --- a/server/src/main/java/org/elasticsearch/action/ActionType.java +++ b/server/src/main/java/org/elasticsearch/action/ActionType.java @@ -11,8 +11,6 @@ import org.elasticsearch.action.support.master.TransportMasterNodeAction; import org.elasticsearch.action.support.nodes.TransportNodesAction; import org.elasticsearch.client.internal.Client; -import org.elasticsearch.client.internal.node.NodeClient; -import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.plugins.ActionPlugin; import org.elasticsearch.transport.TransportService; @@ -25,39 +23,21 @@ * TYPE}. Some legacy implementations create custom subclasses of {@link ActionType} but this is unnecessary and somewhat wasteful. Prefer * to create instances of this class directly whenever possible. */ +@SuppressWarnings("unused") // Response type arg is used to enable better type inference when calling Client#execute public class ActionType { private final String name; /** - * Construct an {@link ActionType} which callers can execute on the local node (using {@link NodeClient}). + * Construct an {@link ActionType} with the given name. *

* There is no facility for directly executing an action on a different node in the local cluster. To achieve this, implement an action * which runs on the local node and knows how to use the {@link TransportService} to forward the request to a different node. There are * several utilities that help implement such an action, including {@link TransportNodesAction} or {@link TransportMasterNodeAction}. * * @param name The name of the action, which must be unique across actions. - * @return an {@link ActionType} which callers can execute on the local node. */ - public static ActionType localOnly(String name) { - return new ActionType<>(name, Writeable.Reader.localOnly()); - } - - public static ActionType emptyResponse(String name) { - return new ActionType<>(name, in -> ActionResponse.Empty.INSTANCE); - } - - /** - * Construct an {@link ActionType} and specify a method that can deserialize the response. This {@code responseReader} parameter is - * effectively unused. Use {@link #localOnly} instead. - *

- * There is no facility for directly executing an action on a different node in the local cluster. To achieve this, implement an action - * which runs on the local node and knows how to use the {@link TransportService} to forward the request to a different node. There are - * several utilities that help implement such an action, including {@link TransportNodesAction} or {@link TransportMasterNodeAction}. - * - * @param name The name of the action, which must be unique across actions. - */ - public ActionType(String name, Writeable.Reader ignored) { + public ActionType(String name) { this.name = name; } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/TransportClusterAllocationExplainAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/TransportClusterAllocationExplainAction.java index 7599eb2faef96..c51e6140fac89 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/TransportClusterAllocationExplainAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/TransportClusterAllocationExplainAction.java @@ -44,10 +44,7 @@ public class TransportClusterAllocationExplainAction extends TransportMasterNode ClusterAllocationExplainRequest, ClusterAllocationExplainResponse> { - public static final ActionType TYPE = new ActionType<>( - "cluster:monitor/allocation/explain", - ClusterAllocationExplainResponse::new - ); + public static final ActionType TYPE = new ActionType<>("cluster:monitor/allocation/explain"); private static final Logger logger = LogManager.getLogger(TransportClusterAllocationExplainAction.class); private final ClusterInfoService clusterInfoService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/TransportDeleteDesiredBalanceAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/TransportDeleteDesiredBalanceAction.java index 76b563c3f540a..76a9b5a245a84 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/TransportDeleteDesiredBalanceAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/TransportDeleteDesiredBalanceAction.java @@ -35,7 +35,7 @@ public class TransportDeleteDesiredBalanceAction extends TransportMasterNodeAction { - public static final ActionType TYPE = ActionType.emptyResponse("cluster:admin/desired_balance/reset"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/desired_balance/reset"); @Nullable private final MasterServiceTaskQueue resetDesiredBalanceTaskQueue; diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/TransportGetDesiredBalanceAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/TransportGetDesiredBalanceAction.java index 49611ffae8718..fca7b5c44fd29 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/TransportGetDesiredBalanceAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/TransportGetDesiredBalanceAction.java @@ -43,10 +43,7 @@ public class TransportGetDesiredBalanceAction extends TransportMasterNodeReadAction { - public static final ActionType TYPE = new ActionType<>( - "cluster:admin/desired_balance/get", - DesiredBalanceResponse::from - ); + public static final ActionType TYPE = new ActionType<>("cluster:admin/desired_balance/get"); @Nullable private final DesiredBalanceShardsAllocator desiredBalanceShardsAllocator; private final ClusterInfoService clusterInfoService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/configuration/TransportAddVotingConfigExclusionsAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/configuration/TransportAddVotingConfigExclusionsAction.java index b9bcf0944cd83..c540d535e60d4 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/configuration/TransportAddVotingConfigExclusionsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/configuration/TransportAddVotingConfigExclusionsAction.java @@ -49,7 +49,7 @@ public class TransportAddVotingConfigExclusionsAction extends TransportMasterNod AddVotingConfigExclusionsRequest, ActionResponse.Empty> { - public static final ActionType TYPE = ActionType.emptyResponse("cluster:admin/voting_config/add_exclusions"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/voting_config/add_exclusions"); private static final Logger logger = LogManager.getLogger(TransportAddVotingConfigExclusionsAction.class); public static final Setting MAXIMUM_VOTING_CONFIG_EXCLUSIONS_SETTING = Setting.intSetting( diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/configuration/TransportClearVotingConfigExclusionsAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/configuration/TransportClearVotingConfigExclusionsAction.java index 113d085f51fdb..bbe292e817389 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/configuration/TransportClearVotingConfigExclusionsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/configuration/TransportClearVotingConfigExclusionsAction.java @@ -43,7 +43,7 @@ public class TransportClearVotingConfigExclusionsAction extends TransportMasterN ClearVotingConfigExclusionsRequest, ActionResponse.Empty> { - public static final ActionType TYPE = ActionType.emptyResponse("cluster:admin/voting_config/clear_exclusions"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/voting_config/clear_exclusions"); private static final Logger logger = LogManager.getLogger(TransportClearVotingConfigExclusionsAction.class); private final Reconfigurator reconfigurator; diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/coordination/ClusterFormationInfoAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/coordination/ClusterFormationInfoAction.java index 906aa00947bb2..95025c851fd94 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/coordination/ClusterFormationInfoAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/coordination/ClusterFormationInfoAction.java @@ -37,7 +37,7 @@ public class ClusterFormationInfoAction extends ActionType { diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/desirednodes/TransportDeleteDesiredNodesAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/desirednodes/TransportDeleteDesiredNodesAction.java index 8eb74bea05629..e6e2616e67662 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/desirednodes/TransportDeleteDesiredNodesAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/desirednodes/TransportDeleteDesiredNodesAction.java @@ -37,7 +37,7 @@ public class TransportDeleteDesiredNodesAction extends TransportMasterNodeAction { - public static final ActionType TYPE = ActionType.emptyResponse("cluster:admin/desired_nodes/delete"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/desired_nodes/delete"); private final MasterServiceTaskQueue taskQueue; @Inject diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/desirednodes/UpdateDesiredNodesAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/desirednodes/UpdateDesiredNodesAction.java index 335ab15cd14cb..37f7baa3a30d9 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/desirednodes/UpdateDesiredNodesAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/desirednodes/UpdateDesiredNodesAction.java @@ -15,6 +15,6 @@ public class UpdateDesiredNodesAction extends ActionType { public static final String NAME = "cluster:monitor/health"; - public static final ActionType TYPE = new ActionType(NAME, ClusterHealthResponse::new); + public static final ActionType TYPE = new ActionType(NAME); private static final Logger logger = LogManager.getLogger(TransportClusterHealthAction.class); private final AllocationService allocationService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/migration/GetFeatureUpgradeStatusAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/migration/GetFeatureUpgradeStatusAction.java index 85c6c9ef9e133..4a57620d61e81 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/migration/GetFeatureUpgradeStatusAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/migration/GetFeatureUpgradeStatusAction.java @@ -19,6 +19,6 @@ public class GetFeatureUpgradeStatusAction extends ActionType { - public static final ActionType TYPE = ActionType.localOnly("cluster:monitor/nodes/hot_threads"); + public static final ActionType TYPE = new ActionType<>("cluster:monitor/nodes/hot_threads"); @Inject public TransportNodesHotThreadsAction( diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/info/TransportNodesInfoAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/info/TransportNodesInfoAction.java index 89753bfa94df8..eca6102393a19 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/info/TransportNodesInfoAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/info/TransportNodesInfoAction.java @@ -35,7 +35,7 @@ public class TransportNodesInfoAction extends TransportNodesAction< TransportNodesInfoAction.NodeInfoRequest, NodeInfo> { - public static final ActionType TYPE = ActionType.localOnly("cluster:monitor/nodes/info"); + public static final ActionType TYPE = new ActionType<>("cluster:monitor/nodes/info"); private final NodeService nodeService; @Inject diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/reload/TransportNodesReloadSecureSettingsAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/reload/TransportNodesReloadSecureSettingsAction.java index 9598f378a188c..71da6fdeb1f3b 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/reload/TransportNodesReloadSecureSettingsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/reload/TransportNodesReloadSecureSettingsAction.java @@ -40,9 +40,7 @@ public class TransportNodesReloadSecureSettingsAction extends TransportNodesActi NodesReloadSecureSettingsRequest.NodeRequest, NodesReloadSecureSettingsResponse.NodeResponse> { - public static final ActionType TYPE = ActionType.localOnly( - "cluster:admin/nodes/reload_secure_settings" - ); + public static final ActionType TYPE = new ActionType<>("cluster:admin/nodes/reload_secure_settings"); private static final Logger logger = LogManager.getLogger(TransportNodesReloadSecureSettingsAction.class); diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/PrevalidateNodeRemovalAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/PrevalidateNodeRemovalAction.java index e0c4d07e2c385..4e996055a1962 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/PrevalidateNodeRemovalAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/PrevalidateNodeRemovalAction.java @@ -16,7 +16,7 @@ public class PrevalidateNodeRemovalAction extends ActionType { public static final String ACTION_NAME = "internal:admin/indices/prevalidate_shard_path"; - public static final ActionType TYPE = new ActionType<>(ACTION_NAME, Writeable.Reader.localOnly()); + public static final ActionType TYPE = new ActionType<>(ACTION_NAME); private static final Logger logger = LogManager.getLogger(TransportPrevalidateShardPathAction.class); private final TransportService transportService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/TransportNodesStatsAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/TransportNodesStatsAction.java index 106bad68e482e..1edc57b0a7df2 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/TransportNodesStatsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/TransportNodesStatsAction.java @@ -41,7 +41,7 @@ public class TransportNodesStatsAction extends TransportNodesAction< TransportNodesStatsAction.NodeStatsRequest, NodeStats> { - public static final ActionType TYPE = ActionType.localOnly("cluster:monitor/nodes/stats"); + public static final ActionType TYPE = new ActionType<>("cluster:monitor/nodes/stats"); private final NodeService nodeService; @Inject diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/tasks/cancel/CancelTasksAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/tasks/cancel/CancelTasksAction.java index 3cba83305c0fa..50fea2093da49 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/tasks/cancel/CancelTasksAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/tasks/cancel/CancelTasksAction.java @@ -20,6 +20,6 @@ public class CancelTasksAction extends ActionType { public static final String NAME = "cluster:admin/tasks/cancel"; private CancelTasksAction() { - super(NAME, ListTasksResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/tasks/get/GetTaskAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/tasks/get/GetTaskAction.java index a2acdbcd98c1d..21be31462ef0d 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/tasks/get/GetTaskAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/tasks/get/GetTaskAction.java @@ -20,6 +20,6 @@ public class GetTaskAction extends ActionType { public static final String NAME = "cluster:monitor/task/get"; private GetTaskAction() { - super(NAME, GetTaskResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/tasks/list/TransportListTasksAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/tasks/list/TransportListTasksAction.java index c0c9ec493de70..62ede5b2f480b 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/tasks/list/TransportListTasksAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/tasks/list/TransportListTasksAction.java @@ -45,7 +45,7 @@ public class TransportListTasksAction extends TransportTasksAction TYPE = new ActionType<>("cluster:monitor/tasks/lists", ListTasksResponse::new); + public static final ActionType TYPE = new ActionType<>("cluster:monitor/tasks/lists"); public static long waitForCompletionTimeout(TimeValue timeout) { if (timeout == null) { diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/usage/TransportNodesUsageAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/usage/TransportNodesUsageAction.java index c661023e79629..638773cce52e8 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/usage/TransportNodesUsageAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/usage/TransportNodesUsageAction.java @@ -34,7 +34,7 @@ public class TransportNodesUsageAction extends TransportNodesAction< TransportNodesUsageAction.NodeUsageRequest, NodeUsage> { - public static final ActionType TYPE = ActionType.localOnly("cluster:monitor/nodes/usage"); + public static final ActionType TYPE = new ActionType<>("cluster:monitor/nodes/usage"); private final UsageService restUsageService; private final AggregationUsageService aggregationUsageService; private final long sinceTime; diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/remote/RemoteClusterNodesAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/remote/RemoteClusterNodesAction.java index 406913037bc5d..5f3fd654eeb84 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/remote/RemoteClusterNodesAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/remote/RemoteClusterNodesAction.java @@ -39,7 +39,7 @@ public class RemoteClusterNodesAction { public static final String NAME = "cluster:internal/remote_cluster/nodes"; - public static final ActionType TYPE = ActionType.localOnly(NAME); + public static final ActionType TYPE = new ActionType<>(NAME); public static final RemoteClusterActionType REMOTE_TYPE = new RemoteClusterActionType<>( NAME, RemoteClusterNodesAction.Response::new diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/remote/TransportRemoteInfoAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/remote/TransportRemoteInfoAction.java index ae7453b7c8cee..c7d74fc414115 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/remote/TransportRemoteInfoAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/remote/TransportRemoteInfoAction.java @@ -23,7 +23,7 @@ public final class TransportRemoteInfoAction extends HandledTransportAction { - public static final ActionType TYPE = new ActionType<>("cluster:monitor/remote/info", RemoteInfoResponse::new); + public static final ActionType TYPE = new ActionType<>("cluster:monitor/remote/info"); private final RemoteClusterService remoteClusterService; @Inject diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/cleanup/CleanupRepositoryAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/cleanup/CleanupRepositoryAction.java index 94fe5a96f89a2..d71c66fd6f3ca 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/cleanup/CleanupRepositoryAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/cleanup/CleanupRepositoryAction.java @@ -15,6 +15,6 @@ public final class CleanupRepositoryAction extends ActionType { - public static final ActionType TYPE = ActionType.localOnly("cluster:admin/repository/delete"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/repository/delete"); private final RepositoriesService repositoriesService; @Inject diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/GetRepositoriesAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/GetRepositoriesAction.java index 3411f29819f3c..11e31a539fffd 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/GetRepositoriesAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/GetRepositoriesAction.java @@ -19,7 +19,7 @@ public class GetRepositoriesAction extends ActionType { public static final String NAME = "cluster:admin/repository/get"; private GetRepositoriesAction() { - super(NAME, GetRepositoriesResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/put/TransportPutRepositoryAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/put/TransportPutRepositoryAction.java index 98b2d1561eb01..eb7e26b30e874 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/put/TransportPutRepositoryAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/put/TransportPutRepositoryAction.java @@ -34,7 +34,7 @@ */ public class TransportPutRepositoryAction extends AcknowledgedTransportMasterNodeAction { - public static final ActionType TYPE = ActionType.localOnly("cluster:admin/repository/put"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/repository/put"); private final RepositoriesService repositoriesService; @Inject diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/verify/VerifyRepositoryAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/verify/VerifyRepositoryAction.java index 0daaae79592f1..fe66441c41844 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/verify/VerifyRepositoryAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/verify/VerifyRepositoryAction.java @@ -19,6 +19,6 @@ public class VerifyRepositoryAction extends ActionType public static final String NAME = "cluster:admin/repository/verify"; private VerifyRepositoryAction() { - super(NAME, VerifyRepositoryResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteAction.java index 6b626f7c0b170..a09ef9e38bd19 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteAction.java @@ -16,6 +16,6 @@ public class ClusterRerouteAction extends ActionType { public static final String NAME = "cluster:admin/reroute"; private ClusterRerouteAction() { - super(NAME, ClusterRerouteResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/settings/ClusterGetSettingsAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/settings/ClusterGetSettingsAction.java index 0e868087b637d..1ee458100c47f 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/settings/ClusterGetSettingsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/settings/ClusterGetSettingsAction.java @@ -26,7 +26,7 @@ public class ClusterGetSettingsAction extends ActionType { - public static final ActionType TYPE = ActionType.localOnly("cluster:admin/snapshot/clone"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/snapshot/clone"); private final SnapshotsService snapshotsService; @Inject diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotAction.java index eb3a3dfdaebb9..d24fbbb63246b 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotAction.java @@ -19,6 +19,6 @@ public class CreateSnapshotAction extends ActionType { public static final String NAME = "cluster:admin/snapshot/create"; private CreateSnapshotAction() { - super(NAME, CreateSnapshotResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java index 1451f39dadf7c..5db56bfe41ad0 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java @@ -29,7 +29,7 @@ * Transport action for delete snapshot operation */ public class TransportDeleteSnapshotAction extends AcknowledgedTransportMasterNodeAction { - public static final ActionType TYPE = ActionType.localOnly("cluster:admin/snapshot/delete"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/snapshot/delete"); private final SnapshotsService snapshotsService; @Inject diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/features/ResetFeatureStateAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/features/ResetFeatureStateAction.java index 6953fc00b481a..ce1af6abd7732 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/features/ResetFeatureStateAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/features/ResetFeatureStateAction.java @@ -17,6 +17,6 @@ public class ResetFeatureStateAction extends ActionType { public static final String NAME = "cluster:admin/snapshot/get"; private GetSnapshotsAction() { - super(NAME, GetSnapshotsResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/shard/GetShardSnapshotAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/shard/GetShardSnapshotAction.java index bdf822d79f4c5..7cb3440e422a5 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/shard/GetShardSnapshotAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/shard/GetShardSnapshotAction.java @@ -16,6 +16,6 @@ public class GetShardSnapshotAction extends ActionType public static final String NAME = "internal:admin/snapshot/get_shard"; public GetShardSnapshotAction() { - super(NAME, GetShardSnapshotResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/restore/RestoreSnapshotAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/restore/RestoreSnapshotAction.java index a3b6db6ad97c7..3e3916bab19ae 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/restore/RestoreSnapshotAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/restore/RestoreSnapshotAction.java @@ -19,6 +19,6 @@ public class RestoreSnapshotAction extends ActionType { public static final String NAME = "cluster:admin/snapshot/restore"; private RestoreSnapshotAction() { - super(NAME, RestoreSnapshotResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/status/SnapshotsStatusAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/status/SnapshotsStatusAction.java index 9f68ac17a25e8..16faab60b561f 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/status/SnapshotsStatusAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/status/SnapshotsStatusAction.java @@ -19,6 +19,6 @@ public class SnapshotsStatusAction extends ActionType { public static final String NAME = "cluster:admin/snapshot/status"; private SnapshotsStatusAction() { - super(NAME, SnapshotsStatusResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/status/TransportNodesSnapshotsStatus.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/status/TransportNodesSnapshotsStatus.java index c7a29e61da28d..9215d97490629 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/status/TransportNodesSnapshotsStatus.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/status/TransportNodesSnapshotsStatus.java @@ -23,7 +23,6 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.index.snapshots.IndexShardSnapshotStatus; import org.elasticsearch.snapshots.Snapshot; @@ -51,7 +50,7 @@ public class TransportNodesSnapshotsStatus extends TransportNodesAction< TransportNodesSnapshotsStatus.NodeSnapshotStatus> { public static final String ACTION_NAME = SnapshotsStatusAction.NAME + "[nodes]"; - public static final ActionType TYPE = new ActionType<>(ACTION_NAME, Writeable.Reader.localOnly()); + public static final ActionType TYPE = new ActionType<>(ACTION_NAME); private final SnapshotShardsService snapshotShardsService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/state/ClusterStateAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/state/ClusterStateAction.java index 72d57bfcb7d6b..96cb85d241b52 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/state/ClusterStateAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/state/ClusterStateAction.java @@ -10,7 +10,6 @@ import org.elasticsearch.action.ActionType; import org.elasticsearch.action.RemoteClusterActionType; -import org.elasticsearch.common.io.stream.Writeable; public class ClusterStateAction extends ActionType { @@ -22,6 +21,6 @@ public class ClusterStateAction extends ActionType { ); private ClusterStateAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsAction.java index a6bd5bb1f66da..f2e3547d08cda 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsAction.java @@ -9,7 +9,6 @@ package org.elasticsearch.action.admin.cluster.stats; import org.elasticsearch.action.ActionType; -import org.elasticsearch.common.io.stream.Writeable; public class ClusterStatsAction extends ActionType { @@ -17,6 +16,6 @@ public class ClusterStatsAction extends ActionType { public static final String NAME = "cluster:monitor/stats"; private ClusterStatsAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetScriptContextAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetScriptContextAction.java index d984debcce1d0..f1b1e481aea2b 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetScriptContextAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetScriptContextAction.java @@ -16,6 +16,6 @@ public class GetScriptContextAction extends ActionType public static final String NAME = "cluster:admin/script_context/get"; private GetScriptContextAction() { - super(NAME, GetScriptContextResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetScriptLanguageAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetScriptLanguageAction.java index 267f15cabfc1e..e8655b3022abd 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetScriptLanguageAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetScriptLanguageAction.java @@ -15,6 +15,6 @@ public class GetScriptLanguageAction extends ActionType { public static final String NAME = "cluster:admin/script/get"; private GetStoredScriptAction() { - super(NAME, GetStoredScriptResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportDeleteStoredScriptAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportDeleteStoredScriptAction.java index 37821f597a8e5..a5d1fd7e151c5 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportDeleteStoredScriptAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportDeleteStoredScriptAction.java @@ -27,7 +27,7 @@ public class TransportDeleteStoredScriptAction extends AcknowledgedTransportMasterNodeAction { - public static final ActionType TYPE = ActionType.localOnly("cluster:admin/script/delete"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/script/delete"); @Inject public TransportDeleteStoredScriptAction( diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportPutStoredScriptAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportPutStoredScriptAction.java index f526cf37e357b..6a73cd0b91264 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportPutStoredScriptAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportPutStoredScriptAction.java @@ -27,7 +27,7 @@ public class TransportPutStoredScriptAction extends AcknowledgedTransportMasterNodeAction { - public static final ActionType TYPE = ActionType.localOnly("cluster:admin/script/put"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/script/put"); private final ScriptService scriptService; @Inject diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/tasks/TransportPendingClusterTasksAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/tasks/TransportPendingClusterTasksAction.java index a03f0d36f7dad..efca8ab779b20 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/tasks/TransportPendingClusterTasksAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/tasks/TransportPendingClusterTasksAction.java @@ -31,10 +31,7 @@ public class TransportPendingClusterTasksAction extends TransportMasterNodeReadA PendingClusterTasksRequest, PendingClusterTasksResponse> { - public static final ActionType TYPE = new ActionType<>( - "cluster:monitor/task", - PendingClusterTasksResponse::new - ); + public static final ActionType TYPE = new ActionType<>("cluster:monitor/task"); private static final Logger logger = LogManager.getLogger(TransportPendingClusterTasksAction.class); private final ClusterService clusterService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/TransportIndicesAliasesAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/TransportIndicesAliasesAction.java index 367837fa91296..e56be8852e7df 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/TransportIndicesAliasesAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/TransportIndicesAliasesAction.java @@ -59,7 +59,7 @@ public class TransportIndicesAliasesAction extends AcknowledgedTransportMasterNodeAction { public static final String NAME = "indices:admin/aliases"; - public static final ActionType TYPE = ActionType.localOnly(NAME); + public static final ActionType TYPE = new ActionType<>(NAME); private static final Logger logger = LogManager.getLogger(TransportIndicesAliasesAction.class); private final MetadataIndexAliasesService indexAliasesService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesAction.java index a04c7c2c2af60..a033abfd0a107 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesAction.java @@ -9,7 +9,6 @@ package org.elasticsearch.action.admin.indices.alias.get; import org.elasticsearch.action.ActionType; -import org.elasticsearch.common.io.stream.Writeable; public class GetAliasesAction extends ActionType { @@ -17,6 +16,6 @@ public class GetAliasesAction extends ActionType { public static final String NAME = "indices:admin/aliases/get"; private GetAliasesAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/analyze/AnalyzeAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/analyze/AnalyzeAction.java index 6c5a271c3338b..d19aacb306414 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/analyze/AnalyzeAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/analyze/AnalyzeAction.java @@ -40,7 +40,7 @@ public class AnalyzeAction extends ActionType { public static final String NAME = "indices:admin/analyze"; private AnalyzeAction() { - super(NAME, AnalyzeAction.Response::new); + super(NAME); } public static class Fields { diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/analyze/TransportReloadAnalyzersAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/analyze/TransportReloadAnalyzersAction.java index 2930d578a7b2f..3e13b55dbd9d4 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/analyze/TransportReloadAnalyzersAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/analyze/TransportReloadAnalyzersAction.java @@ -51,10 +51,7 @@ public class TransportReloadAnalyzersAction extends TransportBroadcastByNodeActi ReloadAnalyzersResponse, TransportReloadAnalyzersAction.ReloadResult> { - public static final ActionType TYPE = new ActionType<>( - "indices:admin/reload_analyzers", - ReloadAnalyzersResponse::new - ); + public static final ActionType TYPE = new ActionType<>("indices:admin/reload_analyzers"); private static final Logger logger = LogManager.getLogger(TransportReloadAnalyzersAction.class); private final IndicesService indicesService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/cache/clear/ClearIndicesCacheAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/cache/clear/ClearIndicesCacheAction.java index 7c8bb34a13917..74184598c6db2 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/cache/clear/ClearIndicesCacheAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/cache/clear/ClearIndicesCacheAction.java @@ -17,6 +17,6 @@ public class ClearIndicesCacheAction extends ActionType { public static final String NAME = "indices:admin/cache/clear"; private ClearIndicesCacheAction() { - super(NAME, BroadcastResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java index f4a65a2b6490f..5fe1ba459ba93 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java @@ -41,7 +41,7 @@ public class TransportCloseIndexAction extends TransportMasterNodeAction { public static final String NAME = "indices:admin/close"; - public static final ActionType TYPE = new ActionType<>(NAME, CloseIndexResponse::new); + public static final ActionType TYPE = new ActionType<>(NAME); private static final Logger logger = LogManager.getLogger(TransportCloseIndexAction.class); private final MetadataIndexStateService indexStateService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/close/TransportVerifyShardBeforeCloseAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/close/TransportVerifyShardBeforeCloseAction.java index c5b5602a963d4..ac2f437f7225a 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/close/TransportVerifyShardBeforeCloseAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/close/TransportVerifyShardBeforeCloseAction.java @@ -42,7 +42,7 @@ public class TransportVerifyShardBeforeCloseAction extends TransportReplicationA ReplicationResponse> { public static final String NAME = TransportCloseIndexAction.NAME + "[s]"; - public static final ActionType TYPE = new ActionType<>(NAME, ReplicationResponse::new); + public static final ActionType TYPE = new ActionType<>(NAME); private static final Logger logger = LogManager.getLogger(TransportVerifyShardBeforeCloseAction.class); @Inject diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/create/AutoCreateAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/create/AutoCreateAction.java index f7d58e186d2fd..98848f041cea2 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/create/AutoCreateAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/create/AutoCreateAction.java @@ -69,7 +69,7 @@ public final class AutoCreateAction extends ActionType { public static final String NAME = "indices:admin/auto_create"; private AutoCreateAction() { - super(NAME, CreateIndexResponse::new); + super(NAME); } public static final class TransportAction extends TransportMasterNodeAction { diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexAction.java index e22a8484ff381..5560c44f3fcbe 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexAction.java @@ -16,7 +16,7 @@ public class CreateIndexAction extends ActionType { public static final String NAME = "indices:admin/create"; private CreateIndexAction() { - super(NAME, CreateIndexResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/dangling/delete/TransportDeleteDanglingIndexAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/dangling/delete/TransportDeleteDanglingIndexAction.java index 954e42fc0d7ef..95b1410e16565 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/dangling/delete/TransportDeleteDanglingIndexAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/dangling/delete/TransportDeleteDanglingIndexAction.java @@ -49,7 +49,7 @@ * to add the index to the index graveyard. */ public class TransportDeleteDanglingIndexAction extends AcknowledgedTransportMasterNodeAction { - public static final ActionType TYPE = ActionType.localOnly("cluster:admin/indices/dangling/delete"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/indices/dangling/delete"); private static final Logger logger = LogManager.getLogger(TransportDeleteDanglingIndexAction.class); private final Settings settings; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/dangling/find/TransportFindDanglingIndexAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/dangling/find/TransportFindDanglingIndexAction.java index e3178c4b7fc30..c39f757887e53 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/dangling/find/TransportFindDanglingIndexAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/dangling/find/TransportFindDanglingIndexAction.java @@ -35,7 +35,7 @@ public class TransportFindDanglingIndexAction extends TransportNodesAction< NodeFindDanglingIndexRequest, NodeFindDanglingIndexResponse> { - public static final ActionType TYPE = ActionType.localOnly("cluster:admin/indices/dangling/find"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/indices/dangling/find"); private final TransportService transportService; private final DanglingIndicesState danglingIndicesState; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/dangling/import_index/TransportImportDanglingIndexAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/dangling/import_index/TransportImportDanglingIndexAction.java index 59bf71a4387e1..d3957be682cfd 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/dangling/import_index/TransportImportDanglingIndexAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/dangling/import_index/TransportImportDanglingIndexAction.java @@ -39,7 +39,7 @@ * to perform the actual allocation. */ public class TransportImportDanglingIndexAction extends HandledTransportAction { - public static final ActionType TYPE = ActionType.localOnly("cluster:admin/indices/dangling/import"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/indices/dangling/import"); private static final Logger logger = LogManager.getLogger(TransportImportDanglingIndexAction.class); private final LocalAllocateDangledIndices danglingIndexAllocator; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/dangling/list/TransportListDanglingIndicesAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/dangling/list/TransportListDanglingIndicesAction.java index 7baa190e3899d..e347874599ff4 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/dangling/list/TransportListDanglingIndicesAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/dangling/list/TransportListDanglingIndicesAction.java @@ -37,7 +37,7 @@ public class TransportListDanglingIndicesAction extends TransportNodesAction< NodeListDanglingIndicesRequest, NodeListDanglingIndicesResponse> { - public static final ActionType TYPE = ActionType.localOnly("cluster:admin/indices/dangling/list"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/indices/dangling/list"); private final TransportService transportService; private final DanglingIndicesState danglingIndicesState; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/delete/TransportDeleteIndexAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/delete/TransportDeleteIndexAction.java index c980e35c00e44..1eb8612d16da3 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/delete/TransportDeleteIndexAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/delete/TransportDeleteIndexAction.java @@ -37,7 +37,7 @@ */ public class TransportDeleteIndexAction extends AcknowledgedTransportMasterNodeAction { - public static final ActionType TYPE = ActionType.localOnly("indices:admin/delete"); + public static final ActionType TYPE = new ActionType<>("indices:admin/delete"); private static final Logger logger = LogManager.getLogger(TransportDeleteIndexAction.class); private final MetadataDeleteIndexService deleteIndexService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/diskusage/AnalyzeIndexDiskUsageAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/diskusage/AnalyzeIndexDiskUsageAction.java index ee6d7b14f1930..710bf5077b73d 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/diskusage/AnalyzeIndexDiskUsageAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/diskusage/AnalyzeIndexDiskUsageAction.java @@ -15,6 +15,6 @@ public class AnalyzeIndexDiskUsageAction extends ActionType { public static final String NAME = "indices:admin/flush"; private FlushAction() { - super(NAME, BroadcastResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/flush/TransportShardFlushAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/flush/TransportShardFlushAction.java index 29af167679451..74ae53f7ac9de 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/flush/TransportShardFlushAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/flush/TransportShardFlushAction.java @@ -35,7 +35,7 @@ public class TransportShardFlushAction extends TransportReplicationAction { public static final String NAME = FlushAction.NAME + "[s]"; - public static final ActionType TYPE = new ActionType<>(NAME, ReplicationResponse::new); + public static final ActionType TYPE = new ActionType<>(NAME); @Inject public TransportShardFlushAction( diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/forcemerge/ForceMergeAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/forcemerge/ForceMergeAction.java index 1270365cded0d..df6a42a67ae54 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/forcemerge/ForceMergeAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/forcemerge/ForceMergeAction.java @@ -17,6 +17,6 @@ public class ForceMergeAction extends ActionType { public static final String NAME = "indices:admin/forcemerge"; private ForceMergeAction() { - super(NAME, BroadcastResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/get/GetIndexAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/get/GetIndexAction.java index 914bb4e34769c..ea2671eafe01f 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/get/GetIndexAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/get/GetIndexAction.java @@ -10,7 +10,6 @@ import org.elasticsearch.action.ActionType; import org.elasticsearch.action.RemoteClusterActionType; -import org.elasticsearch.common.io.stream.Writeable; public class GetIndexAction extends ActionType { @@ -19,6 +18,6 @@ public class GetIndexAction extends ActionType { public static final RemoteClusterActionType REMOTE_TYPE = new RemoteClusterActionType<>(NAME, GetIndexResponse::new); private GetIndexAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/GetFieldMappingsAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/GetFieldMappingsAction.java index 6b7a80e2d59ca..0245457ac7588 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/GetFieldMappingsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/GetFieldMappingsAction.java @@ -16,7 +16,7 @@ public class GetFieldMappingsAction extends ActionType public static final String NAME = "indices:admin/mappings/fields/get"; private GetFieldMappingsAction() { - super(NAME, GetFieldMappingsResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/GetMappingsAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/GetMappingsAction.java index e96440864fda0..2e5976f8239d5 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/GetMappingsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/GetMappingsAction.java @@ -16,6 +16,6 @@ public class GetMappingsAction extends ActionType { public static final String NAME = "indices:admin/mappings/get"; private GetMappingsAction() { - super(NAME, GetMappingsResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/TransportGetFieldMappingsIndexAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/TransportGetFieldMappingsIndexAction.java index 349391e425212..28c01198f516f 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/TransportGetFieldMappingsIndexAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/TransportGetFieldMappingsIndexAction.java @@ -50,7 +50,7 @@ public class TransportGetFieldMappingsIndexAction extends TransportSingleShardAc GetFieldMappingsResponse> { private static final String ACTION_NAME = GetFieldMappingsAction.NAME + "[index]"; - public static final ActionType TYPE = new ActionType<>(ACTION_NAME, GetFieldMappingsResponse::new); + public static final ActionType TYPE = new ActionType<>(ACTION_NAME); protected final ClusterService clusterService; private final IndicesService indicesService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/put/TransportAutoPutMappingAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/put/TransportAutoPutMappingAction.java index 0921bdcfe11a2..a94b1fce0439f 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/put/TransportAutoPutMappingAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/put/TransportAutoPutMappingAction.java @@ -32,7 +32,7 @@ public class TransportAutoPutMappingAction extends AcknowledgedTransportMasterNodeAction { - public static final ActionType TYPE = ActionType.localOnly("indices:admin/mapping/auto_put"); + public static final ActionType TYPE = new ActionType<>("indices:admin/mapping/auto_put"); private static final Logger logger = LogManager.getLogger(TransportAutoPutMappingAction.class); private final MetadataMappingService metadataMappingService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/put/TransportPutMappingAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/put/TransportPutMappingAction.java index 489ac9a378254..0b21cd8de86fb 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/put/TransportPutMappingAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/put/TransportPutMappingAction.java @@ -45,7 +45,7 @@ */ public class TransportPutMappingAction extends AcknowledgedTransportMasterNodeAction { - public static final ActionType TYPE = ActionType.localOnly("indices:admin/mapping/put"); + public static final ActionType TYPE = new ActionType<>("indices:admin/mapping/put"); private static final Logger logger = LogManager.getLogger(TransportPutMappingAction.class); private final MetadataMappingService metadataMappingService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/open/OpenIndexAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/open/OpenIndexAction.java index 959ce867949c2..8fb772496baf7 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/open/OpenIndexAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/open/OpenIndexAction.java @@ -16,7 +16,7 @@ public class OpenIndexAction extends ActionType { public static final String NAME = "indices:admin/open"; private OpenIndexAction() { - super(NAME, OpenIndexResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/readonly/AddIndexBlockAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/readonly/AddIndexBlockAction.java index 630230437fe91..460be3cf10c1c 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/readonly/AddIndexBlockAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/readonly/AddIndexBlockAction.java @@ -16,6 +16,6 @@ public class AddIndexBlockAction extends ActionType { public static final String NAME = "indices:admin/block/add"; private AddIndexBlockAction() { - super(NAME, AddIndexBlockResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/readonly/TransportVerifyShardIndexBlockAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/readonly/TransportVerifyShardIndexBlockAction.java index 7daf04f41a9fb..ac590d1a4d826 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/readonly/TransportVerifyShardIndexBlockAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/readonly/TransportVerifyShardIndexBlockAction.java @@ -45,7 +45,7 @@ public class TransportVerifyShardIndexBlockAction extends TransportReplicationAc ReplicationResponse> { public static final String NAME = AddIndexBlockAction.NAME + "[s]"; - public static final ActionType TYPE = new ActionType<>(NAME, ReplicationResponse::new); + public static final ActionType TYPE = new ActionType<>(NAME); @Inject public TransportVerifyShardIndexBlockAction( diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/recovery/RecoveryAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/recovery/RecoveryAction.java index 6b3f22703d223..0f1ad96a6ad0f 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/recovery/RecoveryAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/recovery/RecoveryAction.java @@ -19,6 +19,6 @@ public class RecoveryAction extends ActionType { public static final String NAME = "indices:monitor/recovery"; private RecoveryAction() { - super(NAME, RecoveryResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/refresh/RefreshAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/refresh/RefreshAction.java index f094ff75d9c41..d484346e1b8fc 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/refresh/RefreshAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/refresh/RefreshAction.java @@ -17,6 +17,6 @@ public class RefreshAction extends ActionType { public static final String NAME = "indices:admin/refresh"; private RefreshAction() { - super(NAME, BroadcastResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/refresh/TransportShardRefreshAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/refresh/TransportShardRefreshAction.java index f4c72d7e37f3d..b3e6385e7099d 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/refresh/TransportShardRefreshAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/refresh/TransportShardRefreshAction.java @@ -42,7 +42,7 @@ public class TransportShardRefreshAction extends TransportReplicationAction< private static final Logger logger = LogManager.getLogger(TransportShardRefreshAction.class); public static final String NAME = RefreshAction.NAME + "[s]"; - public static final ActionType TYPE = new ActionType<>(NAME, ReplicationResponse::new); + public static final ActionType TYPE = new ActionType<>(NAME); public static final String SOURCE_API = "api"; private final Executor refreshExecutor; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/resolve/ResolveIndexAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/resolve/ResolveIndexAction.java index 142f61866ed1a..aaa4901f74fe7 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/resolve/ResolveIndexAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/resolve/ResolveIndexAction.java @@ -68,7 +68,7 @@ public class ResolveIndexAction extends ActionType public static final RemoteClusterActionType REMOTE_TYPE = new RemoteClusterActionType<>(NAME, Response::new); private ResolveIndexAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } public static class Request extends ActionRequest implements IndicesRequest.Replaceable { diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverAction.java index 8ae13f510184a..84ca69bcde77d 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverAction.java @@ -16,7 +16,7 @@ public class RolloverAction extends ActionType { public static final String NAME = "indices:admin/rollover"; private RolloverAction() { - super(NAME, RolloverResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/segments/IndicesSegmentsAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/segments/IndicesSegmentsAction.java index b170cafae98a8..86df6b6d9a755 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/segments/IndicesSegmentsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/segments/IndicesSegmentsAction.java @@ -16,6 +16,6 @@ public class IndicesSegmentsAction extends ActionType { public static final String NAME = "indices:monitor/segments"; private IndicesSegmentsAction() { - super(NAME, IndicesSegmentResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/settings/get/GetSettingsAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/settings/get/GetSettingsAction.java index 4fe42fff45011..4522519952ea8 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/settings/get/GetSettingsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/settings/get/GetSettingsAction.java @@ -16,6 +16,6 @@ public class GetSettingsAction extends ActionType { public static final String NAME = "indices:monitor/settings/get"; public GetSettingsAction() { - super(NAME, GetSettingsResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/settings/put/TransportUpdateSettingsAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/settings/put/TransportUpdateSettingsAction.java index 3d1a8dad9d1bc..164c403d1b516 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/settings/put/TransportUpdateSettingsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/settings/put/TransportUpdateSettingsAction.java @@ -45,7 +45,7 @@ public class TransportUpdateSettingsAction extends AcknowledgedTransportMasterNodeAction { - public static final ActionType TYPE = ActionType.localOnly("indices:admin/settings/update"); + public static final ActionType TYPE = new ActionType<>("indices:admin/settings/update"); private static final Logger logger = LogManager.getLogger(TransportUpdateSettingsAction.class); private final MetadataUpdateSettingsService updateSettingsService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/shards/TransportIndicesShardStoresAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/shards/TransportIndicesShardStoresAction.java index 7d091d8278ab7..4b1c5b3f58dd5 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/shards/TransportIndicesShardStoresAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/shards/TransportIndicesShardStoresAction.java @@ -63,7 +63,7 @@ public class TransportIndicesShardStoresAction extends TransportMasterNodeReadAc IndicesShardStoresRequest, IndicesShardStoresResponse> { - public static final ActionType TYPE = ActionType.localOnly("indices:monitor/shard_stores"); + public static final ActionType TYPE = new ActionType<>("indices:monitor/shard_stores"); private static final Logger logger = LogManager.getLogger(TransportIndicesShardStoresAction.class); diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/shrink/ResizeAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/shrink/ResizeAction.java index aa838e473bd29..e89ccac18ff2f 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/shrink/ResizeAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/shrink/ResizeAction.java @@ -17,7 +17,7 @@ public class ResizeAction extends ActionType { public static final String NAME = "indices:admin/resize"; private ResizeAction() { - super(NAME, CreateIndexResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/shrink/ShrinkAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/shrink/ShrinkAction.java index 7df58990b69ed..129c07b64fd4d 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/shrink/ShrinkAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/shrink/ShrinkAction.java @@ -17,7 +17,7 @@ public class ShrinkAction extends ActionType { public static final String NAME = "indices:admin/shrink"; private ShrinkAction() { - super(NAME, CreateIndexResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/stats/FieldUsageStatsAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/stats/FieldUsageStatsAction.java index 825b66f63d812..e7d55aba26605 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/stats/FieldUsageStatsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/stats/FieldUsageStatsAction.java @@ -16,6 +16,6 @@ public class FieldUsageStatsAction extends ActionType { public static final String NAME = "indices:monitor/field_usage_stats"; private FieldUsageStatsAction() { - super(NAME, FieldUsageStatsResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/stats/IndicesStatsAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/stats/IndicesStatsAction.java index 8c22b77aab23a..08ed9df5d2455 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/stats/IndicesStatsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/stats/IndicesStatsAction.java @@ -10,7 +10,6 @@ import org.elasticsearch.action.ActionType; import org.elasticsearch.action.RemoteClusterActionType; -import org.elasticsearch.common.io.stream.Writeable; public class IndicesStatsAction extends ActionType { @@ -22,6 +21,6 @@ public class IndicesStatsAction extends ActionType { ); private IndicesStatsAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/template/delete/TransportDeleteComponentTemplateAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/template/delete/TransportDeleteComponentTemplateAction.java index 9b6f0ad9a66c1..593162305f2d0 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/template/delete/TransportDeleteComponentTemplateAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/template/delete/TransportDeleteComponentTemplateAction.java @@ -43,7 +43,7 @@ public class TransportDeleteComponentTemplateAction extends AcknowledgedTransportMasterNodeAction< TransportDeleteComponentTemplateAction.Request> { - public static final ActionType TYPE = ActionType.localOnly("cluster:admin/component_template/delete"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/component_template/delete"); private final MetadataIndexTemplateService indexTemplateService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/template/delete/TransportDeleteComposableIndexTemplateAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/template/delete/TransportDeleteComposableIndexTemplateAction.java index 5eada4dd6ace9..f884c8404d0f2 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/template/delete/TransportDeleteComposableIndexTemplateAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/template/delete/TransportDeleteComposableIndexTemplateAction.java @@ -43,7 +43,7 @@ public class TransportDeleteComposableIndexTemplateAction extends AcknowledgedTransportMasterNodeAction< TransportDeleteComposableIndexTemplateAction.Request> { - public static final ActionType TYPE = ActionType.localOnly("indices:admin/index_template/delete"); + public static final ActionType TYPE = new ActionType<>("indices:admin/index_template/delete"); private final MetadataIndexTemplateService indexTemplateService; @Inject diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/template/delete/TransportDeleteIndexTemplateAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/template/delete/TransportDeleteIndexTemplateAction.java index 066d0999dd81a..0a7781bf044dd 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/template/delete/TransportDeleteIndexTemplateAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/template/delete/TransportDeleteIndexTemplateAction.java @@ -31,7 +31,7 @@ */ public class TransportDeleteIndexTemplateAction extends AcknowledgedTransportMasterNodeAction { - public static final ActionType TYPE = ActionType.localOnly("indices:admin/template/delete"); + public static final ActionType TYPE = new ActionType<>("indices:admin/template/delete"); private static final Logger logger = LogManager.getLogger(TransportDeleteIndexTemplateAction.class); private final MetadataIndexTemplateService indexTemplateService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/template/get/GetComponentTemplateAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/template/get/GetComponentTemplateAction.java index 1e0a36cfc1a99..7d2dad80bf35a 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/template/get/GetComponentTemplateAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/template/get/GetComponentTemplateAction.java @@ -35,7 +35,7 @@ public class GetComponentTemplateAction extends ActionType { diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/template/put/PutComponentTemplateAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/template/put/PutComponentTemplateAction.java index 6d7302e127afe..56e7079ec38ba 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/template/put/PutComponentTemplateAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/template/put/PutComponentTemplateAction.java @@ -31,7 +31,7 @@ public class PutComponentTemplateAction extends ActionType public static final String NAME = "cluster:admin/component_template/put"; private PutComponentTemplateAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } /** diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/template/put/TransportPutComposableIndexTemplateAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/template/put/TransportPutComposableIndexTemplateAction.java index 9155eac703632..8d259083a1352 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/template/put/TransportPutComposableIndexTemplateAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/template/put/TransportPutComposableIndexTemplateAction.java @@ -52,7 +52,7 @@ public class TransportPutComposableIndexTemplateAction extends AcknowledgedTransportMasterNodeAction< TransportPutComposableIndexTemplateAction.Request> { - public static final ActionType TYPE = ActionType.localOnly("indices:admin/index_template/put"); + public static final ActionType TYPE = new ActionType<>("indices:admin/index_template/put"); private final MetadataIndexTemplateService indexTemplateService; @Inject diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/template/put/TransportPutIndexTemplateAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/template/put/TransportPutIndexTemplateAction.java index d1d701e63675f..c2b4e5136e556 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/template/put/TransportPutIndexTemplateAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/template/put/TransportPutIndexTemplateAction.java @@ -37,7 +37,7 @@ */ public class TransportPutIndexTemplateAction extends AcknowledgedTransportMasterNodeAction { - public static final ActionType TYPE = ActionType.localOnly("indices:admin/template/put"); + public static final ActionType TYPE = new ActionType<>("indices:admin/template/put"); private static final Logger logger = LogManager.getLogger(TransportPutIndexTemplateAction.class); private final MetadataIndexTemplateService indexTemplateService; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/validate/query/ValidateQueryAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/validate/query/ValidateQueryAction.java index 23757b120a80a..323be06664f4c 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/validate/query/ValidateQueryAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/validate/query/ValidateQueryAction.java @@ -16,6 +16,6 @@ public class ValidateQueryAction extends ActionType { public static final String NAME = "indices:admin/validate/query"; private ValidateQueryAction() { - super(NAME, ValidateQueryResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/bulk/BulkAction.java b/server/src/main/java/org/elasticsearch/action/bulk/BulkAction.java index 70b010b6ca88d..cf977ff51f39d 100644 --- a/server/src/main/java/org/elasticsearch/action/bulk/BulkAction.java +++ b/server/src/main/java/org/elasticsearch/action/bulk/BulkAction.java @@ -22,7 +22,7 @@ public class BulkAction extends ActionType { ); private BulkAction() { - super(NAME, BulkResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/bulk/SimulateBulkAction.java b/server/src/main/java/org/elasticsearch/action/bulk/SimulateBulkAction.java index a799c60fe7b38..089869395c997 100644 --- a/server/src/main/java/org/elasticsearch/action/bulk/SimulateBulkAction.java +++ b/server/src/main/java/org/elasticsearch/action/bulk/SimulateBulkAction.java @@ -16,6 +16,6 @@ public class SimulateBulkAction extends ActionType { public static final String NAME = "indices:data/write/simulate/bulk"; private SimulateBulkAction() { - super(NAME, BulkResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/bulk/TransportShardBulkAction.java b/server/src/main/java/org/elasticsearch/action/bulk/TransportShardBulkAction.java index e6d5bdcc46696..ee9126622efc9 100644 --- a/server/src/main/java/org/elasticsearch/action/bulk/TransportShardBulkAction.java +++ b/server/src/main/java/org/elasticsearch/action/bulk/TransportShardBulkAction.java @@ -76,7 +76,7 @@ public class TransportShardBulkAction extends TransportWriteAction { public static final String ACTION_NAME = BulkAction.NAME + "[s]"; - public static final ActionType TYPE = new ActionType<>(ACTION_NAME, BulkShardResponse::new); + public static final ActionType TYPE = new ActionType<>(ACTION_NAME); private static final Logger logger = LogManager.getLogger(TransportShardBulkAction.class); diff --git a/server/src/main/java/org/elasticsearch/action/datastreams/CreateDataStreamAction.java b/server/src/main/java/org/elasticsearch/action/datastreams/CreateDataStreamAction.java index 4ecb092f34d4b..f9e559fa16ec7 100644 --- a/server/src/main/java/org/elasticsearch/action/datastreams/CreateDataStreamAction.java +++ b/server/src/main/java/org/elasticsearch/action/datastreams/CreateDataStreamAction.java @@ -27,7 +27,7 @@ public class CreateDataStreamAction extends ActionType { public static final String NAME = "indices:admin/data_stream/create"; private CreateDataStreamAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest implements IndicesRequest { diff --git a/server/src/main/java/org/elasticsearch/action/datastreams/DataStreamsStatsAction.java b/server/src/main/java/org/elasticsearch/action/datastreams/DataStreamsStatsAction.java index 4457fc9e9a0f4..9a4eaf9a78e9b 100644 --- a/server/src/main/java/org/elasticsearch/action/datastreams/DataStreamsStatsAction.java +++ b/server/src/main/java/org/elasticsearch/action/datastreams/DataStreamsStatsAction.java @@ -32,7 +32,7 @@ public class DataStreamsStatsAction extends ActionType { diff --git a/server/src/main/java/org/elasticsearch/action/datastreams/DeleteDataStreamAction.java b/server/src/main/java/org/elasticsearch/action/datastreams/DeleteDataStreamAction.java index e23accd351a26..b68a7d3fcd159 100644 --- a/server/src/main/java/org/elasticsearch/action/datastreams/DeleteDataStreamAction.java +++ b/server/src/main/java/org/elasticsearch/action/datastreams/DeleteDataStreamAction.java @@ -30,7 +30,7 @@ public class DeleteDataStreamAction extends ActionType { public static final String NAME = "indices:admin/data_stream/delete"; private DeleteDataStreamAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends MasterNodeRequest implements IndicesRequest.Replaceable { diff --git a/server/src/main/java/org/elasticsearch/action/datastreams/GetDataStreamAction.java b/server/src/main/java/org/elasticsearch/action/datastreams/GetDataStreamAction.java index f591cc22d19a8..1590556253b21 100644 --- a/server/src/main/java/org/elasticsearch/action/datastreams/GetDataStreamAction.java +++ b/server/src/main/java/org/elasticsearch/action/datastreams/GetDataStreamAction.java @@ -44,7 +44,7 @@ public class GetDataStreamAction extends ActionType implements IndicesRequest.Replaceable { diff --git a/server/src/main/java/org/elasticsearch/action/datastreams/MigrateToDataStreamAction.java b/server/src/main/java/org/elasticsearch/action/datastreams/MigrateToDataStreamAction.java index 0f69a68bbfbe8..3a834273e84cf 100644 --- a/server/src/main/java/org/elasticsearch/action/datastreams/MigrateToDataStreamAction.java +++ b/server/src/main/java/org/elasticsearch/action/datastreams/MigrateToDataStreamAction.java @@ -27,7 +27,7 @@ public class MigrateToDataStreamAction extends ActionType public static final String NAME = "indices:admin/data_stream/migrate"; private MigrateToDataStreamAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest implements IndicesRequest { diff --git a/server/src/main/java/org/elasticsearch/action/datastreams/ModifyDataStreamsAction.java b/server/src/main/java/org/elasticsearch/action/datastreams/ModifyDataStreamsAction.java index d2a04305cb2ba..308b8ccfd5064 100644 --- a/server/src/main/java/org/elasticsearch/action/datastreams/ModifyDataStreamsAction.java +++ b/server/src/main/java/org/elasticsearch/action/datastreams/ModifyDataStreamsAction.java @@ -36,7 +36,7 @@ public class ModifyDataStreamsAction extends ActionType { public static final String NAME = "indices:admin/data_stream/modify"; private ModifyDataStreamsAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static final class Request extends AcknowledgedRequest implements IndicesRequest, ToXContentObject { diff --git a/server/src/main/java/org/elasticsearch/action/datastreams/PromoteDataStreamAction.java b/server/src/main/java/org/elasticsearch/action/datastreams/PromoteDataStreamAction.java index f58e9497949bf..3b3e644272cbc 100644 --- a/server/src/main/java/org/elasticsearch/action/datastreams/PromoteDataStreamAction.java +++ b/server/src/main/java/org/elasticsearch/action/datastreams/PromoteDataStreamAction.java @@ -27,7 +27,7 @@ public class PromoteDataStreamAction extends ActionType { public static final String NAME = "indices:admin/data_stream/promote"; private PromoteDataStreamAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends MasterNodeRequest implements IndicesRequest { diff --git a/server/src/main/java/org/elasticsearch/action/delete/TransportDeleteAction.java b/server/src/main/java/org/elasticsearch/action/delete/TransportDeleteAction.java index 6c275d994a4ed..6abe033637c56 100644 --- a/server/src/main/java/org/elasticsearch/action/delete/TransportDeleteAction.java +++ b/server/src/main/java/org/elasticsearch/action/delete/TransportDeleteAction.java @@ -24,7 +24,7 @@ public class TransportDeleteAction extends TransportSingleItemBulkWriteAction { public static final String NAME = "indices:data/write/delete"; - public static final ActionType TYPE = new ActionType<>(NAME, DeleteResponse::new); + public static final ActionType TYPE = new ActionType<>(NAME); @Inject public TransportDeleteAction(TransportService transportService, ActionFilters actionFilters, TransportBulkAction bulkAction) { diff --git a/server/src/main/java/org/elasticsearch/action/downsample/DownsampleAction.java b/server/src/main/java/org/elasticsearch/action/downsample/DownsampleAction.java index 5875ab5089d92..08d315fe39ce5 100644 --- a/server/src/main/java/org/elasticsearch/action/downsample/DownsampleAction.java +++ b/server/src/main/java/org/elasticsearch/action/downsample/DownsampleAction.java @@ -35,7 +35,7 @@ public class DownsampleAction extends ActionType { public static final TimeValue DEFAULT_WAIT_TIMEOUT = new TimeValue(1, TimeUnit.DAYS); private DownsampleAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends MasterNodeRequest implements IndicesRequest, ToXContentObject { diff --git a/server/src/main/java/org/elasticsearch/action/explain/TransportExplainAction.java b/server/src/main/java/org/elasticsearch/action/explain/TransportExplainAction.java index d889f8fac8113..d2d7a945520c1 100644 --- a/server/src/main/java/org/elasticsearch/action/explain/TransportExplainAction.java +++ b/server/src/main/java/org/elasticsearch/action/explain/TransportExplainAction.java @@ -49,7 +49,7 @@ // TODO: AggregatedDfs. Currently the idf can be different then when executing a normal search with explain. public class TransportExplainAction extends TransportSingleShardAction { - public static final ActionType TYPE = new ActionType<>("indices:data/read/explain", ExplainResponse::new); + public static final ActionType TYPE = new ActionType<>("indices:data/read/explain"); private final SearchService searchService; @Inject diff --git a/server/src/main/java/org/elasticsearch/action/fieldcaps/TransportFieldCapabilitiesAction.java b/server/src/main/java/org/elasticsearch/action/fieldcaps/TransportFieldCapabilitiesAction.java index 79de0259459db..fa396b1ad18bf 100644 --- a/server/src/main/java/org/elasticsearch/action/fieldcaps/TransportFieldCapabilitiesAction.java +++ b/server/src/main/java/org/elasticsearch/action/fieldcaps/TransportFieldCapabilitiesAction.java @@ -65,7 +65,7 @@ public class TransportFieldCapabilitiesAction extends HandledTransportAction { public static final String NAME = "indices:data/read/field_caps"; - public static final ActionType TYPE = ActionType.localOnly(NAME); + public static final ActionType TYPE = new ActionType<>(NAME); public static final RemoteClusterActionType REMOTE_TYPE = new RemoteClusterActionType<>( NAME, FieldCapabilitiesResponse::new diff --git a/server/src/main/java/org/elasticsearch/action/get/TransportGetAction.java b/server/src/main/java/org/elasticsearch/action/get/TransportGetAction.java index 6440304360bf3..0cc1d51c4d97e 100644 --- a/server/src/main/java/org/elasticsearch/action/get/TransportGetAction.java +++ b/server/src/main/java/org/elasticsearch/action/get/TransportGetAction.java @@ -47,7 +47,7 @@ */ public class TransportGetAction extends TransportSingleShardAction { - public static final ActionType TYPE = new ActionType<>("indices:data/read/get", GetResponse::new); + public static final ActionType TYPE = new ActionType<>("indices:data/read/get"); private static final Logger logger = LogManager.getLogger(TransportGetAction.class); private final IndicesService indicesService; diff --git a/server/src/main/java/org/elasticsearch/action/get/TransportMultiGetAction.java b/server/src/main/java/org/elasticsearch/action/get/TransportMultiGetAction.java index 7db644415dbc2..fcb10f3deef60 100644 --- a/server/src/main/java/org/elasticsearch/action/get/TransportMultiGetAction.java +++ b/server/src/main/java/org/elasticsearch/action/get/TransportMultiGetAction.java @@ -35,7 +35,7 @@ public class TransportMultiGetAction extends HandledTransportAction { public static final String NAME = "indices:data/read/mget"; - public static final ActionType TYPE = new ActionType<>(NAME, MultiGetResponse::new); + public static final ActionType TYPE = new ActionType<>(NAME); private final ClusterService clusterService; private final NodeClient client; private final IndexNameExpressionResolver indexNameExpressionResolver; diff --git a/server/src/main/java/org/elasticsearch/action/get/TransportShardMultiGetAction.java b/server/src/main/java/org/elasticsearch/action/get/TransportShardMultiGetAction.java index a05bbf1bfd9d3..6dfd706b3268f 100644 --- a/server/src/main/java/org/elasticsearch/action/get/TransportShardMultiGetAction.java +++ b/server/src/main/java/org/elasticsearch/action/get/TransportShardMultiGetAction.java @@ -48,7 +48,7 @@ public class TransportShardMultiGetAction extends TransportSingleShardAction { private static final String ACTION_NAME = TransportMultiGetAction.NAME + "[shard]"; - public static final ActionType TYPE = new ActionType<>(ACTION_NAME, MultiGetShardResponse::new); + public static final ActionType TYPE = new ActionType<>(ACTION_NAME); private static final Logger logger = LogManager.getLogger(TransportShardMultiGetAction.class); private final IndicesService indicesService; diff --git a/server/src/main/java/org/elasticsearch/action/index/TransportIndexAction.java b/server/src/main/java/org/elasticsearch/action/index/TransportIndexAction.java index 5e91498244dd0..cc61f40d303d3 100644 --- a/server/src/main/java/org/elasticsearch/action/index/TransportIndexAction.java +++ b/server/src/main/java/org/elasticsearch/action/index/TransportIndexAction.java @@ -32,10 +32,7 @@ public class TransportIndexAction extends TransportSingleItemBulkWriteAction { public static final String NAME = "indices:data/write/index"; - public static final ActionType TYPE = new ActionType<>(NAME, in -> { - assert false : "Might not be an IndexResponse!"; - return new IndexResponse(in); - }); + public static final ActionType TYPE = new ActionType<>(NAME); @Inject public TransportIndexAction(ActionFilters actionFilters, TransportService transportService, TransportBulkAction bulkAction) { diff --git a/server/src/main/java/org/elasticsearch/action/ingest/DeletePipelineTransportAction.java b/server/src/main/java/org/elasticsearch/action/ingest/DeletePipelineTransportAction.java index 6878096e38614..a8eef9f94b884 100644 --- a/server/src/main/java/org/elasticsearch/action/ingest/DeletePipelineTransportAction.java +++ b/server/src/main/java/org/elasticsearch/action/ingest/DeletePipelineTransportAction.java @@ -29,7 +29,7 @@ public class DeletePipelineTransportAction extends AcknowledgedTransportMasterNodeAction { - public static final ActionType TYPE = ActionType.localOnly("cluster:admin/ingest/pipeline/delete"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/ingest/pipeline/delete"); private final IngestService ingestService; @Inject diff --git a/server/src/main/java/org/elasticsearch/action/ingest/GetPipelineAction.java b/server/src/main/java/org/elasticsearch/action/ingest/GetPipelineAction.java index 39a0417541ef7..48cdf5dbd92e6 100644 --- a/server/src/main/java/org/elasticsearch/action/ingest/GetPipelineAction.java +++ b/server/src/main/java/org/elasticsearch/action/ingest/GetPipelineAction.java @@ -16,6 +16,6 @@ public class GetPipelineAction extends ActionType { public static final String NAME = "cluster:admin/ingest/pipeline/get"; public GetPipelineAction() { - super(NAME, GetPipelineResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/ingest/PutPipelineTransportAction.java b/server/src/main/java/org/elasticsearch/action/ingest/PutPipelineTransportAction.java index 5233961cdda7b..5a97596aa00ff 100644 --- a/server/src/main/java/org/elasticsearch/action/ingest/PutPipelineTransportAction.java +++ b/server/src/main/java/org/elasticsearch/action/ingest/PutPipelineTransportAction.java @@ -34,7 +34,7 @@ import static org.elasticsearch.ingest.IngestService.INGEST_ORIGIN; public class PutPipelineTransportAction extends AcknowledgedTransportMasterNodeAction { - public static final ActionType TYPE = ActionType.localOnly("cluster:admin/ingest/pipeline/put"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/ingest/pipeline/put"); private final IngestService ingestService; private final OriginSettingClient client; diff --git a/server/src/main/java/org/elasticsearch/action/ingest/SimulatePipelineAction.java b/server/src/main/java/org/elasticsearch/action/ingest/SimulatePipelineAction.java index 9d2ee21560907..d62bbbacd13ce 100644 --- a/server/src/main/java/org/elasticsearch/action/ingest/SimulatePipelineAction.java +++ b/server/src/main/java/org/elasticsearch/action/ingest/SimulatePipelineAction.java @@ -16,6 +16,6 @@ public class SimulatePipelineAction extends ActionType public static final String NAME = "cluster:admin/ingest/pipeline/simulate"; public SimulatePipelineAction() { - super(NAME, SimulatePipelineResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/search/TransportClearScrollAction.java b/server/src/main/java/org/elasticsearch/action/search/TransportClearScrollAction.java index e1a6bb6c42b2e..65284d5d55585 100644 --- a/server/src/main/java/org/elasticsearch/action/search/TransportClearScrollAction.java +++ b/server/src/main/java/org/elasticsearch/action/search/TransportClearScrollAction.java @@ -22,7 +22,7 @@ public class TransportClearScrollAction extends HandledTransportAction TYPE = new ActionType<>(NAME, ClearScrollResponse::new); + public static final ActionType TYPE = new ActionType<>(NAME); private final ClusterService clusterService; private final SearchTransportService searchTransportService; diff --git a/server/src/main/java/org/elasticsearch/action/search/TransportClosePointInTimeAction.java b/server/src/main/java/org/elasticsearch/action/search/TransportClosePointInTimeAction.java index 338e63d6af2a6..f507b2e1136a8 100644 --- a/server/src/main/java/org/elasticsearch/action/search/TransportClosePointInTimeAction.java +++ b/server/src/main/java/org/elasticsearch/action/search/TransportClosePointInTimeAction.java @@ -23,10 +23,7 @@ public class TransportClosePointInTimeAction extends HandledTransportAction { - public static final ActionType TYPE = new ActionType<>( - "indices:data/read/close_point_in_time", - ClosePointInTimeResponse::new - ); + public static final ActionType TYPE = new ActionType<>("indices:data/read/close_point_in_time"); private final ClusterService clusterService; private final SearchTransportService searchTransportService; private final NamedWriteableRegistry namedWriteableRegistry; diff --git a/server/src/main/java/org/elasticsearch/action/search/TransportMultiSearchAction.java b/server/src/main/java/org/elasticsearch/action/search/TransportMultiSearchAction.java index c81f3c3dc24c6..a2c41042871ba 100644 --- a/server/src/main/java/org/elasticsearch/action/search/TransportMultiSearchAction.java +++ b/server/src/main/java/org/elasticsearch/action/search/TransportMultiSearchAction.java @@ -36,7 +36,7 @@ public class TransportMultiSearchAction extends HandledTransportAction { public static final String NAME = "indices:data/read/msearch"; - public static final ActionType TYPE = new ActionType<>(NAME, MultiSearchResponse::new); + public static final ActionType TYPE = new ActionType<>(NAME); private static final Logger logger = LogManager.getLogger(TransportMultiSearchAction.class); private final int allocatedProcessors; private final ThreadPool threadPool; diff --git a/server/src/main/java/org/elasticsearch/action/search/TransportOpenPointInTimeAction.java b/server/src/main/java/org/elasticsearch/action/search/TransportOpenPointInTimeAction.java index ca3bca7c3969f..91784ba331857 100644 --- a/server/src/main/java/org/elasticsearch/action/search/TransportOpenPointInTimeAction.java +++ b/server/src/main/java/org/elasticsearch/action/search/TransportOpenPointInTimeAction.java @@ -55,10 +55,7 @@ public class TransportOpenPointInTimeAction extends HandledTransportAction TYPE = new ActionType<>( - "indices:data/read/open_point_in_time", - OpenPointInTimeResponse::new - ); + public static final ActionType TYPE = new ActionType<>("indices:data/read/open_point_in_time"); private final TransportSearchAction transportSearchAction; private final SearchTransportService searchTransportService; diff --git a/server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java b/server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java index 1c953a667d5aa..d391bc198725b 100644 --- a/server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java +++ b/server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java @@ -112,7 +112,7 @@ public class TransportSearchAction extends HandledTransportAction { public static final String NAME = "indices:data/read/search"; - public static final ActionType TYPE = ActionType.localOnly(NAME); + public static final ActionType TYPE = new ActionType<>(NAME); public static final RemoteClusterActionType REMOTE_TYPE = new RemoteClusterActionType<>(NAME, SearchResponse::new); private static final Logger logger = LogManager.getLogger(TransportSearchAction.class); private static final DeprecationLogger DEPRECATION_LOGGER = DeprecationLogger.getLogger(TransportSearchAction.class); diff --git a/server/src/main/java/org/elasticsearch/action/search/TransportSearchScrollAction.java b/server/src/main/java/org/elasticsearch/action/search/TransportSearchScrollAction.java index 0c442129b5b87..27086366283f9 100644 --- a/server/src/main/java/org/elasticsearch/action/search/TransportSearchScrollAction.java +++ b/server/src/main/java/org/elasticsearch/action/search/TransportSearchScrollAction.java @@ -28,7 +28,7 @@ import static org.elasticsearch.action.search.TransportSearchHelper.parseScrollId; public class TransportSearchScrollAction extends HandledTransportAction { - public static final ActionType TYPE = ActionType.localOnly("indices:data/read/scroll"); + public static final ActionType TYPE = new ActionType<>("indices:data/read/scroll"); public static final RemoteClusterActionType REMOTE_TYPE = new RemoteClusterActionType<>( TYPE.name(), SearchResponse::new diff --git a/server/src/main/java/org/elasticsearch/action/search/TransportSearchShardsAction.java b/server/src/main/java/org/elasticsearch/action/search/TransportSearchShardsAction.java index ed01158aa8a4c..60efb910a5269 100644 --- a/server/src/main/java/org/elasticsearch/action/search/TransportSearchShardsAction.java +++ b/server/src/main/java/org/elasticsearch/action/search/TransportSearchShardsAction.java @@ -45,7 +45,7 @@ public class TransportSearchShardsAction extends HandledTransportAction { public static final String NAME = "indices:admin/search/search_shards"; - public static final ActionType TYPE = ActionType.localOnly(NAME); + public static final ActionType TYPE = new ActionType<>(NAME); public static final RemoteClusterActionType REMOTE_TYPE = new RemoteClusterActionType<>( NAME, SearchShardsResponse::new diff --git a/server/src/main/java/org/elasticsearch/action/support/TransportAction.java b/server/src/main/java/org/elasticsearch/action/support/TransportAction.java index 35f1b645293bd..222941981f05a 100644 --- a/server/src/main/java/org/elasticsearch/action/support/TransportAction.java +++ b/server/src/main/java/org/elasticsearch/action/support/TransportAction.java @@ -14,7 +14,6 @@ import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.ActionResponse; -import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.core.Releasable; import org.elasticsearch.core.Releasables; import org.elasticsearch.tasks.Task; @@ -139,7 +138,7 @@ public void onFailure(Exception e) { /** * A method to use as a placeholder in implementations of {@link TransportAction} which only ever run on the local node, and therefore - * do not need to serialize or deserialize any messages. See also {@link Writeable.Reader#localOnly()}. + * do not need to serialize or deserialize any messages. */ // TODO remove this when https://github.com/elastic/elasticsearch/issues/100111 is resolved public static T localOnly() { diff --git a/server/src/main/java/org/elasticsearch/action/synonyms/AbstractSynonymsPagedResultAction.java b/server/src/main/java/org/elasticsearch/action/synonyms/AbstractSynonymsPagedResultAction.java index ba2ff244d7b21..f1ebafe28be7c 100644 --- a/server/src/main/java/org/elasticsearch/action/synonyms/AbstractSynonymsPagedResultAction.java +++ b/server/src/main/java/org/elasticsearch/action/synonyms/AbstractSynonymsPagedResultAction.java @@ -35,7 +35,7 @@ public abstract class AbstractSynonymsPagedResultAction extends ActionType { public AbstractSynonymsPagedResultAction(String name, Writeable.Reader reader) { - super(name, reader); + super(name); } /** diff --git a/server/src/main/java/org/elasticsearch/action/synonyms/DeleteSynonymRuleAction.java b/server/src/main/java/org/elasticsearch/action/synonyms/DeleteSynonymRuleAction.java index 17e25aea6952f..cc98da3648709 100644 --- a/server/src/main/java/org/elasticsearch/action/synonyms/DeleteSynonymRuleAction.java +++ b/server/src/main/java/org/elasticsearch/action/synonyms/DeleteSynonymRuleAction.java @@ -25,7 +25,7 @@ public class DeleteSynonymRuleAction extends ActionType { public static final String NAME = "cluster:admin/synonym_rules/delete"; public DeleteSynonymRuleAction() { - super(NAME, SynonymUpdateResponse::new); + super(NAME); } public static class Request extends ActionRequest { diff --git a/server/src/main/java/org/elasticsearch/action/synonyms/DeleteSynonymsAction.java b/server/src/main/java/org/elasticsearch/action/synonyms/DeleteSynonymsAction.java index 11e99dab6066b..52bbb40eb52f8 100644 --- a/server/src/main/java/org/elasticsearch/action/synonyms/DeleteSynonymsAction.java +++ b/server/src/main/java/org/elasticsearch/action/synonyms/DeleteSynonymsAction.java @@ -25,7 +25,7 @@ public class DeleteSynonymsAction extends ActionType { public static final String NAME = "cluster:admin/synonyms/delete"; public DeleteSynonymsAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends ActionRequest { diff --git a/server/src/main/java/org/elasticsearch/action/synonyms/GetSynonymRuleAction.java b/server/src/main/java/org/elasticsearch/action/synonyms/GetSynonymRuleAction.java index dee27849adc30..6a1c3e17a70ad 100644 --- a/server/src/main/java/org/elasticsearch/action/synonyms/GetSynonymRuleAction.java +++ b/server/src/main/java/org/elasticsearch/action/synonyms/GetSynonymRuleAction.java @@ -29,7 +29,7 @@ public class GetSynonymRuleAction extends ActionType { public static final String NAME = "cluster:admin/synonym_rules/put"; public PutSynonymRuleAction() { - super(NAME, SynonymUpdateResponse::new); + super(NAME); } public static class Request extends ActionRequest { diff --git a/server/src/main/java/org/elasticsearch/action/synonyms/PutSynonymsAction.java b/server/src/main/java/org/elasticsearch/action/synonyms/PutSynonymsAction.java index 6662d04dd55ab..6bb6f484e54d3 100644 --- a/server/src/main/java/org/elasticsearch/action/synonyms/PutSynonymsAction.java +++ b/server/src/main/java/org/elasticsearch/action/synonyms/PutSynonymsAction.java @@ -36,7 +36,7 @@ public class PutSynonymsAction extends ActionType { public static final String NAME = "cluster:admin/synonyms/put"; public PutSynonymsAction() { - super(NAME, SynonymUpdateResponse::new); + super(NAME); } public static class Request extends ActionRequest { diff --git a/server/src/main/java/org/elasticsearch/action/termvectors/MultiTermVectorsAction.java b/server/src/main/java/org/elasticsearch/action/termvectors/MultiTermVectorsAction.java index b8a62f9f0509b..0f5917cdcb259 100644 --- a/server/src/main/java/org/elasticsearch/action/termvectors/MultiTermVectorsAction.java +++ b/server/src/main/java/org/elasticsearch/action/termvectors/MultiTermVectorsAction.java @@ -16,6 +16,6 @@ public class MultiTermVectorsAction extends ActionType public static final String NAME = "indices:data/read/mtv"; private MultiTermVectorsAction() { - super(NAME, MultiTermVectorsResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/termvectors/TermVectorsAction.java b/server/src/main/java/org/elasticsearch/action/termvectors/TermVectorsAction.java index 4fa2bc84d3ff2..492673c18245a 100644 --- a/server/src/main/java/org/elasticsearch/action/termvectors/TermVectorsAction.java +++ b/server/src/main/java/org/elasticsearch/action/termvectors/TermVectorsAction.java @@ -16,7 +16,7 @@ public class TermVectorsAction extends ActionType { public static final String NAME = "indices:data/read/tv"; private TermVectorsAction() { - super(NAME, TermVectorsResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/action/termvectors/TransportShardMultiTermsVectorAction.java b/server/src/main/java/org/elasticsearch/action/termvectors/TransportShardMultiTermsVectorAction.java index e7de3d7e70cfc..d0277e8ce8c80 100644 --- a/server/src/main/java/org/elasticsearch/action/termvectors/TransportShardMultiTermsVectorAction.java +++ b/server/src/main/java/org/elasticsearch/action/termvectors/TransportShardMultiTermsVectorAction.java @@ -37,7 +37,7 @@ public class TransportShardMultiTermsVectorAction extends TransportSingleShardAc private final IndicesService indicesService; private static final String ACTION_NAME = MultiTermVectorsAction.NAME + "[shard]"; - public static final ActionType TYPE = new ActionType<>(ACTION_NAME, MultiTermVectorsShardResponse::new); + public static final ActionType TYPE = new ActionType<>(ACTION_NAME); @Inject public TransportShardMultiTermsVectorAction( diff --git a/server/src/main/java/org/elasticsearch/action/update/TransportUpdateAction.java b/server/src/main/java/org/elasticsearch/action/update/TransportUpdateAction.java index c9deec8c504a1..5dd1bd17067db 100644 --- a/server/src/main/java/org/elasticsearch/action/update/TransportUpdateAction.java +++ b/server/src/main/java/org/elasticsearch/action/update/TransportUpdateAction.java @@ -60,7 +60,7 @@ public class TransportUpdateAction extends TransportInstanceSingleOperationAction { public static final String NAME = "indices:data/write/update"; - public static final ActionType TYPE = new ActionType<>(NAME, UpdateResponse::new); + public static final ActionType TYPE = new ActionType<>(NAME); private final AutoCreateIndex autoCreateIndex; private final UpdateHelper updateHelper; private final IndicesService indicesService; diff --git a/server/src/main/java/org/elasticsearch/common/io/stream/Writeable.java b/server/src/main/java/org/elasticsearch/common/io/stream/Writeable.java index d3422c1b51a22..5da8c282ad4bc 100644 --- a/server/src/main/java/org/elasticsearch/common/io/stream/Writeable.java +++ b/server/src/main/java/org/elasticsearch/common/io/stream/Writeable.java @@ -8,8 +8,6 @@ package org.elasticsearch.common.io.stream; -import org.elasticsearch.action.support.TransportAction; - import java.io.IOException; /** @@ -27,7 +25,7 @@ public interface Writeable { /** * Reference to a method that can write some object to a {@link StreamOutput}. *

- * By convention this is a method from {@link StreamOutput} itself (e.g., {@link StreamOutput#writeString}). If the value can be + * By convention this is a method from {@link StreamOutput} itself (e.g., {@link StreamOutput#writeString(String)}. If the value can be * {@code null}, then the "optional" variant of methods should be used! *

* Most classes should implement {@link Writeable} and the {@link Writeable#writeTo(StreamOutput)} method should use @@ -75,14 +73,6 @@ interface Reader { * @param in Input to read the value from */ V read(StreamInput in) throws IOException; - - /** - * A {@link Reader} which must never be called, for use in local-only transport actions. See also {@link TransportAction#localOnly}. - */ - // TODO remove this when https://github.com/elastic/elasticsearch/issues/100111 is resolved - static Reader localOnly() { - return in -> TransportAction.localOnly(); - } } } diff --git a/server/src/main/java/org/elasticsearch/gateway/TransportNodesListGatewayStartedShards.java b/server/src/main/java/org/elasticsearch/gateway/TransportNodesListGatewayStartedShards.java index 68a1c54fd9869..39c33eb1684bb 100644 --- a/server/src/main/java/org/elasticsearch/gateway/TransportNodesListGatewayStartedShards.java +++ b/server/src/main/java/org/elasticsearch/gateway/TransportNodesListGatewayStartedShards.java @@ -27,7 +27,6 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.core.Nullable; import org.elasticsearch.env.NodeEnvironment; @@ -63,7 +62,7 @@ public class TransportNodesListGatewayStartedShards extends TransportNodesAction private static final Logger logger = LogManager.getLogger(TransportNodesListGatewayStartedShards.class); public static final String ACTION_NAME = "internal:gateway/local/started_shards"; - public static final ActionType TYPE = new ActionType<>(ACTION_NAME, Writeable.Reader.localOnly()); + public static final ActionType TYPE = new ActionType<>(ACTION_NAME); private final Settings settings; private final NodeEnvironment nodeEnv; diff --git a/server/src/main/java/org/elasticsearch/health/GetHealthAction.java b/server/src/main/java/org/elasticsearch/health/GetHealthAction.java index c1efa58a50c86..eeff060c174da 100644 --- a/server/src/main/java/org/elasticsearch/health/GetHealthAction.java +++ b/server/src/main/java/org/elasticsearch/health/GetHealthAction.java @@ -22,7 +22,6 @@ import org.elasticsearch.common.collect.Iterators; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.xcontent.ChunkedToXContent; import org.elasticsearch.core.Nullable; import org.elasticsearch.health.stats.HealthApiStats; @@ -47,7 +46,7 @@ public class GetHealthAction extends ActionType { public static final String NAME = "cluster:monitor/health_api"; private GetHealthAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } public static class Response extends ActionResponse implements ChunkedToXContent { diff --git a/server/src/main/java/org/elasticsearch/health/node/FetchHealthInfoCacheAction.java b/server/src/main/java/org/elasticsearch/health/node/FetchHealthInfoCacheAction.java index 6433e3028dbfa..f342daa413fd6 100644 --- a/server/src/main/java/org/elasticsearch/health/node/FetchHealthInfoCacheAction.java +++ b/server/src/main/java/org/elasticsearch/health/node/FetchHealthInfoCacheAction.java @@ -89,7 +89,7 @@ public int hashCode() { public static final String NAME = "cluster:monitor/fetch/health/info"; private FetchHealthInfoCacheAction() { - super(NAME, FetchHealthInfoCacheAction.Response::new); + super(NAME); } public static class TransportAction extends TransportHealthNodeAction< diff --git a/server/src/main/java/org/elasticsearch/health/node/UpdateHealthInfoCacheAction.java b/server/src/main/java/org/elasticsearch/health/node/UpdateHealthInfoCacheAction.java index d1961c597bc1e..9567331c678b5 100644 --- a/server/src/main/java/org/elasticsearch/health/node/UpdateHealthInfoCacheAction.java +++ b/server/src/main/java/org/elasticsearch/health/node/UpdateHealthInfoCacheAction.java @@ -140,7 +140,7 @@ public int hashCode() { public static final String NAME = "cluster:monitor/update/health/info"; private UpdateHealthInfoCacheAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class TransportAction extends TransportHealthNodeAction { diff --git a/server/src/main/java/org/elasticsearch/health/stats/HealthApiStatsAction.java b/server/src/main/java/org/elasticsearch/health/stats/HealthApiStatsAction.java index 7ee616ab2f3b9..9833a5368f058 100644 --- a/server/src/main/java/org/elasticsearch/health/stats/HealthApiStatsAction.java +++ b/server/src/main/java/org/elasticsearch/health/stats/HealthApiStatsAction.java @@ -18,7 +18,6 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.metrics.Counters; import org.elasticsearch.core.Nullable; import org.elasticsearch.transport.TransportRequest; @@ -36,7 +35,7 @@ public class HealthApiStatsAction extends ActionType { diff --git a/server/src/main/java/org/elasticsearch/index/reindex/DeleteByQueryAction.java b/server/src/main/java/org/elasticsearch/index/reindex/DeleteByQueryAction.java index b34c4dd3bfb43..c547c9f5902b1 100644 --- a/server/src/main/java/org/elasticsearch/index/reindex/DeleteByQueryAction.java +++ b/server/src/main/java/org/elasticsearch/index/reindex/DeleteByQueryAction.java @@ -16,6 +16,6 @@ public class DeleteByQueryAction extends ActionType { public static final String NAME = "indices:data/write/delete/byquery"; private DeleteByQueryAction() { - super(NAME, BulkByScrollResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/index/reindex/ReindexAction.java b/server/src/main/java/org/elasticsearch/index/reindex/ReindexAction.java index 6ef9214663e5c..33294657a9f3d 100644 --- a/server/src/main/java/org/elasticsearch/index/reindex/ReindexAction.java +++ b/server/src/main/java/org/elasticsearch/index/reindex/ReindexAction.java @@ -15,6 +15,6 @@ public class ReindexAction extends ActionType { public static final String NAME = "indices:data/write/reindex"; private ReindexAction() { - super(NAME, BulkByScrollResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/index/reindex/UpdateByQueryAction.java b/server/src/main/java/org/elasticsearch/index/reindex/UpdateByQueryAction.java index 6ec2e9f9b3232..b1642f369db37 100644 --- a/server/src/main/java/org/elasticsearch/index/reindex/UpdateByQueryAction.java +++ b/server/src/main/java/org/elasticsearch/index/reindex/UpdateByQueryAction.java @@ -15,6 +15,6 @@ public class UpdateByQueryAction extends ActionType { public static final String NAME = "indices:data/write/update/byquery"; private UpdateByQueryAction() { - super(NAME, BulkByScrollResponse::new); + super(NAME); } } diff --git a/server/src/main/java/org/elasticsearch/index/seqno/GlobalCheckpointSyncAction.java b/server/src/main/java/org/elasticsearch/index/seqno/GlobalCheckpointSyncAction.java index 1f8a863fe3e7b..7d3df2c174a83 100644 --- a/server/src/main/java/org/elasticsearch/index/seqno/GlobalCheckpointSyncAction.java +++ b/server/src/main/java/org/elasticsearch/index/seqno/GlobalCheckpointSyncAction.java @@ -39,7 +39,7 @@ public class GlobalCheckpointSyncAction extends TransportReplicationAction< ReplicationResponse> { public static String ACTION_NAME = "indices:admin/seq_no/global_checkpoint_sync"; - public static ActionType TYPE = new ActionType<>(ACTION_NAME, ReplicationResponse::new); + public static ActionType TYPE = new ActionType<>(ACTION_NAME); @Inject public GlobalCheckpointSyncAction( diff --git a/server/src/main/java/org/elasticsearch/index/seqno/RetentionLeaseActions.java b/server/src/main/java/org/elasticsearch/index/seqno/RetentionLeaseActions.java index 9e9926dedd881..49548aa1a6353 100644 --- a/server/src/main/java/org/elasticsearch/index/seqno/RetentionLeaseActions.java +++ b/server/src/main/java/org/elasticsearch/index/seqno/RetentionLeaseActions.java @@ -46,9 +46,9 @@ public class RetentionLeaseActions { public static final long RETAIN_ALL = -1; - public static final ActionType ADD = ActionType.localOnly("indices:admin/seq_no/add_retention_lease"); - public static final ActionType RENEW = ActionType.localOnly("indices:admin/seq_no/renew_retention_lease"); - public static final ActionType REMOVE = ActionType.localOnly("indices:admin/seq_no/remove_retention_lease"); + public static final ActionType ADD = new ActionType<>("indices:admin/seq_no/add_retention_lease"); + public static final ActionType RENEW = new ActionType<>("indices:admin/seq_no/renew_retention_lease"); + public static final ActionType REMOVE = new ActionType<>("indices:admin/seq_no/remove_retention_lease"); public static final RemoteClusterActionType REMOTE_ADD = RemoteClusterActionType.emptyResponse(ADD.name()); public static final RemoteClusterActionType REMOTE_RENEW = RemoteClusterActionType.emptyResponse(RENEW.name()); diff --git a/server/src/main/java/org/elasticsearch/indices/recovery/StatelessPrimaryRelocationAction.java b/server/src/main/java/org/elasticsearch/indices/recovery/StatelessPrimaryRelocationAction.java index 490f19fc9111c..9a0e52e3aa1b8 100644 --- a/server/src/main/java/org/elasticsearch/indices/recovery/StatelessPrimaryRelocationAction.java +++ b/server/src/main/java/org/elasticsearch/indices/recovery/StatelessPrimaryRelocationAction.java @@ -23,7 +23,7 @@ public class StatelessPrimaryRelocationAction { - public static final ActionType TYPE = ActionType.emptyResponse( + public static final ActionType TYPE = new ActionType<>( "internal:index/shard/recovery/stateless_primary_relocation" ); diff --git a/server/src/main/java/org/elasticsearch/indices/store/TransportNodesListShardStoreMetadata.java b/server/src/main/java/org/elasticsearch/indices/store/TransportNodesListShardStoreMetadata.java index ae9f7b730d60b..63ea457cd5a71 100644 --- a/server/src/main/java/org/elasticsearch/indices/store/TransportNodesListShardStoreMetadata.java +++ b/server/src/main/java/org/elasticsearch/indices/store/TransportNodesListShardStoreMetadata.java @@ -64,7 +64,7 @@ public class TransportNodesListShardStoreMetadata extends TransportNodesAction< private static final Logger logger = LogManager.getLogger(TransportNodesListShardStoreMetadata.class); public static final String ACTION_NAME = "internal:cluster/nodes/indices/shard/store"; - public static final ActionType TYPE = new ActionType<>(ACTION_NAME, Writeable.Reader.localOnly()); + public static final ActionType TYPE = new ActionType<>(ACTION_NAME); private final Settings settings; private final IndicesService indicesService; diff --git a/server/src/main/java/org/elasticsearch/persistent/CompletionPersistentTaskAction.java b/server/src/main/java/org/elasticsearch/persistent/CompletionPersistentTaskAction.java index 7af206a12ecc9..44e86e056ef3b 100644 --- a/server/src/main/java/org/elasticsearch/persistent/CompletionPersistentTaskAction.java +++ b/server/src/main/java/org/elasticsearch/persistent/CompletionPersistentTaskAction.java @@ -40,7 +40,7 @@ public class CompletionPersistentTaskAction extends ActionType { diff --git a/server/src/main/java/org/elasticsearch/persistent/RemovePersistentTaskAction.java b/server/src/main/java/org/elasticsearch/persistent/RemovePersistentTaskAction.java index 8e0ee8f87422e..1fbdd03dcc268 100644 --- a/server/src/main/java/org/elasticsearch/persistent/RemovePersistentTaskAction.java +++ b/server/src/main/java/org/elasticsearch/persistent/RemovePersistentTaskAction.java @@ -34,7 +34,7 @@ public class RemovePersistentTaskAction extends ActionType { diff --git a/server/src/main/java/org/elasticsearch/persistent/StartPersistentTaskAction.java b/server/src/main/java/org/elasticsearch/persistent/StartPersistentTaskAction.java index d98abdffaf463..7dbb458354752 100644 --- a/server/src/main/java/org/elasticsearch/persistent/StartPersistentTaskAction.java +++ b/server/src/main/java/org/elasticsearch/persistent/StartPersistentTaskAction.java @@ -40,7 +40,7 @@ public class StartPersistentTaskAction extends ActionType { diff --git a/server/src/main/java/org/elasticsearch/persistent/UpdatePersistentTaskStatusAction.java b/server/src/main/java/org/elasticsearch/persistent/UpdatePersistentTaskStatusAction.java index f961a9fffec27..dcf86f85eb709 100644 --- a/server/src/main/java/org/elasticsearch/persistent/UpdatePersistentTaskStatusAction.java +++ b/server/src/main/java/org/elasticsearch/persistent/UpdatePersistentTaskStatusAction.java @@ -36,7 +36,7 @@ public class UpdatePersistentTaskStatusAction extends ActionType { diff --git a/server/src/test/java/org/elasticsearch/action/ActionModuleTests.java b/server/src/test/java/org/elasticsearch/action/ActionModuleTests.java index 0ab3572eb3cf8..5dd85f9ee35d5 100644 --- a/server/src/test/java/org/elasticsearch/action/ActionModuleTests.java +++ b/server/src/test/java/org/elasticsearch/action/ActionModuleTests.java @@ -92,7 +92,7 @@ protected FakeTransportAction(String actionName, ActionFilters actionFilters, Ta @Override protected void doExecute(Task task, FakeRequest request, ActionListener listener) {} } - final var action = new ActionType<>("fake", null); + final var action = new ActionType<>("fake"); ActionPlugin registersFakeAction = new ActionPlugin() { @Override public List> getActions() { diff --git a/server/src/test/java/org/elasticsearch/action/ActionTests.java b/server/src/test/java/org/elasticsearch/action/ActionTests.java index 4874972314ee6..dd8ab675652fc 100644 --- a/server/src/test/java/org/elasticsearch/action/ActionTests.java +++ b/server/src/test/java/org/elasticsearch/action/ActionTests.java @@ -13,9 +13,9 @@ public class ActionTests extends ESTestCase { public void testEquals() { - final var fakeAction1 = ActionType.localOnly("a"); - final var fakeAction2 = ActionType.localOnly("a"); - final var fakeAction3 = ActionType.localOnly("b"); + final var fakeAction1 = new ActionType<>("a"); + final var fakeAction2 = new ActionType<>("a"); + final var fakeAction3 = new ActionType<>("b"); String s = "Some random other object"; assertEquals(fakeAction1, fakeAction1); assertEquals(fakeAction2, fakeAction2); diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TestTaskPlugin.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TestTaskPlugin.java index 581473eb074be..d714105d9a13a 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TestTaskPlugin.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TestTaskPlugin.java @@ -71,11 +71,8 @@ public class TestTaskPlugin extends Plugin implements ActionPlugin, NetworkPlugi private static final Logger logger = LogManager.getLogger(TestTaskPlugin.class); - public static final ActionType TEST_TASK_ACTION = ActionType.localOnly("cluster:admin/tasks/test"); - public static final ActionType UNBLOCK_TASK_ACTION = new ActionType<>( - "cluster:admin/tasks/testunblock", - UnblockTestTasksResponse::new - ); + public static final ActionType TEST_TASK_ACTION = new ActionType<>("cluster:admin/tasks/test"); + public static final ActionType UNBLOCK_TASK_ACTION = new ActionType<>("cluster:admin/tasks/testunblock"); @Override public List> getActions() { diff --git a/server/src/test/java/org/elasticsearch/action/support/TransportActionFilterChainRefCountingTests.java b/server/src/test/java/org/elasticsearch/action/support/TransportActionFilterChainRefCountingTests.java index 8062bfea5a637..a199003fc59c4 100644 --- a/server/src/test/java/org/elasticsearch/action/support/TransportActionFilterChainRefCountingTests.java +++ b/server/src/test/java/org/elasticsearch/action/support/TransportActionFilterChainRefCountingTests.java @@ -41,7 +41,7 @@ protected Collection> getPlugins() { return List.of(TestPlugin.class); } - static final ActionType TYPE = ActionType.localOnly("test:action"); + static final ActionType TYPE = new ActionType<>("test:action"); public void testAsyncActionFilterRefCounting() { final var countDownLatch = new CountDownLatch(2); diff --git a/server/src/test/java/org/elasticsearch/indices/settings/InternalOrPrivateSettingsPlugin.java b/server/src/test/java/org/elasticsearch/indices/settings/InternalOrPrivateSettingsPlugin.java index 877f8ce4dcb96..cb57096d02744 100644 --- a/server/src/test/java/org/elasticsearch/indices/settings/InternalOrPrivateSettingsPlugin.java +++ b/server/src/test/java/org/elasticsearch/indices/settings/InternalOrPrivateSettingsPlugin.java @@ -61,10 +61,7 @@ public List> getSettings() { public static class UpdateInternalOrPrivateAction { - public static final ActionType INSTANCE = new ActionType<>( - "indices:admin/settings/update-internal-or-private-index", - UpdateInternalOrPrivateAction.Response::new - ); + public static final ActionType INSTANCE = new ActionType<>("indices:admin/settings/update-internal-or-private-index"); public static class Request extends MasterNodeRequest { diff --git a/server/src/test/java/org/elasticsearch/persistent/TestPersistentTasksPlugin.java b/server/src/test/java/org/elasticsearch/persistent/TestPersistentTasksPlugin.java index c131537c1815a..d0ed4f87dbc58 100644 --- a/server/src/test/java/org/elasticsearch/persistent/TestPersistentTasksPlugin.java +++ b/server/src/test/java/org/elasticsearch/persistent/TestPersistentTasksPlugin.java @@ -76,10 +76,7 @@ */ public class TestPersistentTasksPlugin extends Plugin implements ActionPlugin, PersistentTaskPlugin { - public static final ActionType TEST_ACTION = new ActionType<>( - "cluster:admin/persistent/task_test", - TestTasksResponse::new - ); + public static final ActionType TEST_ACTION = new ActionType<>("cluster:admin/persistent/task_test"); @Override public List> getActions() { diff --git a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekTrackerPlugin.java b/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekTrackerPlugin.java index 5ecc9c9deb2bf..bb88aad387a0d 100644 --- a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekTrackerPlugin.java +++ b/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekTrackerPlugin.java @@ -39,7 +39,7 @@ public class SeekTrackerPlugin extends Plugin implements ActionPlugin { Setting.Property.NodeScope ); - public static final ActionType SEEK_STATS_ACTION = ActionType.localOnly("cluster:monitor/seek_stats"); + public static final ActionType SEEK_STATS_ACTION = new ActionType<>("cluster:monitor/seek_stats"); private final SeekStatsService seekStatsService = new SeekStatsService(); private final boolean enabled; diff --git a/test/framework/src/main/java/org/elasticsearch/client/internal/RedirectToLocalClusterRemoteClusterClient.java b/test/framework/src/main/java/org/elasticsearch/client/internal/RedirectToLocalClusterRemoteClusterClient.java index e5f9607ca6efb..3f2569844673c 100644 --- a/test/framework/src/main/java/org/elasticsearch/client/internal/RedirectToLocalClusterRemoteClusterClient.java +++ b/test/framework/src/main/java/org/elasticsearch/client/internal/RedirectToLocalClusterRemoteClusterClient.java @@ -10,6 +10,7 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionRequest; +import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.ActionType; import org.elasticsearch.action.RemoteClusterActionType; import org.elasticsearch.client.internal.node.NodeClient; @@ -33,6 +34,6 @@ public void Request request, ActionListener listener ) { - delegate.execute(ActionType.localOnly(action.name()), request, listener.map(r -> (Response) r)); + delegate.execute(new ActionType(action.name()), request, listener.map(r -> (Response) r)); } } diff --git a/x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/DeleteAutoscalingPolicyAction.java b/x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/DeleteAutoscalingPolicyAction.java index e5e717ec61e07..d3be1816924fb 100644 --- a/x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/DeleteAutoscalingPolicyAction.java +++ b/x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/DeleteAutoscalingPolicyAction.java @@ -22,7 +22,7 @@ public class DeleteAutoscalingPolicyAction extends ActionType { diff --git a/x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/GetAutoscalingCapacityAction.java b/x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/GetAutoscalingCapacityAction.java index b00395f1c0558..4a356f74e03f8 100644 --- a/x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/GetAutoscalingCapacityAction.java +++ b/x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/GetAutoscalingCapacityAction.java @@ -32,7 +32,7 @@ public class GetAutoscalingCapacityAction extends ActionType { diff --git a/x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/GetAutoscalingPolicyAction.java b/x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/GetAutoscalingPolicyAction.java index d01fb600ccbfe..12f1363151bec 100644 --- a/x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/GetAutoscalingPolicyAction.java +++ b/x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/GetAutoscalingPolicyAction.java @@ -26,7 +26,7 @@ public class GetAutoscalingPolicyAction extends ActionType { diff --git a/x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/PutAutoscalingPolicyAction.java b/x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/PutAutoscalingPolicyAction.java index fe0cda75503e0..0de558121fa50 100644 --- a/x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/PutAutoscalingPolicyAction.java +++ b/x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/PutAutoscalingPolicyAction.java @@ -40,7 +40,7 @@ public class PutAutoscalingPolicyAction extends ActionType public static final String NAME = "cluster:admin/autoscaling/put_autoscaling_policy"; private PutAutoscalingPolicyAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/ShardChangesAction.java b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/ShardChangesAction.java index 305fb1252140e..ca6fb5683e540 100644 --- a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/ShardChangesAction.java +++ b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/ShardChangesAction.java @@ -66,7 +66,7 @@ public class ShardChangesAction extends ActionType public static final RemoteClusterActionType REMOTE_TYPE = new RemoteClusterActionType<>(NAME, Response::new); private ShardChangesAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } public static class Request extends SingleShardRequest implements RawIndexingDataTransportRequest { diff --git a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/bulk/BulkShardOperationsAction.java b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/bulk/BulkShardOperationsAction.java index eb0cb95da5dff..71e0b644d1a95 100644 --- a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/bulk/BulkShardOperationsAction.java +++ b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/bulk/BulkShardOperationsAction.java @@ -14,6 +14,6 @@ public class BulkShardOperationsAction extends ActionType ActionResponse.Empty.INSTANCE); + super(name); } abstract static class TransportDeleteCcrRestoreSessionAction extends HandledTransportAction< diff --git a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/repositories/DeleteInternalCcrRepositoryAction.java b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/repositories/DeleteInternalCcrRepositoryAction.java index 2b33e18d83bfb..f8e4cda1501b6 100644 --- a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/repositories/DeleteInternalCcrRepositoryAction.java +++ b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/repositories/DeleteInternalCcrRepositoryAction.java @@ -13,7 +13,6 @@ import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.TransportAction; import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.repositories.RepositoriesService; import org.elasticsearch.tasks.Task; import org.elasticsearch.transport.TransportService; @@ -24,7 +23,7 @@ public class DeleteInternalCcrRepositoryAction extends ActionType { public static final String NAME = "cluster:admin/xpack/license/basic_status"; private GetBasicStatusAction() { - super(NAME, GetBasicStatusResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetLicenseAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetLicenseAction.java index c987374b5bbf8..4125856990a44 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetLicenseAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetLicenseAction.java @@ -14,6 +14,6 @@ public class GetLicenseAction extends ActionType { public static final String NAME = "cluster:monitor/xpack/license/get"; private GetLicenseAction() { - super(NAME, GetLicenseResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetTrialStatusAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetTrialStatusAction.java index 8649fe2506ace..aa5d03b2648e0 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetTrialStatusAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetTrialStatusAction.java @@ -14,6 +14,6 @@ public class GetTrialStatusAction extends ActionType { public static final String NAME = "cluster:admin/xpack/license/trial_status"; private GetTrialStatusAction() { - super(NAME, GetTrialStatusResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/PostStartBasicAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/PostStartBasicAction.java index c7be971ba4bfd..4532a00d95717 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/PostStartBasicAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/PostStartBasicAction.java @@ -14,6 +14,6 @@ public class PostStartBasicAction extends ActionType { public static final String NAME = "cluster:admin/xpack/license/start_basic"; private PostStartBasicAction() { - super(NAME, PostStartBasicResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/PostStartTrialAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/PostStartTrialAction.java index 8e3057b3af1c1..469e69c5798d1 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/PostStartTrialAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/PostStartTrialAction.java @@ -14,6 +14,6 @@ public class PostStartTrialAction extends ActionType { public static final String NAME = "cluster:admin/xpack/license/start_trial"; private PostStartTrialAction() { - super(NAME, PostStartTrialResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/PutLicenseAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/PutLicenseAction.java index f98fa7c566c62..e6da3bc5a3eb1 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/PutLicenseAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/PutLicenseAction.java @@ -15,6 +15,6 @@ public class PutLicenseAction extends ActionType { public static final String NAME = "cluster:admin/xpack/license/put"; private PutLicenseAction() { - super(NAME, PutLicenseResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/TransportDeleteLicenseAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/TransportDeleteLicenseAction.java index fe9e2f4a8f24f..7ac59e1dc327a 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/TransportDeleteLicenseAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/TransportDeleteLicenseAction.java @@ -26,7 +26,7 @@ public class TransportDeleteLicenseAction extends AcknowledgedTransportMasterNodeAction { - public static final ActionType TYPE = ActionType.localOnly("cluster:admin/xpack/license/delete"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/xpack/license/delete"); private final MutableLicenseService licenseService; @Inject diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/TransportGetFeatureUsageAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/TransportGetFeatureUsageAction.java index 6be7e73058363..00023f9c30e70 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/TransportGetFeatureUsageAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/TransportGetFeatureUsageAction.java @@ -25,10 +25,7 @@ public class TransportGetFeatureUsageAction extends HandledTransportAction { - public static final ActionType TYPE = new ActionType<>( - "cluster:admin/xpack/license/feature_usage", - GetFeatureUsageResponse::new - ); + public static final ActionType TYPE = new ActionType<>("cluster:admin/xpack/license/feature_usage"); private final XPackLicenseState licenseState; diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/cluster/action/MigrateToDataTiersAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/cluster/action/MigrateToDataTiersAction.java index 5d973c48ff7bf..fc9af342e31d5 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/cluster/action/MigrateToDataTiersAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/cluster/action/MigrateToDataTiersAction.java @@ -15,7 +15,7 @@ public class MigrateToDataTiersAction extends ActionType { @@ -21,6 +20,6 @@ public class XPackInfoAction extends ActionType { ); public XPackInfoAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/XPackInfoFeatureAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/XPackInfoFeatureAction.java index 859950470f0e3..8b5ce8c7368e1 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/XPackInfoFeatureAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/XPackInfoFeatureAction.java @@ -89,7 +89,7 @@ public class XPackInfoFeatureAction extends ActionType } private XPackInfoFeatureAction(String name) { - super(BASE_NAME + name, XPackInfoFeatureResponse::new); + super(BASE_NAME + name); } @Override diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/XPackUsageAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/XPackUsageAction.java index e70118ca7578f..690adba2533ed 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/XPackUsageAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/XPackUsageAction.java @@ -14,6 +14,6 @@ public class XPackUsageAction extends ActionType { public static final XPackUsageAction INSTANCE = new XPackUsageAction(); public XPackUsageAction() { - super(NAME, XPackUsageResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/XPackUsageFeatureAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/XPackUsageFeatureAction.java index c0e6d96c1569a..fed5e8e15ce9c 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/XPackUsageFeatureAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/XPackUsageFeatureAction.java @@ -87,7 +87,7 @@ public class XPackUsageFeatureAction extends ActionType { - public static final ActionType TYPE = ActionType.localOnly("indices:data/read/async_search/delete"); + public static final ActionType TYPE = new ActionType<>("indices:data/read/async_search/delete"); private final DeleteAsyncResultsService deleteResultsService; private final ClusterService clusterService; private final TransportService transportService; diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/ActivateAutoFollowPatternAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/ActivateAutoFollowPatternAction.java index 1c0204618bd45..300d2844b7a2a 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/ActivateAutoFollowPatternAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/ActivateAutoFollowPatternAction.java @@ -25,7 +25,7 @@ public class ActivateAutoFollowPatternAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/CcrStatsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/CcrStatsAction.java index 225c784ef1431..b6c078134634b 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/CcrStatsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/CcrStatsAction.java @@ -29,7 +29,7 @@ public class CcrStatsAction extends ActionType { public static final CcrStatsAction INSTANCE = new CcrStatsAction(); private CcrStatsAction() { - super(NAME, CcrStatsAction.Response::new); + super(NAME); } public static class Request extends MasterNodeRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/DeleteAutoFollowPatternAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/DeleteAutoFollowPatternAction.java index 44c815ac986db..8e7e9f8605245 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/DeleteAutoFollowPatternAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/DeleteAutoFollowPatternAction.java @@ -24,7 +24,7 @@ public class DeleteAutoFollowPatternAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/FollowInfoAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/FollowInfoAction.java index b6e771e07ac46..c405e4e81ff19 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/FollowInfoAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/FollowInfoAction.java @@ -34,7 +34,7 @@ public class FollowInfoAction extends ActionType { public static final FollowInfoAction INSTANCE = new FollowInfoAction(); private FollowInfoAction() { - super(NAME, FollowInfoAction.Response::new); + super(NAME); } public static class Request extends MasterNodeReadRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/FollowStatsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/FollowStatsAction.java index 1fdee42e7e18e..4dde222245334 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/FollowStatsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/FollowStatsAction.java @@ -42,7 +42,7 @@ public class FollowStatsAction extends ActionType { public static final ForgetFollowerAction INSTANCE = new ForgetFollowerAction(); private ForgetFollowerAction() { - super(NAME, BroadcastResponse::new); + super(NAME); } /** diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/GetAutoFollowPatternAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/GetAutoFollowPatternAction.java index 8a327735052b5..70f4f256c87e2 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/GetAutoFollowPatternAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/GetAutoFollowPatternAction.java @@ -27,7 +27,7 @@ public class GetAutoFollowPatternAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/PauseFollowAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/PauseFollowAction.java index c38cb391d7cc5..7ad8e5881e443 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/PauseFollowAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/PauseFollowAction.java @@ -23,7 +23,7 @@ public class PauseFollowAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ccr/pause_follow"; private PauseFollowAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends MasterNodeRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/PutAutoFollowPatternAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/PutAutoFollowPatternAction.java index 8154067e72b18..92902aa9962ab 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/PutAutoFollowPatternAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/PutAutoFollowPatternAction.java @@ -37,7 +37,7 @@ public class PutAutoFollowPatternAction extends ActionType private static final int MAX_NAME_BYTES = 255; private PutAutoFollowPatternAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/PutFollowAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/PutFollowAction.java index fe5a224f85e00..c2e1048541a47 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/PutFollowAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/PutFollowAction.java @@ -37,7 +37,7 @@ public final class PutFollowAction extends ActionType public static final String NAME = "indices:admin/xpack/ccr/put_follow"; private PutFollowAction() { - super(NAME, PutFollowAction.Response::new); + super(NAME); } public static final class Request extends AcknowledgedRequest implements IndicesRequest, ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/ResumeFollowAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/ResumeFollowAction.java index 0e8c95bde2bba..4cd84733b19e0 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/ResumeFollowAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/ResumeFollowAction.java @@ -29,7 +29,7 @@ public final class ResumeFollowAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ccr/resume_follow"; private ResumeFollowAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends MasterNodeRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/UnfollowAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/UnfollowAction.java index 630496c822050..808df5f8bccb0 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/UnfollowAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/UnfollowAction.java @@ -26,7 +26,7 @@ public class UnfollowAction extends ActionType { public static final String NAME = "indices:admin/xpack/ccr/unfollow"; private UnfollowAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest implements IndicesRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/datatiers/NodesDataTiersUsageTransportAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/datatiers/NodesDataTiersUsageTransportAction.java index 06a3b47d47a65..08a2d5ae4f5b4 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/datatiers/NodesDataTiersUsageTransportAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/datatiers/NodesDataTiersUsageTransportAction.java @@ -55,7 +55,7 @@ public class NodesDataTiersUsageTransportAction extends TransportNodesAction< NodesDataTiersUsageTransportAction.NodeRequest, NodeDataTiersUsage> { - public static final ActionType TYPE = ActionType.localOnly("cluster:monitor/nodes/data_tier_usage"); + public static final ActionType TYPE = new ActionType<>("cluster:monitor/nodes/data_tier_usage"); public static final NodeFeature LOCALLY_PRECALCULATED_STATS_FEATURE = new NodeFeature("usage.data_tiers.precalculate_stats"); private static final CommonStatsFlags STATS_FLAGS = new CommonStatsFlags().clear() diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/downsample/DownsampleIndexerAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/downsample/DownsampleIndexerAction.java index dcaf5057e9d43..708a746d61414 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/downsample/DownsampleIndexerAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/downsample/DownsampleIndexerAction.java @@ -37,7 +37,7 @@ public class DownsampleIndexerAction extends ActionType implements IndicesRequest, ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/DeleteEnrichPolicyAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/DeleteEnrichPolicyAction.java index f7571c115ec38..e444232291101 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/DeleteEnrichPolicyAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/DeleteEnrichPolicyAction.java @@ -22,7 +22,7 @@ public class DeleteEnrichPolicyAction extends ActionType { public static final String NAME = "cluster:admin/xpack/enrich/delete"; private DeleteEnrichPolicyAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends MasterNodeRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/EnrichStatsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/EnrichStatsAction.java index 4ece0f1a62e2a..c0d96347ccae4 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/EnrichStatsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/EnrichStatsAction.java @@ -28,7 +28,7 @@ public class EnrichStatsAction extends ActionType { public static final String NAME = "cluster:monitor/xpack/enrich/stats"; private EnrichStatsAction() { - super(NAME, Response::new); + super(NAME); } public static class Request extends MasterNodeRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/ExecuteEnrichPolicyAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/ExecuteEnrichPolicyAction.java index ba802f9bf9ea8..779ea535f74d9 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/ExecuteEnrichPolicyAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/ExecuteEnrichPolicyAction.java @@ -25,7 +25,7 @@ public class ExecuteEnrichPolicyAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/GetEnrichPolicyAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/GetEnrichPolicyAction.java index d7428ce2e4a26..ef8229b407b56 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/GetEnrichPolicyAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/GetEnrichPolicyAction.java @@ -31,7 +31,7 @@ public class GetEnrichPolicyAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/PutEnrichPolicyAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/PutEnrichPolicyAction.java index ec1b04e453bb5..4ebbb75239879 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/PutEnrichPolicyAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/enrich/action/PutEnrichPolicyAction.java @@ -24,7 +24,7 @@ public class PutEnrichPolicyAction extends ActionType { public static final String NAME = "cluster:admin/xpack/enrich/put"; private PutEnrichPolicyAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static Request fromXContent(XContentParser parser, String name) throws IOException { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/frozen/action/FreezeIndexAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/frozen/action/FreezeIndexAction.java index 5fa759268555a..d4d76200c25be 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/frozen/action/FreezeIndexAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/frozen/action/FreezeIndexAction.java @@ -15,6 +15,6 @@ public class FreezeIndexAction extends ActionType { public static final String NAME = "indices:admin/freeze"; private FreezeIndexAction() { - super(NAME, FreezeResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/graph/action/GraphExploreAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/graph/action/GraphExploreAction.java index 9a1b01a86ed86..9242d2ea5ce83 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/graph/action/GraphExploreAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/graph/action/GraphExploreAction.java @@ -15,6 +15,6 @@ public class GraphExploreAction extends ActionType { public static final String NAME = "indices:data/read/xpack/graph/explore"; private GraphExploreAction() { - super(NAME, GraphExploreResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/DeleteLifecycleAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/DeleteLifecycleAction.java index 924889483f16f..4e022f2cf1394 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/DeleteLifecycleAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/DeleteLifecycleAction.java @@ -24,7 +24,7 @@ public class DeleteLifecycleAction extends ActionType { public static final String NAME = "cluster:admin/ilm/delete"; protected DeleteLifecycleAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/ExplainLifecycleAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/ExplainLifecycleAction.java index aef79d89c68c4..b3c23ca3798b0 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/ExplainLifecycleAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/ExplainLifecycleAction.java @@ -15,7 +15,7 @@ public class ExplainLifecycleAction extends ActionType public static final String NAME = "indices:admin/ilm/explain"; protected ExplainLifecycleAction() { - super(NAME, ExplainLifecycleResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/GetLifecycleAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/GetLifecycleAction.java index d9a32d6ba6b3f..97d1fbf524963 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/GetLifecycleAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/GetLifecycleAction.java @@ -35,7 +35,7 @@ public class GetLifecycleAction extends ActionType public static final String NAME = "cluster:admin/ilm/get"; protected GetLifecycleAction() { - super(NAME, GetLifecycleAction.Response::new); + super(NAME); } public static class Response extends ActionResponse implements ChunkedToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/GetStatusAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/GetStatusAction.java index 94f233e6825ed..f70510de382a9 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/GetStatusAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/GetStatusAction.java @@ -24,7 +24,7 @@ public class GetStatusAction extends ActionType { public static final String NAME = "cluster:admin/ilm/operation_mode/get"; protected GetStatusAction() { - super(NAME, GetStatusAction.Response::new); + super(NAME); } public static class Response extends ActionResponse implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/ILMActions.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/ILMActions.java index ed3c88ef86be1..fb76cc80a0e43 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/ILMActions.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/ILMActions.java @@ -11,9 +11,9 @@ public enum ILMActions { ; - public static final ActionType START = ActionType.localOnly("cluster:admin/ilm/start"); - public static final ActionType STOP = ActionType.localOnly("cluster:admin/ilm/stop"); - public static final ActionType RETRY = ActionType.localOnly("indices:admin/ilm/retry"); - public static final ActionType MOVE_TO_STEP = ActionType.localOnly("cluster:admin/ilm/_move/post"); - public static final ActionType PUT = ActionType.localOnly("cluster:admin/ilm/put"); + public static final ActionType START = new ActionType<>("cluster:admin/ilm/start"); + public static final ActionType STOP = new ActionType<>("cluster:admin/ilm/stop"); + public static final ActionType RETRY = new ActionType<>("indices:admin/ilm/retry"); + public static final ActionType MOVE_TO_STEP = new ActionType<>("cluster:admin/ilm/_move/post"); + public static final ActionType PUT = new ActionType<>("cluster:admin/ilm/put"); } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/RemoveIndexLifecyclePolicyAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/RemoveIndexLifecyclePolicyAction.java index 50f1e026d6365..68537fba3bfd1 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/RemoveIndexLifecyclePolicyAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/action/RemoveIndexLifecyclePolicyAction.java @@ -29,7 +29,7 @@ public class RemoveIndexLifecyclePolicyAction extends ActionType public static final String NAME = "cluster:admin/xpack/inference/delete"; public DeleteInferenceModelAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/GetInferenceModelAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/GetInferenceModelAction.java index 6cb7734e0feba..dc9307b3af0c1 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/GetInferenceModelAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/GetInferenceModelAction.java @@ -29,7 +29,7 @@ public class GetInferenceModelAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/InferenceAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/InferenceAction.java index 30375e36a0e1d..fd526063766e2 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/InferenceAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/InferenceAction.java @@ -41,7 +41,7 @@ public class InferenceAction extends ActionType { public static final String NAME = "cluster:monitor/xpack/inference"; public InferenceAction() { - super(NAME, Response::new); + super(NAME); } public static class Request extends ActionRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/PutInferenceModelAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/PutInferenceModelAction.java index d09b96f897e06..cebf7f1ee610d 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/PutInferenceModelAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/PutInferenceModelAction.java @@ -32,7 +32,7 @@ public class PutInferenceModelAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/AuditMlNotificationAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/AuditMlNotificationAction.java index 4fc509ca67b38..2090f1cb1bd54 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/AuditMlNotificationAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/AuditMlNotificationAction.java @@ -30,7 +30,7 @@ public class AuditMlNotificationAction extends ActionType public static final String NAME = "cluster:internal/xpack/ml/notification"; private AuditMlNotificationAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public enum AuditType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/CancelJobModelSnapshotUpgradeAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/CancelJobModelSnapshotUpgradeAction.java index 18d9168fc962d..0a4525e0524d7 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/CancelJobModelSnapshotUpgradeAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/CancelJobModelSnapshotUpgradeAction.java @@ -40,7 +40,7 @@ public class CancelJobModelSnapshotUpgradeAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/CloseJobAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/CloseJobAction.java index fbaa2b8b65141..381fb30b65e68 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/CloseJobAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/CloseJobAction.java @@ -36,7 +36,7 @@ public class CloseJobAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/job/close"; private CloseJobAction() { - super(NAME, CloseJobAction.Response::new); + super(NAME); } public static class Request extends BaseTasksRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/CoordinatedInferenceAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/CoordinatedInferenceAction.java index 7af3d1a150ac8..00064138f0362 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/CoordinatedInferenceAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/CoordinatedInferenceAction.java @@ -30,7 +30,7 @@ public class CoordinatedInferenceAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteCalendarAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteCalendarAction.java index d361be83e4d12..5c5e02559b1d5 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteCalendarAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteCalendarAction.java @@ -23,7 +23,7 @@ public class DeleteCalendarAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/calendars/delete"; private DeleteCalendarAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteCalendarEventAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteCalendarEventAction.java index 8770a463b1fc6..7d37dc8716387 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteCalendarEventAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteCalendarEventAction.java @@ -24,7 +24,7 @@ public class DeleteCalendarEventAction extends ActionType public static final String NAME = "cluster:admin/xpack/ml/calendars/events/delete"; private DeleteCalendarEventAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteDataFrameAnalyticsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteDataFrameAnalyticsAction.java index b406266b25642..61e76d2131057 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteDataFrameAnalyticsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteDataFrameAnalyticsAction.java @@ -27,7 +27,7 @@ public class DeleteDataFrameAnalyticsAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteDatafeedAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteDatafeedAction.java index d76b9899c922d..2681fadf8fc59 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteDatafeedAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteDatafeedAction.java @@ -26,7 +26,7 @@ public class DeleteDatafeedAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/datafeeds/delete"; private DeleteDatafeedAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest implements ToXContentFragment { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteExpiredDataAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteExpiredDataAction.java index e6f362bbea14c..feb4b16778966 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteExpiredDataAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteExpiredDataAction.java @@ -29,7 +29,7 @@ public class DeleteExpiredDataAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/filters/delete"; private DeleteFilterAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteForecastAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteForecastAction.java index 7d3a853db2c76..f3e888ef9599c 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteForecastAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteForecastAction.java @@ -23,7 +23,7 @@ public class DeleteForecastAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/job/forecast/delete"; private DeleteForecastAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteJobAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteJobAction.java index 16a1f252721d9..58b67e57acf26 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteJobAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteJobAction.java @@ -25,7 +25,7 @@ public class DeleteJobAction extends ActionType { public static final String DELETION_TASK_DESCRIPTION_PREFIX = "delete-job-"; private DeleteJobAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteModelSnapshotAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteModelSnapshotAction.java index 277a82b66ca9b..2bdfcb311f939 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteModelSnapshotAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteModelSnapshotAction.java @@ -24,7 +24,7 @@ public class DeleteModelSnapshotAction extends ActionType public static final String NAME = "cluster:admin/xpack/ml/job/model_snapshots/delete"; private DeleteModelSnapshotAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends ActionRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteTrainedModelAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteTrainedModelAction.java index 72e75ddedad86..9cd19eab449a3 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteTrainedModelAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteTrainedModelAction.java @@ -27,7 +27,7 @@ public class DeleteTrainedModelAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/inference/delete"; private DeleteTrainedModelAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest implements ToXContentFragment { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteTrainedModelAliasAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteTrainedModelAliasAction.java index 13ef47b74681c..507060b1e51a4 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteTrainedModelAliasAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteTrainedModelAliasAction.java @@ -24,7 +24,7 @@ public class DeleteTrainedModelAliasAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteTrainedModelAssignmentAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteTrainedModelAssignmentAction.java index 803563a6724aa..04f1b3ddb2e26 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteTrainedModelAssignmentAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/DeleteTrainedModelAssignmentAction.java @@ -23,7 +23,7 @@ public class DeleteTrainedModelAssignmentAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/EstimateModelMemoryAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/EstimateModelMemoryAction.java index ec9200e6f2b46..a5df3ee8ed703 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/EstimateModelMemoryAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/EstimateModelMemoryAction.java @@ -34,7 +34,7 @@ public class EstimateModelMemoryAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/FinalizeJobExecutionAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/FinalizeJobExecutionAction.java index 0874b6ae7e85d..b270c4506ba4a 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/FinalizeJobExecutionAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/FinalizeJobExecutionAction.java @@ -21,7 +21,7 @@ public class FinalizeJobExecutionAction extends ActionType public static final String NAME = "cluster:internal/xpack/ml/job/finalize_job_execution"; private FinalizeJobExecutionAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends MasterNodeRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/FlushJobAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/FlushJobAction.java index c316e130ecb81..082f6d7aff899 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/FlushJobAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/FlushJobAction.java @@ -31,7 +31,7 @@ public class FlushJobAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/job/flush"; private FlushJobAction() { - super(NAME, FlushJobAction.Response::new); + super(NAME); } public static class Request extends JobTaskRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/ForecastJobAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/ForecastJobAction.java index ed94d145a0276..bb15e4f34d30e 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/ForecastJobAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/ForecastJobAction.java @@ -32,7 +32,7 @@ public class ForecastJobAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/job/forecast"; private ForecastJobAction() { - super(NAME, ForecastJobAction.Response::new); + super(NAME); } public static class Request extends JobTaskRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetBucketsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetBucketsAction.java index 6aa4d284872b3..a6f056a7b2c86 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetBucketsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetBucketsAction.java @@ -33,7 +33,7 @@ public class GetBucketsAction extends ActionType { public static final String NAME = "cluster:monitor/xpack/ml/job/results/buckets/get"; private GetBucketsAction() { - super(NAME, Response::new); + super(NAME); } public static class Request extends ActionRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetCalendarEventsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetCalendarEventsAction.java index 65017cf11fcef..98a79b3e1b800 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetCalendarEventsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetCalendarEventsAction.java @@ -34,7 +34,7 @@ public class GetCalendarEventsAction extends ActionType public static final String NAME = "cluster:monitor/xpack/ml/calendars/get"; private GetCalendarsAction() { - super(NAME, Response::new); + super(NAME); } public static class Request extends ActionRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetCategoriesAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetCategoriesAction.java index 1847f8f74ed75..bdeece989201f 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetCategoriesAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetCategoriesAction.java @@ -39,7 +39,7 @@ public class GetCategoriesAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetDatafeedRunningStateAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetDatafeedRunningStateAction.java index 413bc58e6332d..a2cf82dd30e8c 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetDatafeedRunningStateAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetDatafeedRunningStateAction.java @@ -41,7 +41,7 @@ public class GetDatafeedRunningStateAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetDatafeedsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetDatafeedsAction.java index 4ea73d1b7a6ee..1bd266c68a65a 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetDatafeedsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetDatafeedsAction.java @@ -34,7 +34,7 @@ public class GetDatafeedsAction extends ActionType public static final String ALL = "_all"; private GetDatafeedsAction() { - super(NAME, Response::new); + super(NAME); } public static final class Request extends MasterNodeReadRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetDatafeedsStatsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetDatafeedsStatsAction.java index 54ffd89b68d44..42afa5f4512a3 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetDatafeedsStatsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetDatafeedsStatsAction.java @@ -54,7 +54,7 @@ public class GetDatafeedsStatsAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetFiltersAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetFiltersAction.java index dd838d368ee04..2806b4b355a20 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetFiltersAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetFiltersAction.java @@ -24,7 +24,7 @@ public class GetFiltersAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/filters/get"; private GetFiltersAction() { - super(NAME, Response::new); + super(NAME); } public static final class Request extends AbstractGetResourcesRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetInfluencersAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetInfluencersAction.java index a11484c48a981..e3e4184c18dfc 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetInfluencersAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetInfluencersAction.java @@ -32,7 +32,7 @@ public class GetInfluencersAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetJobsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetJobsAction.java index 490c4dd99fcb0..3d23a91a27f2a 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetJobsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetJobsAction.java @@ -32,7 +32,7 @@ public class GetJobsAction extends ActionType { public static final String NAME = "cluster:monitor/xpack/ml/job/get"; private GetJobsAction() { - super(NAME, Response::new); + super(NAME); } public static final class Request extends MasterNodeReadRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetJobsStatsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetJobsStatsAction.java index d819f7d846843..5a13684fcd79f 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetJobsStatsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetJobsStatsAction.java @@ -57,7 +57,7 @@ public class GetJobsStatsAction extends ActionType private static final String TIMING_STATS = "timing_stats"; private GetJobsStatsAction() { - super(NAME, GetJobsStatsAction.Response::new); + super(NAME); } public static class Request extends BaseTasksRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetMlAutoscalingStats.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetMlAutoscalingStats.java index 27e5b1cb76f4d..a7a99836cdaee 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetMlAutoscalingStats.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetMlAutoscalingStats.java @@ -32,7 +32,7 @@ public class GetMlAutoscalingStats extends ActionType { public static final String NAME = "cluster:monitor/xpack/ml/autoscaling/stats/get"; public GetMlAutoscalingStats() { - super(NAME, Response::new); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetModelSnapshotsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetModelSnapshotsAction.java index edf0a7f7e7e65..7219bcb209fe9 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetModelSnapshotsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetModelSnapshotsAction.java @@ -39,7 +39,7 @@ public class GetModelSnapshotsAction extends ActionType { public static final String NAME = "cluster:monitor/xpack/ml/job/results/records/get"; private GetRecordsAction() { - super(NAME, Response::new); + super(NAME); } public static class Request extends ActionRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetTrainedModelsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetTrainedModelsAction.java index 0c5fbbc065e29..4992177a10f8d 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetTrainedModelsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/GetTrainedModelsAction.java @@ -33,7 +33,7 @@ public class GetTrainedModelsAction extends ActionType { public static final InferModelAction EXTERNAL_INSTANCE = new InferModelAction(EXTERNAL_NAME); private InferModelAction(String name) { - super(name, Response::new); + super(name); } public static class Request extends ActionRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/InferTrainedModelDeploymentAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/InferTrainedModelDeploymentAction.java index 99d190a786564..bd03913290e0c 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/InferTrainedModelDeploymentAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/InferTrainedModelDeploymentAction.java @@ -56,7 +56,7 @@ public class InferTrainedModelDeploymentAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/KillProcessAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/KillProcessAction.java index 7992093651138..4dfd76fa54793 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/KillProcessAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/KillProcessAction.java @@ -21,7 +21,7 @@ public class KillProcessAction extends ActionType { public static final String NAME = "cluster:internal/xpack/ml/job/kill/process"; private KillProcessAction() { - super(NAME, KillProcessAction.Response::new); + super(NAME); } public static class Request extends JobTaskRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/MlInfoAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/MlInfoAction.java index 3c69056625e89..1f1eb69ce606c 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/MlInfoAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/MlInfoAction.java @@ -26,7 +26,7 @@ public class MlInfoAction extends ActionType { public static final String NAME = "cluster:monitor/xpack/ml/info/get"; private MlInfoAction() { - super(NAME, Response::new); + super(NAME); } public static class Request extends ActionRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/MlMemoryAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/MlMemoryAction.java index f4bd469e65432..e8b345b3c3ff6 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/MlMemoryAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/MlMemoryAction.java @@ -60,7 +60,7 @@ public class MlMemoryAction extends ActionType { static final String JAVA_INFERENCE_IN_BYTES = "java_inference_in_bytes"; private MlMemoryAction() { - super(NAME, Response::new); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/OpenJobAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/OpenJobAction.java index c50342dd78157..b6f852605db9f 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/OpenJobAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/OpenJobAction.java @@ -39,7 +39,7 @@ public class OpenJobAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/job/open"; private OpenJobAction() { - super(NAME, NodeAcknowledgedResponse::new); + super(NAME); } public static class Request extends MasterNodeRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PersistJobAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PersistJobAction.java index 916ebe0d613f2..34c78894f5cd0 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PersistJobAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PersistJobAction.java @@ -21,7 +21,7 @@ public class PersistJobAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/job/persist"; private PersistJobAction() { - super(NAME, PersistJobAction.Response::new); + super(NAME); } public static class Request extends JobTaskRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PostCalendarEventsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PostCalendarEventsAction.java index 4afad7a650db0..6ca201fd8034a 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PostCalendarEventsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PostCalendarEventsAction.java @@ -35,7 +35,7 @@ public class PostCalendarEventsAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/job/data/post"; private PostDataAction() { - super(NAME, PostDataAction.Response::new); + super(NAME); } public static class Response extends BaseTasksResponse implements ToXContentObject, Writeable { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PreviewDataFrameAnalyticsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PreviewDataFrameAnalyticsAction.java index 86c794084388f..634487aa0d39f 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PreviewDataFrameAnalyticsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PreviewDataFrameAnalyticsAction.java @@ -37,7 +37,7 @@ public class PreviewDataFrameAnalyticsAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/calendars/put"; private PutCalendarAction() { - super(NAME, Response::new); + super(NAME); } public static class Request extends ActionRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutDataFrameAnalyticsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutDataFrameAnalyticsAction.java index 67cf1865efb78..c9da8aa4dd579 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutDataFrameAnalyticsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutDataFrameAnalyticsAction.java @@ -32,7 +32,7 @@ public class PutDataFrameAnalyticsAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutDatafeedAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutDatafeedAction.java index a4c6aaa6e53bd..67b1b2f9087e3 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutDatafeedAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutDatafeedAction.java @@ -26,7 +26,7 @@ public class PutDatafeedAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/datafeeds/put"; private PutDatafeedAction() { - super(NAME, Response::new); + super(NAME); } public static class Request extends AcknowledgedRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutFilterAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutFilterAction.java index b2d3196824036..50216b72f20d6 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutFilterAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutFilterAction.java @@ -29,7 +29,7 @@ public class PutFilterAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/filters/put"; private PutFilterAction() { - super(NAME, Response::new); + super(NAME); } public static class Request extends ActionRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutJobAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutJobAction.java index 54fd0c7c2a4eb..400bdaa3a27ea 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutJobAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutJobAction.java @@ -29,7 +29,7 @@ public class PutJobAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/job/put"; private PutJobAction() { - super(NAME, Response::new); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutTrainedModelAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutTrainedModelAction.java index 5f81290261232..769a3a3dded28 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutTrainedModelAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutTrainedModelAction.java @@ -32,7 +32,7 @@ public class PutTrainedModelAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutTrainedModelAliasAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutTrainedModelAliasAction.java index b5fc85bdc4f99..9f0b5880f5c51 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutTrainedModelAliasAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutTrainedModelAliasAction.java @@ -35,7 +35,7 @@ public class PutTrainedModelAliasAction extends ActionType public static final String NAME = "cluster:admin/xpack/ml/inference/model_aliases/put"; private PutTrainedModelAliasAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutTrainedModelDefinitionPartAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutTrainedModelDefinitionPartAction.java index 6f64c41c8dee9..b7fcb98426cc0 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutTrainedModelDefinitionPartAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutTrainedModelDefinitionPartAction.java @@ -34,7 +34,7 @@ public class PutTrainedModelDefinitionPartAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutTrainedModelVocabularyAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutTrainedModelVocabularyAction.java index ed988f952bc97..1abae7be95011 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutTrainedModelVocabularyAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/PutTrainedModelVocabularyAction.java @@ -34,7 +34,7 @@ public class PutTrainedModelVocabularyAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/ResetJobAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/ResetJobAction.java index 9bc7dfe9ae3dc..bc74f16eea0e5 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/ResetJobAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/ResetJobAction.java @@ -33,7 +33,7 @@ public class ResetJobAction extends ActionType { public static final TransportVersion TRANSPORT_VERSION_INTRODUCED = TransportVersions.V_7_14_0; private ResetJobAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/RevertModelSnapshotAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/RevertModelSnapshotAction.java index a74744f1f5771..eb975133e71eb 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/RevertModelSnapshotAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/RevertModelSnapshotAction.java @@ -30,7 +30,7 @@ public class RevertModelSnapshotAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/SetResetModeAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/SetResetModeAction.java index 3fc9b8a0f10b1..cd1d6f57b5195 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/SetResetModeAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/SetResetModeAction.java @@ -15,7 +15,7 @@ public class SetResetModeAction extends ActionType { public static final String NAME = "cluster:internal/xpack/ml/reset_mode"; private SetResetModeAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/SetUpgradeModeAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/SetUpgradeModeAction.java index a5faef506ea37..9a1574bd2b036 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/SetUpgradeModeAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/SetUpgradeModeAction.java @@ -25,7 +25,7 @@ public class SetUpgradeModeAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/upgrade_mode"; private SetUpgradeModeAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StartDataFrameAnalyticsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StartDataFrameAnalyticsAction.java index 85a7202817e83..67abda2b3eb64 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StartDataFrameAnalyticsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StartDataFrameAnalyticsAction.java @@ -42,7 +42,7 @@ public class StartDataFrameAnalyticsAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StartDatafeedAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StartDatafeedAction.java index 38a657bd472da..0ac1203f1144b 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StartDatafeedAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StartDatafeedAction.java @@ -50,7 +50,7 @@ public class StartDatafeedAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/datafeed/start"; private StartDatafeedAction() { - super(NAME, NodeAcknowledgedResponse::new); + super(NAME); } public static class Request extends MasterNodeRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StartTrainedModelDeploymentAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StartTrainedModelDeploymentAction.java index c05c73bc31ddf..8d9da97538e11 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StartTrainedModelDeploymentAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StartTrainedModelDeploymentAction.java @@ -69,7 +69,7 @@ public class StartTrainedModelDeploymentAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StopDataFrameAnalyticsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StopDataFrameAnalyticsAction.java index d1c82635a83c2..f352e24fee616 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StopDataFrameAnalyticsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StopDataFrameAnalyticsAction.java @@ -42,7 +42,7 @@ public class StopDataFrameAnalyticsAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StopDatafeedAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StopDatafeedAction.java index 209966fd43875..453e7a4528a87 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StopDatafeedAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StopDatafeedAction.java @@ -39,7 +39,7 @@ public class StopDatafeedAction extends ActionType public static final TimeValue DEFAULT_TIMEOUT = TimeValue.timeValueMinutes(5); private StopDatafeedAction() { - super(NAME, StopDatafeedAction.Response::new); + super(NAME); } public static class Request extends BaseTasksRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StopTrainedModelDeploymentAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StopTrainedModelDeploymentAction.java index 5fc3776e7013c..a0c54ac16aba9 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StopTrainedModelDeploymentAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/StopTrainedModelDeploymentAction.java @@ -34,7 +34,7 @@ public class StopTrainedModelDeploymentAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/TrainedModelCacheInfoAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/TrainedModelCacheInfoAction.java index e58742799d4e6..81a0a95c9f8ba 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/TrainedModelCacheInfoAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/TrainedModelCacheInfoAction.java @@ -30,7 +30,7 @@ public class TrainedModelCacheInfoAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateCalendarJobAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateCalendarJobAction.java index e5096051b1eae..e98eb38db6ea2 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateCalendarJobAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateCalendarJobAction.java @@ -22,7 +22,7 @@ public class UpdateCalendarJobAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateDatafeedAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateDatafeedAction.java index 369b6fc27b4a8..694ca39d9cd49 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateDatafeedAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateDatafeedAction.java @@ -26,7 +26,7 @@ public class UpdateDatafeedAction extends ActionType public static final String NAME = "cluster:admin/xpack/ml/datafeeds/update"; private UpdateDatafeedAction() { - super(NAME, PutDatafeedAction.Response::new); + super(NAME); } public static class Request extends AcknowledgedRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateFilterAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateFilterAction.java index e63aa95aeefd7..4e232bea4cc5b 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateFilterAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateFilterAction.java @@ -36,7 +36,7 @@ public class UpdateFilterAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/filters/update"; private UpdateFilterAction() { - super(NAME, PutFilterAction.Response::new); + super(NAME); } public static class Request extends ActionRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateJobAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateJobAction.java index 773de612f1537..4e80fcab05e2f 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateJobAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateJobAction.java @@ -25,7 +25,7 @@ public class UpdateJobAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/job/update"; private UpdateJobAction() { - super(NAME, PutJobAction.Response::new); + super(NAME); } public static class Request extends AcknowledgedRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateModelSnapshotAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateModelSnapshotAction.java index c83b7d7578bf1..d80b055cc0fcc 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateModelSnapshotAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateModelSnapshotAction.java @@ -32,7 +32,7 @@ public class UpdateModelSnapshotAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateTrainedModelDeploymentAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateTrainedModelDeploymentAction.java index 33e26fb0ab3d1..b598d398025e0 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateTrainedModelDeploymentAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpdateTrainedModelDeploymentAction.java @@ -34,7 +34,7 @@ public class UpdateTrainedModelDeploymentAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpgradeJobModelSnapshotAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpgradeJobModelSnapshotAction.java index b09eed900838c..7fbcffa476159 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpgradeJobModelSnapshotAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/UpgradeJobModelSnapshotAction.java @@ -30,7 +30,7 @@ public class UpgradeJobModelSnapshotAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/ValidateDetectorAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/ValidateDetectorAction.java index 2f7b561d69c04..6831f985fdc76 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/ValidateDetectorAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/ValidateDetectorAction.java @@ -26,7 +26,7 @@ public class ValidateDetectorAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/job/validate/detector"; protected ValidateDetectorAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends ActionRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/ValidateJobConfigAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/ValidateJobConfigAction.java index e90ac5c47210e..48549ae100e36 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/ValidateJobConfigAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/action/ValidateJobConfigAction.java @@ -27,7 +27,7 @@ public class ValidateJobConfigAction extends ActionType { public static final String NAME = "cluster:admin/xpack/ml/job/validate"; protected ValidateJobConfigAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends ActionRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/packageloader/action/GetTrainedModelPackageConfigAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/packageloader/action/GetTrainedModelPackageConfigAction.java index addc29a4990b4..8fcc977e3faeb 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/packageloader/action/GetTrainedModelPackageConfigAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/packageloader/action/GetTrainedModelPackageConfigAction.java @@ -29,7 +29,7 @@ public class GetTrainedModelPackageConfigAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/packageloader/action/LoadTrainedModelPackageAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/packageloader/action/LoadTrainedModelPackageAction.java index 2e0d89eec7ae0..fd935c052333d 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/packageloader/action/LoadTrainedModelPackageAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/packageloader/action/LoadTrainedModelPackageAction.java @@ -29,7 +29,7 @@ public class LoadTrainedModelPackageAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/monitoring/action/MonitoringBulkAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/monitoring/action/MonitoringBulkAction.java index 919403f3e09a0..eece4d6d5a925 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/monitoring/action/MonitoringBulkAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/monitoring/action/MonitoringBulkAction.java @@ -14,6 +14,6 @@ public class MonitoringBulkAction extends ActionType { public static final String NAME = "cluster:admin/xpack/monitoring/bulk"; private MonitoringBulkAction() { - super(NAME, MonitoringBulkResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/monitoring/action/MonitoringMigrateAlertsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/monitoring/action/MonitoringMigrateAlertsAction.java index 895cca529135f..5c742f9a505a6 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/monitoring/action/MonitoringMigrateAlertsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/monitoring/action/MonitoringMigrateAlertsAction.java @@ -14,6 +14,6 @@ public class MonitoringMigrateAlertsAction extends ActionType implements ToXContentFragment { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/GetRollupCapsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/GetRollupCapsAction.java index 200c984317d79..6c76ca813170d 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/GetRollupCapsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/GetRollupCapsAction.java @@ -34,7 +34,7 @@ public class GetRollupCapsAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/PutRollupJobAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/PutRollupJobAction.java index a5784125dc8b2..06a6b4c2a072c 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/PutRollupJobAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/PutRollupJobAction.java @@ -29,7 +29,7 @@ public class PutRollupJobAction extends ActionType { public static final String NAME = "cluster:admin/xpack/rollup/put"; private PutRollupJobAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest implements IndicesRequest, ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/RollupSearchAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/RollupSearchAction.java index c0bb62aa610fe..ee720a7819afc 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/RollupSearchAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/RollupSearchAction.java @@ -18,7 +18,7 @@ public class RollupSearchAction extends ActionType { public static final String NAME = "indices:data/read/xpack/rollup/search"; private RollupSearchAction() { - super(NAME, SearchResponse::new); + super(NAME); } public static class RequestBuilder extends ActionRequestBuilder { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/StartRollupJobAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/StartRollupJobAction.java index 00a4daaa061c9..b05a2170a1be4 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/StartRollupJobAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/StartRollupJobAction.java @@ -28,7 +28,7 @@ public class StartRollupJobAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/StopRollupJobAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/StopRollupJobAction.java index f1527b4c2cafb..bf09f0a0111a4 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/StopRollupJobAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/action/StopRollupJobAction.java @@ -35,7 +35,7 @@ public class StopRollupJobAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/GetAsyncSearchAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/GetAsyncSearchAction.java index 7c11d93d915b2..2eaf9c5be9633 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/GetAsyncSearchAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/GetAsyncSearchAction.java @@ -13,6 +13,6 @@ public class GetAsyncSearchAction extends ActionType { public static final String NAME = "indices:data/read/async_search/get"; private GetAsyncSearchAction() { - super(NAME, AsyncSearchResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/GetAsyncStatusAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/GetAsyncStatusAction.java index 85d43a73ada94..4c6b65a837f97 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/GetAsyncStatusAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/GetAsyncStatusAction.java @@ -13,6 +13,6 @@ public class GetAsyncStatusAction extends ActionType { public static final String NAME = "cluster:monitor/async_search/status"; private GetAsyncStatusAction() { - super(NAME, AsyncStatusResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/SubmitAsyncSearchAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/SubmitAsyncSearchAction.java index f1b75a27b92a3..3c616a0fece1e 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/SubmitAsyncSearchAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/SubmitAsyncSearchAction.java @@ -13,6 +13,6 @@ public final class SubmitAsyncSearchAction extends ActionType RELOAD_REMOTE_CLUSTER_CREDENTIALS_ACTION = ActionType.localOnly( + public static final ActionType RELOAD_REMOTE_CLUSTER_CREDENTIALS_ACTION = new ActionType<>( "cluster:admin/xpack/security/remote_cluster_credentials/reload" ); - public static final ActionType QUERY_USER_ACTION = ActionType.localOnly("cluster:admin/xpack/security/user/query"); + public static final ActionType QUERY_USER_ACTION = new ActionType<>("cluster:admin/xpack/security/user/query"); } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/ClearSecurityCacheAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/ClearSecurityCacheAction.java index 5c7bdb39dc49e..7726ba2596364 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/ClearSecurityCacheAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/ClearSecurityCacheAction.java @@ -8,7 +8,6 @@ package org.elasticsearch.xpack.core.security.action; import org.elasticsearch.action.ActionType; -import org.elasticsearch.common.io.stream.Writeable; public class ClearSecurityCacheAction extends ActionType { @@ -16,6 +15,6 @@ public class ClearSecurityCacheAction extends ActionType { public static final CreateApiKeyAction INSTANCE = new CreateApiKeyAction(); private CreateApiKeyAction() { - super(NAME, CreateApiKeyResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/CreateCrossClusterApiKeyAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/CreateCrossClusterApiKeyAction.java index d5bd7f4e6c02e..8abe5251d0209 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/CreateCrossClusterApiKeyAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/CreateCrossClusterApiKeyAction.java @@ -18,7 +18,7 @@ public final class CreateCrossClusterApiKeyAction extends ActionType { public static final GetApiKeyAction INSTANCE = new GetApiKeyAction(); private GetApiKeyAction() { - super(NAME, GetApiKeyResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/GrantApiKeyAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/GrantApiKeyAction.java index 1f9f05ca07e49..c24c9625a5a95 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/GrantApiKeyAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/GrantApiKeyAction.java @@ -19,7 +19,7 @@ public final class GrantApiKeyAction extends ActionType { public static final GrantApiKeyAction INSTANCE = new GrantApiKeyAction(); private GrantApiKeyAction() { - super(NAME, CreateApiKeyResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/InvalidateApiKeyAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/InvalidateApiKeyAction.java index 2ca54a3b416b0..90d582ad867de 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/InvalidateApiKeyAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/InvalidateApiKeyAction.java @@ -18,6 +18,6 @@ public final class InvalidateApiKeyAction extends ActionType { @@ -16,7 +15,7 @@ public final class QueryApiKeyAction extends ActionType { public static final QueryApiKeyAction INSTANCE = new QueryApiKeyAction(); private QueryApiKeyAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/UpdateApiKeyAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/UpdateApiKeyAction.java index 9cacc909b14ea..c42f7a12bea87 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/UpdateApiKeyAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/UpdateApiKeyAction.java @@ -15,6 +15,6 @@ public final class UpdateApiKeyAction extends ActionType { public static final UpdateApiKeyAction INSTANCE = new UpdateApiKeyAction(); private UpdateApiKeyAction() { - super(NAME, UpdateApiKeyResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/UpdateCrossClusterApiKeyAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/UpdateCrossClusterApiKeyAction.java index 9cfda77b3b5f1..e83e67b8fdfff 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/UpdateCrossClusterApiKeyAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/apikey/UpdateCrossClusterApiKeyAction.java @@ -15,6 +15,6 @@ public final class UpdateCrossClusterApiKeyAction extends ActionType { @@ -16,6 +15,6 @@ public class ClearPrivilegesCacheAction extends ActionType public static final String NAME = "cluster:admin/xpack/security/privilege/get"; private GetPrivilegesAction() { - super(NAME, GetPrivilegesResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/privilege/PutPrivilegesAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/privilege/PutPrivilegesAction.java index deb14567b9048..0380380040739 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/privilege/PutPrivilegesAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/privilege/PutPrivilegesAction.java @@ -17,6 +17,6 @@ public final class PutPrivilegesAction extends ActionType public static final String NAME = "cluster:admin/xpack/security/privilege/put"; private PutPrivilegesAction() { - super(NAME, PutPrivilegesResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/ActivateProfileAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/ActivateProfileAction.java index 92fd74bd70538..28b177d912a49 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/ActivateProfileAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/ActivateProfileAction.java @@ -15,6 +15,6 @@ public class ActivateProfileAction extends ActionType { public static final ActivateProfileAction INSTANCE = new ActivateProfileAction(); public ActivateProfileAction() { - super(NAME, ActivateProfileResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/GetProfilesAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/GetProfilesAction.java index 2ba86a1559588..c35693e17d1fe 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/GetProfilesAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/GetProfilesAction.java @@ -15,6 +15,6 @@ public class GetProfilesAction extends ActionType { public static final GetProfilesAction INSTANCE = new GetProfilesAction(); public GetProfilesAction() { - super(NAME, GetProfilesResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/SetProfileEnabledAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/SetProfileEnabledAction.java index c6a61b7e2838a..369147cc5dc4f 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/SetProfileEnabledAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/SetProfileEnabledAction.java @@ -16,6 +16,6 @@ public class SetProfileEnabledAction extends ActionType { public static final SetProfileEnabledAction INSTANCE = new SetProfileEnabledAction(); public SetProfileEnabledAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/SuggestProfilesAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/SuggestProfilesAction.java index f8e4d31f9d5cf..bafa85f79c618 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/SuggestProfilesAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/SuggestProfilesAction.java @@ -15,6 +15,6 @@ public class SuggestProfilesAction extends ActionType { public static final SuggestProfilesAction INSTANCE = new SuggestProfilesAction(); public SuggestProfilesAction() { - super(NAME, SuggestProfilesResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/UpdateProfileDataAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/UpdateProfileDataAction.java index c9dd8eaada068..c6a25b97a8c8c 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/UpdateProfileDataAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/profile/UpdateProfileDataAction.java @@ -16,6 +16,6 @@ public class UpdateProfileDataAction extends ActionType { public static final UpdateProfileDataAction INSTANCE = new UpdateProfileDataAction(); public UpdateProfileDataAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/realm/ClearRealmCacheAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/realm/ClearRealmCacheAction.java index 443babe3fdee7..acd1c94f20fea 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/realm/ClearRealmCacheAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/realm/ClearRealmCacheAction.java @@ -7,7 +7,6 @@ package org.elasticsearch.xpack.core.security.action.realm; import org.elasticsearch.action.ActionType; -import org.elasticsearch.common.io.stream.Writeable; public class ClearRealmCacheAction extends ActionType { @@ -15,6 +14,6 @@ public class ClearRealmCacheAction extends ActionType { public static final String NAME = "cluster:admin/xpack/security/realm/cache/clear"; protected ClearRealmCacheAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/role/ClearRolesCacheAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/role/ClearRolesCacheAction.java index cef2665df87be..a772e948b93d1 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/role/ClearRolesCacheAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/role/ClearRolesCacheAction.java @@ -7,7 +7,6 @@ package org.elasticsearch.xpack.core.security.action.role; import org.elasticsearch.action.ActionType; -import org.elasticsearch.common.io.stream.Writeable; /** * The action for clearing the cache used by native roles that are stored in an index. @@ -18,6 +17,6 @@ public class ClearRolesCacheAction extends ActionType { public static final String NAME = "cluster:admin/xpack/security/roles/cache/clear"; protected ClearRolesCacheAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/role/DeleteRoleAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/role/DeleteRoleAction.java index 2b4ad261ccae2..70c8378f227ae 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/role/DeleteRoleAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/role/DeleteRoleAction.java @@ -17,6 +17,6 @@ public class DeleteRoleAction extends ActionType { public static final String NAME = "cluster:admin/xpack/security/role/delete"; protected DeleteRoleAction() { - super(NAME, DeleteRoleResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/role/GetRolesAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/role/GetRolesAction.java index 543b1485b035f..ac48571d8717e 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/role/GetRolesAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/role/GetRolesAction.java @@ -17,6 +17,6 @@ public class GetRolesAction extends ActionType { public static final String NAME = "cluster:admin/xpack/security/role/get"; protected GetRolesAction() { - super(NAME, GetRolesResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/role/PutRoleAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/role/PutRoleAction.java index 548e7e043b1bc..015b9be849764 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/role/PutRoleAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/role/PutRoleAction.java @@ -17,6 +17,6 @@ public class PutRoleAction extends ActionType { public static final String NAME = "cluster:admin/xpack/security/role/put"; protected PutRoleAction() { - super(NAME, PutRoleResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/rolemapping/DeleteRoleMappingAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/rolemapping/DeleteRoleMappingAction.java index a470f36f905a6..77e4efdb3363b 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/rolemapping/DeleteRoleMappingAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/rolemapping/DeleteRoleMappingAction.java @@ -18,6 +18,6 @@ public class DeleteRoleMappingAction extends ActionType { public static final String NAME = "cluster:admin/xpack/security/role_mapping/get"; private GetRoleMappingsAction() { - super(NAME, GetRoleMappingsResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/rolemapping/PutRoleMappingAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/rolemapping/PutRoleMappingAction.java index d3bdb9c01637a..c876df5972317 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/rolemapping/PutRoleMappingAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/rolemapping/PutRoleMappingAction.java @@ -17,6 +17,6 @@ public class PutRoleMappingAction extends ActionType { public static final String NAME = "cluster:admin/xpack/security/role_mapping/put"; private PutRoleMappingAction() { - super(NAME, PutRoleMappingResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/saml/SamlAuthenticateAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/saml/SamlAuthenticateAction.java index bde668e7a1724..e0be9d6b097f3 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/saml/SamlAuthenticateAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/saml/SamlAuthenticateAction.java @@ -17,6 +17,6 @@ public final class SamlAuthenticateAction extends ActionType { public static final SamlLogoutAction INSTANCE = new SamlLogoutAction(); private SamlLogoutAction() { - super(NAME, SamlLogoutResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/saml/SamlPrepareAuthenticationAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/saml/SamlPrepareAuthenticationAction.java index 0eda263da44ab..a93bf2dd50cd7 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/saml/SamlPrepareAuthenticationAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/saml/SamlPrepareAuthenticationAction.java @@ -17,6 +17,6 @@ public final class SamlPrepareAuthenticationAction extends ActionType { public static final SamlSpMetadataAction INSTANCE = new SamlSpMetadataAction(); private SamlSpMetadataAction() { - super(NAME, SamlSpMetadataResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/service/CreateServiceAccountTokenAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/service/CreateServiceAccountTokenAction.java index 4771196c04fde..8b5cebf718bc7 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/service/CreateServiceAccountTokenAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/service/CreateServiceAccountTokenAction.java @@ -15,6 +15,6 @@ public class CreateServiceAccountTokenAction extends ActionType { @@ -16,6 +15,6 @@ public class GetServiceAccountNodesCredentialsAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/settings/UpdateSecuritySettingsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/settings/UpdateSecuritySettingsAction.java index 88bc63a3a78f8..20feb0faf5033 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/settings/UpdateSecuritySettingsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/settings/UpdateSecuritySettingsAction.java @@ -45,7 +45,7 @@ public class UpdateSecuritySettingsAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/token/CreateTokenAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/token/CreateTokenAction.java index e468b4e1033f7..5828abdcf7ea8 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/token/CreateTokenAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/token/CreateTokenAction.java @@ -17,6 +17,6 @@ public final class CreateTokenAction extends ActionType { public static final CreateTokenAction INSTANCE = new CreateTokenAction(); private CreateTokenAction() { - super(NAME, CreateTokenResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/token/InvalidateTokenAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/token/InvalidateTokenAction.java index 2736138574b5d..6172a6cbd8e33 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/token/InvalidateTokenAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/token/InvalidateTokenAction.java @@ -17,6 +17,6 @@ public final class InvalidateTokenAction extends ActionType { public static final RefreshTokenAction INSTANCE = new RefreshTokenAction(); private RefreshTokenAction() { - super(NAME, CreateTokenResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/AuthenticateAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/AuthenticateAction.java index e5d6dc3922363..7c530f79d4f52 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/AuthenticateAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/AuthenticateAction.java @@ -14,6 +14,6 @@ public class AuthenticateAction extends ActionType { public static final AuthenticateAction INSTANCE = new AuthenticateAction(); public AuthenticateAction() { - super(NAME, AuthenticateResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/DeleteUserAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/DeleteUserAction.java index 657e377c1b208..538a0ab0269c6 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/DeleteUserAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/DeleteUserAction.java @@ -17,6 +17,6 @@ public class DeleteUserAction extends ActionType { public static final String NAME = "cluster:admin/xpack/security/user/delete"; protected DeleteUserAction() { - super(NAME, DeleteUserResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/GetUserPrivilegesAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/GetUserPrivilegesAction.java index b6a93a1e3f07f..6d0faf89e7bd3 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/GetUserPrivilegesAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/GetUserPrivilegesAction.java @@ -17,6 +17,6 @@ public final class GetUserPrivilegesAction extends ActionType { public static final String NAME = "cluster:admin/xpack/security/user/get"; protected GetUsersAction() { - super(NAME, GetUsersResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/HasPrivilegesAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/HasPrivilegesAction.java index 0474dab3484dc..9453d9f769b47 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/HasPrivilegesAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/HasPrivilegesAction.java @@ -8,7 +8,6 @@ import org.elasticsearch.action.ActionType; import org.elasticsearch.action.RemoteClusterActionType; -import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.xpack.core.security.authz.RoleDescriptor; /** @@ -25,6 +24,6 @@ public class HasPrivilegesAction extends ActionType { ); private HasPrivilegesAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/ProfileHasPrivilegesAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/ProfileHasPrivilegesAction.java index 186bf4966c48f..2a65cc85b6d00 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/ProfileHasPrivilegesAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/user/ProfileHasPrivilegesAction.java @@ -15,6 +15,6 @@ public class ProfileHasPrivilegesAction extends ActionType { public static final String NAME = "cluster:admin/xpack/security/user/put"; protected PutUserAction() { - super(NAME, PutUserResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/DeleteSnapshotLifecycleAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/DeleteSnapshotLifecycleAction.java index c79d546a236b8..17a23f6b66b5b 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/DeleteSnapshotLifecycleAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/DeleteSnapshotLifecycleAction.java @@ -21,7 +21,7 @@ public class DeleteSnapshotLifecycleAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/ExecuteSnapshotLifecycleAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/ExecuteSnapshotLifecycleAction.java index 40e7a1cb7e6aa..8a8ecf3a747a8 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/ExecuteSnapshotLifecycleAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/ExecuteSnapshotLifecycleAction.java @@ -28,7 +28,7 @@ public class ExecuteSnapshotLifecycleAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/ExecuteSnapshotRetentionAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/ExecuteSnapshotRetentionAction.java index 0ec08648eb907..9574ba7fff685 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/ExecuteSnapshotRetentionAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/ExecuteSnapshotRetentionAction.java @@ -21,7 +21,7 @@ public class ExecuteSnapshotRetentionAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/GetSLMStatusAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/GetSLMStatusAction.java index bfdc1e393fb05..c7e108b8fec3b 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/GetSLMStatusAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/GetSLMStatusAction.java @@ -22,7 +22,7 @@ public class GetSLMStatusAction extends ActionType public static final String NAME = "cluster:admin/slm/status"; protected GetSLMStatusAction() { - super(NAME, GetSLMStatusAction.Response::new); + super(NAME); } public static class Response extends ActionResponse implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/GetSnapshotLifecycleAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/GetSnapshotLifecycleAction.java index b6fd80e637299..50bf1d1eaf9ea 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/GetSnapshotLifecycleAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/GetSnapshotLifecycleAction.java @@ -27,7 +27,7 @@ public class GetSnapshotLifecycleAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/GetSnapshotLifecycleStatsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/GetSnapshotLifecycleStatsAction.java index 44baab0d45bdd..6279c4208b878 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/GetSnapshotLifecycleStatsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/GetSnapshotLifecycleStatsAction.java @@ -29,7 +29,7 @@ public class GetSnapshotLifecycleStatsAction extends ActionType public static final String NAME = "cluster:admin/slm/put"; protected PutSnapshotLifecycleAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/StartSLMAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/StartSLMAction.java index ed7358be43818..d6deb7bda384f 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/StartSLMAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/StartSLMAction.java @@ -19,7 +19,7 @@ public class StartSLMAction extends ActionType { public static final String NAME = "cluster:admin/slm/start"; protected StartSLMAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/StopSLMAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/StopSLMAction.java index 7f661d5c38ecb..60be1b99cde8d 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/StopSLMAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/action/StopSLMAction.java @@ -19,7 +19,7 @@ public class StopSLMAction extends ActionType { public static final String NAME = "cluster:admin/slm/stop"; protected StopSLMAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/spatial/action/SpatialStatsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/spatial/action/SpatialStatsAction.java index ceee29d173d9b..117d613a20cd9 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/spatial/action/SpatialStatsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/spatial/action/SpatialStatsAction.java @@ -33,7 +33,7 @@ public class SpatialStatsAction extends ActionType public static final String NAME = "cluster:monitor/xpack/spatial/stats"; private SpatialStatsAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } /** diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ssl/action/GetCertificateInfoAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ssl/action/GetCertificateInfoAction.java index 985bab5a0d1d9..cbb747272eebc 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ssl/action/GetCertificateInfoAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ssl/action/GetCertificateInfoAction.java @@ -32,7 +32,7 @@ public class GetCertificateInfoAction extends ActionType { static final ParseField TIMEOUT = new ParseField("timeout"); private TermsEnumAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } public static TermsEnumRequest fromXContent(XContentParser parser, String... indices) throws IOException { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/textstructure/action/FindStructureAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/textstructure/action/FindStructureAction.java index e760471a6f1c2..98bdff8cbced7 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/textstructure/action/FindStructureAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/textstructure/action/FindStructureAction.java @@ -38,7 +38,7 @@ public class FindStructureAction extends ActionType INSTANCE = ActionType.localOnly( + public static final ActionType INSTANCE = new ActionType<>( "cluster:monitor/text_structure/test_grok_pattern" ); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/DeleteTransformAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/DeleteTransformAction.java index 26c32e596c4ef..ef61187757445 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/DeleteTransformAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/DeleteTransformAction.java @@ -25,7 +25,7 @@ public class DeleteTransformAction extends ActionType { public static final String NAME = "cluster:admin/transform/delete"; private DeleteTransformAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/GetCheckpointAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/GetCheckpointAction.java index f510a4b2ca195..f1b11daf9e732 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/GetCheckpointAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/GetCheckpointAction.java @@ -18,7 +18,6 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.core.TimeValue; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.tasks.CancellableTask; @@ -45,7 +44,7 @@ public class GetCheckpointAction extends ActionType REMOTE_TYPE = new RemoteClusterActionType<>(NAME, Response::new); private GetCheckpointAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } public static class Request extends ActionRequest implements IndicesRequest.Replaceable { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/GetCheckpointNodeAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/GetCheckpointNodeAction.java index 8e67dbc6daacd..908810cacf2ec 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/GetCheckpointNodeAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/GetCheckpointNodeAction.java @@ -39,7 +39,7 @@ public class GetCheckpointNodeAction extends ActionType private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(GetTransformAction.class); private GetTransformAction() { - super(NAME, GetTransformAction.Response::new); + super(NAME); } public static class Request extends AbstractGetResourcesRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/GetTransformStatsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/GetTransformStatsAction.java index 46e844f93695e..b7259f9bd8d60 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/GetTransformStatsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/GetTransformStatsAction.java @@ -46,7 +46,7 @@ public class GetTransformStatsAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/PreviewTransformAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/PreviewTransformAction.java index 98018589e73a4..67c5e22902cf2 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/PreviewTransformAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/PreviewTransformAction.java @@ -52,7 +52,7 @@ public class PreviewTransformAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/PutTransformAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/PutTransformAction.java index 5f278db31d5ef..b9f186ec10833 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/PutTransformAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/PutTransformAction.java @@ -35,7 +35,7 @@ public class PutTransformAction extends ActionType { private static final TimeValue MAX_FREQUENCY = TimeValue.timeValueHours(1); private PutTransformAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/ResetTransformAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/ResetTransformAction.java index 64dfa4008404e..9d77ffdc0c218 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/ResetTransformAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/ResetTransformAction.java @@ -25,7 +25,7 @@ public class ResetTransformAction extends ActionType { public static final ResetTransformAction INSTANCE = new ResetTransformAction(); private ResetTransformAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/ScheduleNowTransformAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/ScheduleNowTransformAction.java index 6a50bd40517e1..ebb17ee0d90ad 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/ScheduleNowTransformAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/ScheduleNowTransformAction.java @@ -35,7 +35,7 @@ public class ScheduleNowTransformAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/SetResetModeAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/SetResetModeAction.java index 8b4b4d438d4e8..8fcca8ddcb821 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/SetResetModeAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/SetResetModeAction.java @@ -15,7 +15,7 @@ public class SetResetModeAction extends ActionType { public static final String NAME = "cluster:internal/xpack/transform/reset_mode"; private SetResetModeAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/StartTransformAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/StartTransformAction.java index e04118d1dd6a9..268098c092b0c 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/StartTransformAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/StartTransformAction.java @@ -30,7 +30,7 @@ public class StartTransformAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/StopTransformAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/StopTransformAction.java index 794bf009764f3..6c7f1be2c3231 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/StopTransformAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/StopTransformAction.java @@ -43,7 +43,7 @@ public class StopTransformAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/UpdateTransformAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/UpdateTransformAction.java index b2a764b0be5b0..6a2394463f4b9 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/UpdateTransformAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/UpdateTransformAction.java @@ -40,7 +40,7 @@ public class UpdateTransformAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/UpgradeTransformsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/UpgradeTransformsAction.java index 1f0f809571e69..b7dea916accbc 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/UpgradeTransformsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/UpgradeTransformsAction.java @@ -27,7 +27,7 @@ public class UpgradeTransformsAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/ValidateTransformAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/ValidateTransformAction.java index 34d737a4745db..10e086335825f 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/ValidateTransformAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/ValidateTransformAction.java @@ -27,7 +27,7 @@ public class ValidateTransformAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/QueryWatchesAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/QueryWatchesAction.java index 70ffdc98831f8..31c27cbe3d470 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/QueryWatchesAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/QueryWatchesAction.java @@ -41,7 +41,7 @@ public class QueryWatchesAction extends ActionType public static final String NAME = "cluster:monitor/xpack/watcher/watch/query"; private QueryWatchesAction() { - super(NAME, Response::new); + super(NAME); } public static class Request extends ActionRequest implements ToXContentObject { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/ack/AckWatchAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/ack/AckWatchAction.java index 5cba85377df98..4b147a6e799e1 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/ack/AckWatchAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/ack/AckWatchAction.java @@ -17,6 +17,6 @@ public class AckWatchAction extends ActionType { public static final String NAME = "cluster:admin/xpack/watcher/watch/ack"; private AckWatchAction() { - super(NAME, AckWatchResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/activate/ActivateWatchAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/activate/ActivateWatchAction.java index 6e1add022e4b3..d18ab74c33942 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/activate/ActivateWatchAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/activate/ActivateWatchAction.java @@ -17,6 +17,6 @@ public class ActivateWatchAction extends ActionType { public static final String NAME = "cluster:admin/xpack/watcher/watch/activate"; private ActivateWatchAction() { - super(NAME, ActivateWatchResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/delete/DeleteWatchAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/delete/DeleteWatchAction.java index 4d9cf9f6a896a..4003939f064a6 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/delete/DeleteWatchAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/delete/DeleteWatchAction.java @@ -18,6 +18,6 @@ public class DeleteWatchAction extends ActionType { public static final String NAME = "cluster:admin/xpack/watcher/watch/delete"; private DeleteWatchAction() { - super(NAME, DeleteWatchResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/execute/ExecuteWatchAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/execute/ExecuteWatchAction.java index bb5f92f20d7a8..7c6258b77d475 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/execute/ExecuteWatchAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/execute/ExecuteWatchAction.java @@ -18,6 +18,6 @@ public class ExecuteWatchAction extends ActionType { public static final String NAME = "cluster:admin/xpack/watcher/watch/execute"; private ExecuteWatchAction() { - super(NAME, ExecuteWatchResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/get/GetWatchAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/get/GetWatchAction.java index 004c9eece9b95..c464c37b1a3a5 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/get/GetWatchAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/get/GetWatchAction.java @@ -17,6 +17,6 @@ public class GetWatchAction extends ActionType { public static final String NAME = "cluster:monitor/xpack/watcher/watch/get"; private GetWatchAction() { - super(NAME, GetWatchResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/GetWatcherSettingsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/GetWatcherSettingsAction.java index cc3339d68d81a..576bd220853ce 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/GetWatcherSettingsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/GetWatcherSettingsAction.java @@ -25,7 +25,7 @@ public class GetWatcherSettingsAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/PutWatchAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/PutWatchAction.java index d8b255d433132..7235577c7cdac 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/PutWatchAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/PutWatchAction.java @@ -18,6 +18,6 @@ public class PutWatchAction extends ActionType { public static final String NAME = "cluster:admin/xpack/watcher/watch/put"; private PutWatchAction() { - super(NAME, PutWatchResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/UpdateWatcherSettingsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/UpdateWatcherSettingsAction.java index f8d0ade06e022..29f4db51e146e 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/UpdateWatcherSettingsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/UpdateWatcherSettingsAction.java @@ -32,7 +32,7 @@ public class UpdateWatcherSettingsAction extends ActionType { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/service/WatcherServiceAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/service/WatcherServiceAction.java index 80af58d655dda..0a5bf62c73dc7 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/service/WatcherServiceAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/service/WatcherServiceAction.java @@ -15,6 +15,6 @@ public class WatcherServiceAction extends ActionType { public static final String NAME = "cluster:admin/xpack/watcher/service"; private WatcherServiceAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/stats/WatcherStatsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/stats/WatcherStatsAction.java index 5e102ad446087..1cbbf35101eb2 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/stats/WatcherStatsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/stats/WatcherStatsAction.java @@ -7,7 +7,6 @@ package org.elasticsearch.xpack.core.watcher.transport.actions.stats; import org.elasticsearch.action.ActionType; -import org.elasticsearch.common.io.stream.Writeable; /** * This ActionType gets the stats for the watcher plugin @@ -18,6 +17,6 @@ public class WatcherStatsAction extends ActionType { public static final String NAME = "cluster:monitor/xpack/watcher/stats/dist"; private WatcherStatsAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } } diff --git a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationInfoAction.java b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationInfoAction.java index 0351db53b6c69..13ef198863284 100644 --- a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationInfoAction.java +++ b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationInfoAction.java @@ -52,7 +52,7 @@ public class DeprecationInfoAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/DownsampleShardPersistentTaskExecutor.java b/x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/DownsampleShardPersistentTaskExecutor.java index ebf31bd32b48f..f500ce986f6dd 100644 --- a/x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/DownsampleShardPersistentTaskExecutor.java +++ b/x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/DownsampleShardPersistentTaskExecutor.java @@ -241,7 +241,7 @@ public static class DelegatingAction extends ActionType { public static final String NAME = "indices:data/read/downsample_delegate"; private DelegatingAction() { - super(NAME, in -> new ActionResponse.Empty()); + super(NAME); } public static class Request extends ActionRequest implements IndicesRequest { diff --git a/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichCoordinatorProxyAction.java b/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichCoordinatorProxyAction.java index 5e0e7a6314d67..af5791ac6efd1 100644 --- a/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichCoordinatorProxyAction.java +++ b/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichCoordinatorProxyAction.java @@ -53,7 +53,7 @@ public class EnrichCoordinatorProxyAction extends ActionType { public static final String NAME = "indices:data/read/xpack/enrich/coordinate_lookups"; private EnrichCoordinatorProxyAction() { - super(NAME, SearchResponse::new); + super(NAME); } public static class TransportAction extends HandledTransportAction { diff --git a/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichCoordinatorStatsAction.java b/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichCoordinatorStatsAction.java index 1bd3b5c121c06..f40f14059772e 100644 --- a/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichCoordinatorStatsAction.java +++ b/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichCoordinatorStatsAction.java @@ -20,7 +20,6 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportRequest; @@ -42,7 +41,7 @@ public class EnrichCoordinatorStatsAction extends ActionType { public static final EnrichReindexAction INSTANCE = new EnrichReindexAction(); private EnrichReindexAction() { - super(NAME, BulkByScrollResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichShardMultiSearchAction.java b/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichShardMultiSearchAction.java index cbede83f15107..2aa30614b58f3 100644 --- a/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichShardMultiSearchAction.java +++ b/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichShardMultiSearchAction.java @@ -96,7 +96,7 @@ public class EnrichShardMultiSearchAction extends ActionType { diff --git a/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/InternalExecutePolicyAction.java b/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/InternalExecutePolicyAction.java index e606f6ac8ea9c..769a86c5ec5b1 100644 --- a/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/InternalExecutePolicyAction.java +++ b/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/InternalExecutePolicyAction.java @@ -61,7 +61,7 @@ public class InternalExecutePolicyAction extends ActionType { public static final String NAME = "cluster:admin/xpack/enrich/internal_execute"; private InternalExecutePolicyAction() { - super(NAME, Response::new); + super(NAME); } public static class Request extends ExecuteEnrichPolicyAction.Request { diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/analytics/action/DeleteAnalyticsCollectionAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/analytics/action/DeleteAnalyticsCollectionAction.java index f80628c2f342f..24e4e95d4bd42 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/analytics/action/DeleteAnalyticsCollectionAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/analytics/action/DeleteAnalyticsCollectionAction.java @@ -32,7 +32,7 @@ public class DeleteAnalyticsCollectionAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/analytics/action/GetAnalyticsCollectionAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/analytics/action/GetAnalyticsCollectionAction.java index acabe85af51b5..f0f0e323ba0aa 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/analytics/action/GetAnalyticsCollectionAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/analytics/action/GetAnalyticsCollectionAction.java @@ -34,7 +34,7 @@ public class GetAnalyticsCollectionAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/analytics/action/PostAnalyticsEventAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/analytics/action/PostAnalyticsEventAction.java index 67599e565b816..4876af261b1c6 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/analytics/action/PostAnalyticsEventAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/analytics/action/PostAnalyticsEventAction.java @@ -43,7 +43,7 @@ public class PostAnalyticsEventAction extends ActionType implements ToXContentObject { diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/DeleteConnectorAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/DeleteConnectorAction.java index fab57921772d9..79a6bcce4a3c8 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/DeleteConnectorAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/DeleteConnectorAction.java @@ -32,7 +32,7 @@ public class DeleteConnectorAction extends ActionType { public static final String NAME = "cluster:admin/xpack/connector/delete"; private DeleteConnectorAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends ActionRequest implements ToXContentObject { diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/GetConnectorAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/GetConnectorAction.java index 9d97b6787c243..4cebe5b44bc90 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/GetConnectorAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/GetConnectorAction.java @@ -33,7 +33,7 @@ public class GetConnectorAction extends ActionType public static final String NAME = "cluster:admin/xpack/connector/get"; private GetConnectorAction() { - super(NAME, GetConnectorAction.Response::new); + super(NAME); } public static class Request extends ActionRequest implements ToXContentObject { diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/ListConnectorAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/ListConnectorAction.java index 70cee8b064c71..47ab30f2a955a 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/ListConnectorAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/ListConnectorAction.java @@ -34,7 +34,7 @@ public class ListConnectorAction extends ActionType public static final String NAME = "cluster:admin/xpack/connector/put"; public PutConnectorAction() { - super(NAME, PutConnectorAction.Response::new); + super(NAME); } public static class Request extends ActionRequest implements ToXContentObject { diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/UpdateConnectorConfigurationAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/UpdateConnectorConfigurationAction.java index e1c41cf90968c..6e598b8b0fa2e 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/UpdateConnectorConfigurationAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/UpdateConnectorConfigurationAction.java @@ -40,7 +40,7 @@ public class UpdateConnectorConfigurationAction extends ActionType { public static final String NAME = "cluster:admin/xpack/query_rules/delete"; private DeleteQueryRulesetAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends ActionRequest implements ToXContentObject { diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/action/GetQueryRulesetAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/action/GetQueryRulesetAction.java index 191bf4a806f0f..6045af27c03c8 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/action/GetQueryRulesetAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/action/GetQueryRulesetAction.java @@ -35,7 +35,7 @@ public class GetQueryRulesetAction extends ActionType { public static final String NAME = "indices:data/read/xpack/application/search_application/search"; public QuerySearchApplicationAction() { - super(NAME, SearchResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/search/action/RenderSearchApplicationQueryAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/search/action/RenderSearchApplicationQueryAction.java index b70152c1c3c23..6f74021bd387d 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/search/action/RenderSearchApplicationQueryAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/search/action/RenderSearchApplicationQueryAction.java @@ -25,7 +25,7 @@ public class RenderSearchApplicationQueryAction extends ActionType { public static final String NAME = "indices:data/read/eql"; private EqlSearchAction() { - super(NAME, EqlSearchResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/EqlAsyncGetResultAction.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/EqlAsyncGetResultAction.java index 4b7edcd24b34e..2bd7032f49b4a 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/EqlAsyncGetResultAction.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/EqlAsyncGetResultAction.java @@ -14,6 +14,6 @@ public class EqlAsyncGetResultAction extends ActionType { public static final EqlAsyncGetResultAction INSTANCE = new EqlAsyncGetResultAction(); private EqlAsyncGetResultAction() { - super(EqlAsyncActionNames.EQL_ASYNC_GET_RESULT_ACTION_NAME, EqlSearchResponse::new); + super(EqlAsyncActionNames.EQL_ASYNC_GET_RESULT_ACTION_NAME); } } diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/EqlAsyncGetStatusAction.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/EqlAsyncGetStatusAction.java index 24d6fd6fee68a..46e94a669fa59 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/EqlAsyncGetStatusAction.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/EqlAsyncGetStatusAction.java @@ -14,6 +14,6 @@ public class EqlAsyncGetStatusAction extends ActionType { public static final String NAME = "cluster:monitor/eql/async/status"; private EqlAsyncGetStatusAction() { - super(NAME, QlStatusResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/EqlStatsAction.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/EqlStatsAction.java index 4c68c7ef155d1..29c9eb6237fd8 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/EqlStatsAction.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/EqlStatsAction.java @@ -8,7 +8,6 @@ package org.elasticsearch.xpack.eql.plugin; import org.elasticsearch.action.ActionType; -import org.elasticsearch.common.io.stream.Writeable; public class EqlStatsAction extends ActionType { @@ -16,6 +15,6 @@ public class EqlStatsAction extends ActionType { public static final String NAME = "cluster:monitor/xpack/eql/stats/dist"; private EqlStatsAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlAsyncGetResultAction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlAsyncGetResultAction.java index f6593dccb9c49..ee153c5b29b2f 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlAsyncGetResultAction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlAsyncGetResultAction.java @@ -17,6 +17,6 @@ public class EsqlAsyncGetResultAction extends ActionType { public static final String NAME = EsqlAsyncActionNames.ESQL_ASYNC_GET_RESULT_ACTION_NAME; private EsqlAsyncGetResultAction() { - super(NAME, in -> { throw new IllegalArgumentException("can't transport EsqlAsyncGetResultAction"); }); + super(NAME); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryAction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryAction.java index 13b5b067f5cc9..901a01dcf857e 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryAction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryAction.java @@ -15,6 +15,6 @@ public class EsqlQueryAction extends ActionType { public static final String NAME = "indices:data/read/esql"; private EsqlQueryAction() { - super(NAME, in -> { throw new IllegalArgumentException("can't transport EsqlQuery"); }); + super(NAME); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlStatsAction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlStatsAction.java index 0c23f5f05af6f..98a9a4a9e8a5e 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlStatsAction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlStatsAction.java @@ -8,7 +8,6 @@ package org.elasticsearch.xpack.esql.plugin; import org.elasticsearch.action.ActionType; -import org.elasticsearch.common.io.stream.Writeable; public class EsqlStatsAction extends ActionType { @@ -16,6 +15,6 @@ public class EsqlStatsAction extends ActionType { public static final String NAME = "cluster:monitor/xpack/esql/stats/dist"; private EsqlStatsAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } } diff --git a/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/action/DeleteSecretAction.java b/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/action/DeleteSecretAction.java index 4245b2fca52a6..38103c82ee5e7 100644 --- a/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/action/DeleteSecretAction.java +++ b/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/action/DeleteSecretAction.java @@ -16,6 +16,6 @@ public class DeleteSecretAction extends ActionType { public static final DeleteSecretAction INSTANCE = new DeleteSecretAction(); private DeleteSecretAction() { - super(NAME, DeleteSecretResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/action/GetGlobalCheckpointsAction.java b/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/action/GetGlobalCheckpointsAction.java index 1e3794a4cefe4..a87297702bd30 100644 --- a/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/action/GetGlobalCheckpointsAction.java +++ b/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/action/GetGlobalCheckpointsAction.java @@ -28,7 +28,6 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.util.concurrent.AtomicArray; import org.elasticsearch.common.util.concurrent.CountDown; import org.elasticsearch.core.TimeValue; @@ -55,7 +54,7 @@ public class GetGlobalCheckpointsAction extends ActionType { public static final GetSecretAction INSTANCE = new GetSecretAction(); private GetSecretAction() { - super(NAME, GetSecretResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/action/PostSecretAction.java b/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/action/PostSecretAction.java index c0a0a0bff4fe6..bb30bce36cc48 100644 --- a/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/action/PostSecretAction.java +++ b/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/action/PostSecretAction.java @@ -16,6 +16,6 @@ public class PostSecretAction extends ActionType { public static final PostSecretAction INSTANCE = new PostSecretAction(); private PostSecretAction() { - super(NAME, PostSecretResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/action/DeleteSamlServiceProviderAction.java b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/action/DeleteSamlServiceProviderAction.java index 080cd202c6f0d..38971be7d5062 100644 --- a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/action/DeleteSamlServiceProviderAction.java +++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/action/DeleteSamlServiceProviderAction.java @@ -18,6 +18,6 @@ public class DeleteSamlServiceProviderAction extends ActionType { public static final SamlMetadataAction INSTANCE = new SamlMetadataAction(); private SamlMetadataAction() { - super(NAME, SamlMetadataResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/action/SamlValidateAuthnRequestAction.java b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/action/SamlValidateAuthnRequestAction.java index 0bca97eb3a1fb..baa337ccc72c3 100644 --- a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/action/SamlValidateAuthnRequestAction.java +++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/action/SamlValidateAuthnRequestAction.java @@ -14,6 +14,6 @@ public class SamlValidateAuthnRequestAction extends ActionType { public static final DeletePipelineAction INSTANCE = new DeletePipelineAction(); private DeletePipelineAction() { - super(NAME, DeletePipelineResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/logstash/src/main/java/org/elasticsearch/xpack/logstash/action/GetPipelineAction.java b/x-pack/plugin/logstash/src/main/java/org/elasticsearch/xpack/logstash/action/GetPipelineAction.java index 33ed6646597fc..5c3ac908a8f59 100644 --- a/x-pack/plugin/logstash/src/main/java/org/elasticsearch/xpack/logstash/action/GetPipelineAction.java +++ b/x-pack/plugin/logstash/src/main/java/org/elasticsearch/xpack/logstash/action/GetPipelineAction.java @@ -15,6 +15,6 @@ public class GetPipelineAction extends ActionType { public static final GetPipelineAction INSTANCE = new GetPipelineAction(); private GetPipelineAction() { - super(NAME, GetPipelineResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/logstash/src/main/java/org/elasticsearch/xpack/logstash/action/PutPipelineAction.java b/x-pack/plugin/logstash/src/main/java/org/elasticsearch/xpack/logstash/action/PutPipelineAction.java index 9067321d24d48..f57adde81ab78 100644 --- a/x-pack/plugin/logstash/src/main/java/org/elasticsearch/xpack/logstash/action/PutPipelineAction.java +++ b/x-pack/plugin/logstash/src/main/java/org/elasticsearch/xpack/logstash/action/PutPipelineAction.java @@ -15,6 +15,6 @@ public class PutPipelineAction extends ActionType { public static final PutPipelineAction INSTANCE = new PutPipelineAction(); private PutPipelineAction() { - super(NAME, PutPipelineResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/GetFlamegraphAction.java b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/GetFlamegraphAction.java index fc04f735fdf87..3719722ad2d62 100644 --- a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/GetFlamegraphAction.java +++ b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/GetFlamegraphAction.java @@ -7,13 +7,12 @@ package org.elasticsearch.xpack.profiling; import org.elasticsearch.action.ActionType; -import org.elasticsearch.common.io.stream.Writeable; public final class GetFlamegraphAction extends ActionType { public static final GetFlamegraphAction INSTANCE = new GetFlamegraphAction(); public static final String NAME = "indices:data/read/profiling/flamegraph"; private GetFlamegraphAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } } diff --git a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/GetStackTracesAction.java b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/GetStackTracesAction.java index 84ab6643be781..1fd87740d6292 100644 --- a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/GetStackTracesAction.java +++ b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/GetStackTracesAction.java @@ -7,13 +7,12 @@ package org.elasticsearch.xpack.profiling; import org.elasticsearch.action.ActionType; -import org.elasticsearch.common.io.stream.Writeable; public final class GetStackTracesAction extends ActionType { public static final GetStackTracesAction INSTANCE = new GetStackTracesAction(); public static final String NAME = "indices:data/read/profiling/stack_traces"; private GetStackTracesAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } } diff --git a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/GetStatusAction.java b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/GetStatusAction.java index 2a6b18767d4e9..59132d45995e3 100644 --- a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/GetStatusAction.java +++ b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/GetStatusAction.java @@ -25,7 +25,7 @@ public class GetStatusAction extends ActionType { public static final String NAME = "cluster:monitor/profiling/status/get"; protected GetStatusAction() { - super(NAME, GetStatusAction.Response::new); + super(NAME); } public static class Response extends ActionResponse implements ToXContentObject { diff --git a/x-pack/plugin/repositories-metering-api/src/main/java/org/elasticsearch/xpack/repositories/metering/action/ClearRepositoriesMeteringArchiveAction.java b/x-pack/plugin/repositories-metering-api/src/main/java/org/elasticsearch/xpack/repositories/metering/action/ClearRepositoriesMeteringArchiveAction.java index 30b5b50be89c6..714b8a7d9965a 100644 --- a/x-pack/plugin/repositories-metering-api/src/main/java/org/elasticsearch/xpack/repositories/metering/action/ClearRepositoriesMeteringArchiveAction.java +++ b/x-pack/plugin/repositories-metering-api/src/main/java/org/elasticsearch/xpack/repositories/metering/action/ClearRepositoriesMeteringArchiveAction.java @@ -8,7 +8,6 @@ package org.elasticsearch.xpack.repositories.metering.action; import org.elasticsearch.action.ActionType; -import org.elasticsearch.common.io.stream.Writeable; public final class ClearRepositoriesMeteringArchiveAction extends ActionType { public static final ClearRepositoriesMeteringArchiveAction INSTANCE = new ClearRepositoriesMeteringArchiveAction(); @@ -16,6 +15,6 @@ public final class ClearRepositoriesMeteringArchiveAction extends ActionType { public static final RepositoriesMeteringAction INSTANCE = new RepositoriesMeteringAction(); @@ -16,6 +15,6 @@ public final class RepositoriesMeteringAction extends ActionType { public static final FrozenCacheInfoAction INSTANCE = new FrozenCacheInfoAction(); private FrozenCacheInfoAction() { - super(NAME, FrozenCacheInfoResponse::new); + super(NAME); } public static class Request extends ActionRequest { diff --git a/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/action/cache/FrozenCacheInfoNodeAction.java b/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/action/cache/FrozenCacheInfoNodeAction.java index bb34940628d23..756f9c191a561 100644 --- a/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/action/cache/FrozenCacheInfoNodeAction.java +++ b/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/action/cache/FrozenCacheInfoNodeAction.java @@ -30,7 +30,7 @@ public class FrozenCacheInfoNodeAction extends ActionType TYPE = new ActionType<>(ACTION_NAME, Writeable.Reader.localOnly()); + public static final ActionType TYPE = new ActionType<>(ACTION_NAME); private final CacheService cacheService; diff --git a/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/action/cache/TransportSearchableSnapshotsNodeCachesStatsAction.java b/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/action/cache/TransportSearchableSnapshotsNodeCachesStatsAction.java index c192d5bff8eb9..9a40b39083139 100644 --- a/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/action/cache/TransportSearchableSnapshotsNodeCachesStatsAction.java +++ b/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/action/cache/TransportSearchableSnapshotsNodeCachesStatsAction.java @@ -22,7 +22,6 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.tasks.Task; @@ -52,7 +51,7 @@ public class TransportSearchableSnapshotsNodeCachesStatsAction extends Transport public static final String ACTION_NAME = "cluster:admin/xpack/searchable_snapshots/cache/stats"; - public static final ActionType TYPE = new ActionType<>(ACTION_NAME, Writeable.Reader.localOnly()); + public static final ActionType TYPE = new ActionType<>(ACTION_NAME); private final Supplier> frozenCacheService; private final XPackLicenseState licenseState; diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/saml/TransportSamlCompleteLogoutAction.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/saml/TransportSamlCompleteLogoutAction.java index 7b45313b0e24f..500ef7c51f4bc 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/saml/TransportSamlCompleteLogoutAction.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/saml/TransportSamlCompleteLogoutAction.java @@ -30,9 +30,7 @@ */ public final class TransportSamlCompleteLogoutAction extends HandledTransportAction { - public static final ActionType TYPE = ActionType.emptyResponse( - "cluster:admin/xpack/security/saml/complete_logout" - ); + public static final ActionType TYPE = new ActionType<>("cluster:admin/xpack/security/saml/complete_logout"); private final Realms realms; @Inject diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/user/TransportChangePasswordAction.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/user/TransportChangePasswordAction.java index fc8f931612907..b696c93cf6899 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/user/TransportChangePasswordAction.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/user/TransportChangePasswordAction.java @@ -26,9 +26,7 @@ public class TransportChangePasswordAction extends HandledTransportAction { - public static final ActionType TYPE = ActionType.emptyResponse( - "cluster:admin/xpack/security/user/change_password" - ); + public static final ActionType TYPE = new ActionType<>("cluster:admin/xpack/security/user/change_password"); private final Settings settings; private final NativeUsersStore nativeUsersStore; diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/user/TransportSetEnabledAction.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/user/TransportSetEnabledAction.java index 4647ac0cf5f66..70670840a912d 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/user/TransportSetEnabledAction.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/user/TransportSetEnabledAction.java @@ -28,7 +28,7 @@ */ public class TransportSetEnabledAction extends HandledTransportAction { - public static final ActionType TYPE = ActionType.emptyResponse("cluster:admin/xpack/security/user/set_enabled"); + public static final ActionType TYPE = new ActionType<>("cluster:admin/xpack/security/user/set_enabled"); private final Settings settings; private final SecurityContext securityContext; private final NativeUsersStore usersStore; diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/DeleteShutdownNodeAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/DeleteShutdownNodeAction.java index 153945e933d77..75c36f063f805 100644 --- a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/DeleteShutdownNodeAction.java +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/DeleteShutdownNodeAction.java @@ -23,7 +23,7 @@ public class DeleteShutdownNodeAction extends ActionType { public static final String NAME = "cluster:admin/shutdown/delete"; public DeleteShutdownNodeAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/GetShutdownStatusAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/GetShutdownStatusAction.java index 75afc9e0c05c5..b82e6a08fb269 100644 --- a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/GetShutdownStatusAction.java +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/GetShutdownStatusAction.java @@ -35,7 +35,7 @@ public class GetShutdownStatusAction extends ActionType { diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/PutShutdownNodeAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/PutShutdownNodeAction.java index 0e378eb196724..d05b60cd947f5 100644 --- a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/PutShutdownNodeAction.java +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/PutShutdownNodeAction.java @@ -33,7 +33,7 @@ public class PutShutdownNodeAction extends ActionType { public static final String NAME = "cluster:admin/shutdown/create"; public PutShutdownNodeAction() { - super(NAME, AcknowledgedResponse::readFrom); + super(NAME); } public static class Request extends AcknowledgedRequest { diff --git a/x-pack/plugin/slm/src/main/java/org/elasticsearch/xpack/slm/TransportSLMGetExpiredSnapshotsAction.java b/x-pack/plugin/slm/src/main/java/org/elasticsearch/xpack/slm/TransportSLMGetExpiredSnapshotsAction.java index 050562f0162c9..b1ec8f3a28f1b 100644 --- a/x-pack/plugin/slm/src/main/java/org/elasticsearch/xpack/slm/TransportSLMGetExpiredSnapshotsAction.java +++ b/x-pack/plugin/slm/src/main/java/org/elasticsearch/xpack/slm/TransportSLMGetExpiredSnapshotsAction.java @@ -58,7 +58,7 @@ public class TransportSLMGetExpiredSnapshotsAction extends TransportAction< TransportSLMGetExpiredSnapshotsAction.Request, TransportSLMGetExpiredSnapshotsAction.Response> { - public static final ActionType INSTANCE = ActionType.localOnly("cluster:admin/slm/execute/get_expired_snapshots"); + public static final ActionType INSTANCE = new ActionType<>("cluster:admin/slm/execute/get_expired_snapshots"); private static final Logger logger = LogManager.getLogger(TransportSLMGetExpiredSnapshotsAction.class); diff --git a/x-pack/plugin/snapshot-repo-test-kit/src/main/java/org/elasticsearch/repositories/blobstore/testkit/RepositoryAnalyzeAction.java b/x-pack/plugin/snapshot-repo-test-kit/src/main/java/org/elasticsearch/repositories/blobstore/testkit/RepositoryAnalyzeAction.java index cad66019a3bbb..5e7f5dfdc855d 100644 --- a/x-pack/plugin/snapshot-repo-test-kit/src/main/java/org/elasticsearch/repositories/blobstore/testkit/RepositoryAnalyzeAction.java +++ b/x-pack/plugin/snapshot-repo-test-kit/src/main/java/org/elasticsearch/repositories/blobstore/testkit/RepositoryAnalyzeAction.java @@ -96,7 +96,7 @@ public class RepositoryAnalyzeAction extends HandledTransportAction INSTANCE = ActionType.localOnly("cluster:admin/repository/analyze"); + public static final ActionType INSTANCE = new ActionType<>("cluster:admin/repository/analyze"); static final String UNCONTENDED_REGISTER_NAME_PREFIX = "test-register-uncontended-"; static final String CONTENDED_REGISTER_NAME_PREFIX = "test-register-contended-"; diff --git a/x-pack/plugin/sql/sql-action/src/main/java/org/elasticsearch/xpack/sql/action/SqlClearCursorAction.java b/x-pack/plugin/sql/sql-action/src/main/java/org/elasticsearch/xpack/sql/action/SqlClearCursorAction.java index 5b0e8ce5a2d11..568fcc8275732 100644 --- a/x-pack/plugin/sql/sql-action/src/main/java/org/elasticsearch/xpack/sql/action/SqlClearCursorAction.java +++ b/x-pack/plugin/sql/sql-action/src/main/java/org/elasticsearch/xpack/sql/action/SqlClearCursorAction.java @@ -14,6 +14,6 @@ public class SqlClearCursorAction extends ActionType { public static final String NAME = "indices:data/read/sql/close_cursor"; private SqlClearCursorAction() { - super(NAME, SqlClearCursorResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/sql/sql-action/src/main/java/org/elasticsearch/xpack/sql/action/SqlQueryAction.java b/x-pack/plugin/sql/sql-action/src/main/java/org/elasticsearch/xpack/sql/action/SqlQueryAction.java index d374356a81229..7640363721e91 100644 --- a/x-pack/plugin/sql/sql-action/src/main/java/org/elasticsearch/xpack/sql/action/SqlQueryAction.java +++ b/x-pack/plugin/sql/sql-action/src/main/java/org/elasticsearch/xpack/sql/action/SqlQueryAction.java @@ -14,6 +14,6 @@ public class SqlQueryAction extends ActionType { public static final String NAME = "indices:data/read/sql"; private SqlQueryAction() { - super(NAME, SqlQueryResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/sql/sql-action/src/main/java/org/elasticsearch/xpack/sql/action/SqlTranslateAction.java b/x-pack/plugin/sql/sql-action/src/main/java/org/elasticsearch/xpack/sql/action/SqlTranslateAction.java index df6f202886ab7..5fefc30b33d25 100644 --- a/x-pack/plugin/sql/sql-action/src/main/java/org/elasticsearch/xpack/sql/action/SqlTranslateAction.java +++ b/x-pack/plugin/sql/sql-action/src/main/java/org/elasticsearch/xpack/sql/action/SqlTranslateAction.java @@ -17,6 +17,6 @@ public class SqlTranslateAction extends ActionType { public static final String NAME = "indices:data/read/sql/translate"; private SqlTranslateAction() { - super(NAME, SqlTranslateResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlAsyncGetResultsAction.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlAsyncGetResultsAction.java index cf3c422901877..01790a8749430 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlAsyncGetResultsAction.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlAsyncGetResultsAction.java @@ -16,6 +16,6 @@ public class SqlAsyncGetResultsAction extends ActionType { public static final String NAME = SQL_ASYNC_GET_RESULT_ACTION_NAME; private SqlAsyncGetResultsAction() { - super(NAME, SqlQueryResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlAsyncGetStatusAction.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlAsyncGetStatusAction.java index 366d8c606f86b..22732b1b53f4a 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlAsyncGetStatusAction.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlAsyncGetStatusAction.java @@ -16,6 +16,6 @@ public class SqlAsyncGetStatusAction extends ActionType { public static final String NAME = SQL_ASYNC_GET_STATUS_ACTION_NAME; private SqlAsyncGetStatusAction() { - super(NAME, QlStatusResponse::new); + super(NAME); } } diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlStatsAction.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlStatsAction.java index 1a7afdce307ed..ccff0e20a4b62 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlStatsAction.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlStatsAction.java @@ -8,7 +8,6 @@ package org.elasticsearch.xpack.sql.plugin; import org.elasticsearch.action.ActionType; -import org.elasticsearch.common.io.stream.Writeable; public class SqlStatsAction extends ActionType { @@ -16,6 +15,6 @@ public class SqlStatsAction extends ActionType { public static final String NAME = "cluster:monitor/xpack/sql/stats/dist"; private SqlStatsAction() { - super(NAME, Writeable.Reader.localOnly()); + super(NAME); } } From 55ba6fe41cf46a25f17f7203adba7471806d908c Mon Sep 17 00:00:00 2001 From: David Turner Date: Thu, 25 Jan 2024 08:38:42 +0000 Subject: [PATCH 21/37] Reinstate compat shim lost in #104650 --- .../org/elasticsearch/action/ActionType.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/server/src/main/java/org/elasticsearch/action/ActionType.java b/server/src/main/java/org/elasticsearch/action/ActionType.java index fa8cb0006d587..51927baf7b4db 100644 --- a/server/src/main/java/org/elasticsearch/action/ActionType.java +++ b/server/src/main/java/org/elasticsearch/action/ActionType.java @@ -26,6 +26,22 @@ @SuppressWarnings("unused") // Response type arg is used to enable better type inference when calling Client#execute public class ActionType { + /** + * Construct an {@link ActionType} with the given name. + *

+ * There is no facility for directly executing an action on a different node in the local cluster. To achieve this, implement an action + * which runs on the local node and knows how to use the {@link TransportService} to forward the request to a different node. There are + * several utilities that help implement such an action, including {@link TransportNodesAction} or {@link TransportMasterNodeAction}. + * + * @param name The name of the action, which must be unique across actions. + * @return an {@link ActionType} which callers can execute on the local node. + * @deprecated Just create the {@link ActionType} directly. + */ + @Deprecated(forRemoval = true) + public static ActionType localOnly(String name) { + return new ActionType<>(name); + } + private final String name; /** From bec2115f8ffd2e6efedf3776a733d8c42a98e625 Mon Sep 17 00:00:00 2001 From: David Turner Date: Thu, 25 Jan 2024 09:42:01 +0000 Subject: [PATCH 22/37] Remove `ThreadPool` arg from `TransportResponseHandler#executor` (#104554) This was needed temporarily to support some earlier refactoring work, but is now unnecessary. --- .../action/ActionListenerResponseHandler.java | 3 +- .../TransportReplicationAction.java | 2 +- .../coordination/FollowersChecker.java | 3 +- .../cluster/coordination/JoinHelper.java | 4 +- .../cluster/coordination/LeaderChecker.java | 3 +- .../StatefulPreVoteCollector.java | 3 +- .../elasticsearch/discovery/PeerFinder.java | 3 +- .../RetentionLeaseBackgroundSyncAction.java | 2 +- .../index/seqno/RetentionLeaseSyncAction.java | 2 +- .../recovery/PeerRecoveryTargetService.java | 2 +- .../indices/store/IndicesStore.java | 2 +- .../VerifyNodeRepositoryAction.java | 2 +- .../tasks/TaskCancellationService.java | 5 +- .../ForkingResponseHandlerRunnable.java | 9 +-- .../transport/InboundHandler.java | 8 +-- .../transport/SniffConnectionStrategy.java | 2 +- .../transport/TransportActionProxy.java | 3 +- .../transport/TransportHandshaker.java | 2 +- .../transport/TransportResponseHandler.java | 5 +- .../transport/TransportService.java | 26 ++++---- ...tAddVotingConfigExclusionsActionTests.java | 2 +- ...learVotingConfigExclusionsActionTests.java | 2 +- ...ReplicationAllPermitsAcquisitionTests.java | 2 +- .../coordination/FollowersCheckerTests.java | 11 ++-- .../coordination/LeaderCheckerTests.java | 19 +++--- .../StatefulPreVoteCollectorTests.java | 3 +- .../discovery/PeerFinderTests.java | 2 +- .../tasks/BanFailureLoggingTests.java | 2 +- .../transport/InboundHandlerTests.java | 2 +- .../transport/TransportActionProxyTests.java | 8 +-- ...ortServiceDeserializationFailureTests.java | 5 +- .../TransportServiceLifecycleTests.java | 4 +- .../test/disruption/NetworkDisruptionIT.java | 3 +- .../AbstractSimpleTransportTestCase.java | 60 +++++++++---------- .../DisruptableMockTransportTests.java | 6 +- .../action/TransportTermsEnumAction.java | 2 +- ...curityServerTransportInterceptorTests.java | 12 ++-- .../votingonly/VotingOnlyNodePlugin.java | 4 +- 38 files changed, 113 insertions(+), 127 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/action/ActionListenerResponseHandler.java b/server/src/main/java/org/elasticsearch/action/ActionListenerResponseHandler.java index 4800ba191edf7..f511d5a333062 100644 --- a/server/src/main/java/org/elasticsearch/action/ActionListenerResponseHandler.java +++ b/server/src/main/java/org/elasticsearch/action/ActionListenerResponseHandler.java @@ -11,7 +11,6 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.util.concurrent.EsExecutors; -import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportException; import org.elasticsearch.transport.TransportResponse; import org.elasticsearch.transport.TransportResponseHandler; @@ -55,7 +54,7 @@ public void handleException(TransportException e) { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return executor; } diff --git a/server/src/main/java/org/elasticsearch/action/support/replication/TransportReplicationAction.java b/server/src/main/java/org/elasticsearch/action/support/replication/TransportReplicationAction.java index 0abe7ad678dc5..a935c0e4e06bb 100644 --- a/server/src/main/java/org/elasticsearch/action/support/replication/TransportReplicationAction.java +++ b/server/src/main/java/org/elasticsearch/action/support/replication/TransportReplicationAction.java @@ -961,7 +961,7 @@ public Response read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/main/java/org/elasticsearch/cluster/coordination/FollowersChecker.java b/server/src/main/java/org/elasticsearch/cluster/coordination/FollowersChecker.java index feb0543aad625..cdd21efce3ed5 100644 --- a/server/src/main/java/org/elasticsearch/cluster/coordination/FollowersChecker.java +++ b/server/src/main/java/org/elasticsearch/cluster/coordination/FollowersChecker.java @@ -27,7 +27,6 @@ import org.elasticsearch.core.TimeValue; import org.elasticsearch.monitor.NodeHealthService; import org.elasticsearch.monitor.StatusInfo; -import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool.Names; import org.elasticsearch.transport.ConnectTransportException; import org.elasticsearch.transport.ReceiveTimeoutTransportException; @@ -307,7 +306,7 @@ private void handleWakeUp() { new TransportResponseHandler.Empty() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/main/java/org/elasticsearch/cluster/coordination/JoinHelper.java b/server/src/main/java/org/elasticsearch/cluster/coordination/JoinHelper.java index d11d8ade2a036..815f531e50e3b 100644 --- a/server/src/main/java/org/elasticsearch/cluster/coordination/JoinHelper.java +++ b/server/src/main/java/org/elasticsearch/cluster/coordination/JoinHelper.java @@ -317,7 +317,7 @@ public void onResponse(Void unused) { TransportRequestOptions.of(null, TransportRequestOptions.Type.PING), new TransportResponseHandler.Empty() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -379,7 +379,7 @@ void sendStartJoinRequest(final StartJoinRequest startJoinRequest, final Discove : "sending start-join request for master-ineligible " + startJoinRequest.getMasterCandidateNode(); transportService.sendRequest(destination, START_JOIN_ACTION_NAME, startJoinRequest, new TransportResponseHandler.Empty() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/main/java/org/elasticsearch/cluster/coordination/LeaderChecker.java b/server/src/main/java/org/elasticsearch/cluster/coordination/LeaderChecker.java index 9fcae5bcf67f8..ccd97b569a029 100644 --- a/server/src/main/java/org/elasticsearch/cluster/coordination/LeaderChecker.java +++ b/server/src/main/java/org/elasticsearch/cluster/coordination/LeaderChecker.java @@ -26,7 +26,6 @@ import org.elasticsearch.core.TimeValue; import org.elasticsearch.monitor.NodeHealthService; import org.elasticsearch.monitor.StatusInfo; -import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool.Names; import org.elasticsearch.transport.ConnectTransportException; import org.elasticsearch.transport.NodeDisconnectedException; @@ -239,7 +238,7 @@ void handleWakeUp() { TransportRequestOptions.of(leaderCheckTimeout, Type.PING), new TransportResponseHandler.Empty() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/main/java/org/elasticsearch/cluster/coordination/StatefulPreVoteCollector.java b/server/src/main/java/org/elasticsearch/cluster/coordination/StatefulPreVoteCollector.java index 7bc3514206ffe..bf33f97f2ad42 100644 --- a/server/src/main/java/org/elasticsearch/cluster/coordination/StatefulPreVoteCollector.java +++ b/server/src/main/java/org/elasticsearch/cluster/coordination/StatefulPreVoteCollector.java @@ -18,7 +18,6 @@ import org.elasticsearch.core.Tuple; import org.elasticsearch.monitor.NodeHealthService; import org.elasticsearch.monitor.StatusInfo; -import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool.Names; import org.elasticsearch.transport.TransportException; import org.elasticsearch.transport.TransportResponseHandler; @@ -159,7 +158,7 @@ public void handleException(TransportException exp) { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return clusterCoordinationExecutor; } diff --git a/server/src/main/java/org/elasticsearch/discovery/PeerFinder.java b/server/src/main/java/org/elasticsearch/discovery/PeerFinder.java index 5289ac57e10ca..80f9f3917609e 100644 --- a/server/src/main/java/org/elasticsearch/discovery/PeerFinder.java +++ b/server/src/main/java/org/elasticsearch/discovery/PeerFinder.java @@ -24,7 +24,6 @@ import org.elasticsearch.core.Releasable; import org.elasticsearch.core.Releasables; import org.elasticsearch.core.TimeValue; -import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool.Names; import org.elasticsearch.transport.TransportException; import org.elasticsearch.transport.TransportRequestOptions; @@ -544,7 +543,7 @@ public void handleException(TransportException exp) { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return clusterCoordinationExecutor; } }; diff --git a/server/src/main/java/org/elasticsearch/index/seqno/RetentionLeaseBackgroundSyncAction.java b/server/src/main/java/org/elasticsearch/index/seqno/RetentionLeaseBackgroundSyncAction.java index 5046ea1cb4d0d..541e279d4cfbb 100644 --- a/server/src/main/java/org/elasticsearch/index/seqno/RetentionLeaseBackgroundSyncAction.java +++ b/server/src/main/java/org/elasticsearch/index/seqno/RetentionLeaseBackgroundSyncAction.java @@ -117,7 +117,7 @@ public ReplicationResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/main/java/org/elasticsearch/index/seqno/RetentionLeaseSyncAction.java b/server/src/main/java/org/elasticsearch/index/seqno/RetentionLeaseSyncAction.java index 469dcd09e8f63..d03a29922da07 100644 --- a/server/src/main/java/org/elasticsearch/index/seqno/RetentionLeaseSyncAction.java +++ b/server/src/main/java/org/elasticsearch/index/seqno/RetentionLeaseSyncAction.java @@ -127,7 +127,7 @@ public ReplicationResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/main/java/org/elasticsearch/indices/recovery/PeerRecoveryTargetService.java b/server/src/main/java/org/elasticsearch/indices/recovery/PeerRecoveryTargetService.java index a44c65f74c21d..3447cc73a4288 100644 --- a/server/src/main/java/org/elasticsearch/indices/recovery/PeerRecoveryTargetService.java +++ b/server/src/main/java/org/elasticsearch/indices/recovery/PeerRecoveryTargetService.java @@ -859,7 +859,7 @@ public void handleException(TransportException e) { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { // we do some heavy work like refreshes in the response so fork off to the generic threadpool return threadPool.generic(); } diff --git a/server/src/main/java/org/elasticsearch/indices/store/IndicesStore.java b/server/src/main/java/org/elasticsearch/indices/store/IndicesStore.java index d631c7a11d10c..e97d76638455a 100644 --- a/server/src/main/java/org/elasticsearch/indices/store/IndicesStore.java +++ b/server/src/main/java/org/elasticsearch/indices/store/IndicesStore.java @@ -257,7 +257,7 @@ public ShardActiveResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/main/java/org/elasticsearch/repositories/VerifyNodeRepositoryAction.java b/server/src/main/java/org/elasticsearch/repositories/VerifyNodeRepositoryAction.java index d940415c38916..bc4e0b3167f1b 100644 --- a/server/src/main/java/org/elasticsearch/repositories/VerifyNodeRepositoryAction.java +++ b/server/src/main/java/org/elasticsearch/repositories/VerifyNodeRepositoryAction.java @@ -93,7 +93,7 @@ public void verify(String repository, String verificationToken, final ActionList new VerifyNodeRepositoryRequest(repository, verificationToken), new TransportResponseHandler.Empty() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/main/java/org/elasticsearch/tasks/TaskCancellationService.java b/server/src/main/java/org/elasticsearch/tasks/TaskCancellationService.java index 6ab95072727c0..419f2d0726880 100644 --- a/server/src/main/java/org/elasticsearch/tasks/TaskCancellationService.java +++ b/server/src/main/java/org/elasticsearch/tasks/TaskCancellationService.java @@ -25,7 +25,6 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.util.concurrent.EsExecutors; import org.elasticsearch.common.util.concurrent.ListenableFuture; -import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.NodeDisconnectedException; import org.elasticsearch.transport.NodeNotConnectedException; import org.elasticsearch.transport.Transport; @@ -186,7 +185,7 @@ private void setBanOnChildConnections( TransportRequestOptions.EMPTY, new TransportResponseHandler.Empty() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -238,7 +237,7 @@ private void removeBanOnChildConnections(CancellableTask task, Collection handler, - @Nullable TransportException transportException, - ThreadPool threadPool - ) { - assert handler.executor(threadPool) != EsExecutors.DIRECT_EXECUTOR_SERVICE : "forking handler required, but got " + handler; + ForkingResponseHandlerRunnable(TransportResponseHandler handler, @Nullable TransportException transportException) { + assert handler.executor() != EsExecutors.DIRECT_EXECUTOR_SERVICE : "forking handler required, but got " + handler; this.handler = handler; this.transportException = transportException; } diff --git a/server/src/main/java/org/elasticsearch/transport/InboundHandler.java b/server/src/main/java/org/elasticsearch/transport/InboundHandler.java index 1686213139722..babea8c529d85 100644 --- a/server/src/main/java/org/elasticsearch/transport/InboundHandler.java +++ b/server/src/main/java/org/elasticsearch/transport/InboundHandler.java @@ -376,7 +376,7 @@ private void handleResponse( final TransportResponseHandler handler, final InboundMessage inboundMessage ) { - final var executor = handler.executor(threadPool); + final var executor = handler.executor(); if (executor == EsExecutors.DIRECT_EXECUTOR_SERVICE) { // no need to provide a buffer release here, we never escape the buffer when handling directly doHandleResponse(handler, remoteAddress, stream, inboundMessage.getHeader(), () -> {}); @@ -384,7 +384,7 @@ private void handleResponse( inboundMessage.mustIncRef(); // release buffer once we deserialize the message, but have a fail-safe in #onAfter below in case that didn't work out final Releasable releaseBuffer = Releasables.releaseOnce(inboundMessage::decRef); - executor.execute(new ForkingResponseHandlerRunnable(handler, null, threadPool) { + executor.execute(new ForkingResponseHandlerRunnable(handler, null) { @Override protected void doRun() { doHandleResponse(handler, remoteAddress, stream, inboundMessage.getHeader(), releaseBuffer); @@ -457,11 +457,11 @@ private void handlerResponseError(StreamInput stream, InboundMessage message, fi } private void handleException(final TransportResponseHandler handler, TransportException transportException) { - final var executor = handler.executor(threadPool); + final var executor = handler.executor(); if (executor == EsExecutors.DIRECT_EXECUTOR_SERVICE) { doHandleException(handler, transportException); } else { - executor.execute(new ForkingResponseHandlerRunnable(handler, transportException, threadPool) { + executor.execute(new ForkingResponseHandlerRunnable(handler, transportException) { @Override protected void doRun() { doHandleException(handler, transportException); diff --git a/server/src/main/java/org/elasticsearch/transport/SniffConnectionStrategy.java b/server/src/main/java/org/elasticsearch/transport/SniffConnectionStrategy.java index 0f68a58faf463..75903b5bf72ab 100644 --- a/server/src/main/java/org/elasticsearch/transport/SniffConnectionStrategy.java +++ b/server/src/main/java/org/elasticsearch/transport/SniffConnectionStrategy.java @@ -478,7 +478,7 @@ public void handleException(TransportException exp) { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return managementExecutor; } } diff --git a/server/src/main/java/org/elasticsearch/transport/TransportActionProxy.java b/server/src/main/java/org/elasticsearch/transport/TransportActionProxy.java index 224456b32d62c..f8706dda458e7 100644 --- a/server/src/main/java/org/elasticsearch/transport/TransportActionProxy.java +++ b/server/src/main/java/org/elasticsearch/transport/TransportActionProxy.java @@ -16,7 +16,6 @@ import org.elasticsearch.tasks.CancellableTask; import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.TaskId; -import org.elasticsearch.threadpool.ThreadPool; import java.io.IOException; import java.io.UncheckedIOException; @@ -58,7 +57,7 @@ public void messageReceived(T request, TransportChannel channel, Task task) thro wrappedRequest.setParentTask(taskId); service.sendRequest(targetNode, action, wrappedRequest, new TransportResponseHandler<>() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/main/java/org/elasticsearch/transport/TransportHandshaker.java b/server/src/main/java/org/elasticsearch/transport/TransportHandshaker.java index 61b052c957ac1..d52a31c1e3f3c 100644 --- a/server/src/main/java/org/elasticsearch/transport/TransportHandshaker.java +++ b/server/src/main/java/org/elasticsearch/transport/TransportHandshaker.java @@ -227,7 +227,7 @@ public HandshakeResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/main/java/org/elasticsearch/transport/TransportResponseHandler.java b/server/src/main/java/org/elasticsearch/transport/TransportResponseHandler.java index 9ac090fc00b03..c49a567b198e7 100644 --- a/server/src/main/java/org/elasticsearch/transport/TransportResponseHandler.java +++ b/server/src/main/java/org/elasticsearch/transport/TransportResponseHandler.java @@ -12,7 +12,6 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.util.concurrent.EsExecutors; -import org.elasticsearch.threadpool.ThreadPool; import java.util.concurrent.Executor; @@ -24,7 +23,7 @@ public interface TransportResponseHandler extends W * performance-critical actions, and even then only if the deserialization and handling work is very cheap, because this executor will * perform all the work for responses from remote nodes on the receiving transport worker itself. */ - Executor executor(ThreadPool threadPool); + Executor executor(); void handleResponse(T response); @@ -55,7 +54,7 @@ public void handleResponse() { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return executor; } diff --git a/server/src/main/java/org/elasticsearch/transport/TransportService.java b/server/src/main/java/org/elasticsearch/transport/TransportService.java index a6bab75fc4917..4f07aaf6f94aa 100644 --- a/server/src/main/java/org/elasticsearch/transport/TransportService.java +++ b/server/src/main/java/org/elasticsearch/transport/TransportService.java @@ -382,11 +382,11 @@ protected void doStop() { holderToNotify.action(), new NodeClosedException(localNode) ); - final var executor = handler.executor(threadPool); + final var executor = handler.executor(); if (executor == EsExecutors.DIRECT_EXECUTOR_SERVICE) { handler.handleException(exception); } else { - executor.execute(new ForkingResponseHandlerRunnable(handler, exception, threadPool) { + executor.execute(new ForkingResponseHandlerRunnable(handler, exception) { @Override protected void doRun() { handler.handleException(exception); @@ -999,7 +999,7 @@ protected void doRun() { } private void sendLocalRequest(long requestId, final String action, final TransportRequest request, TransportRequestOptions options) { - final DirectResponseChannel channel = new DirectResponseChannel(localNode, action, requestId, this, threadPool); + final DirectResponseChannel channel = new DirectResponseChannel(localNode, action, requestId, this); try { onRequestSent(localNode, requestId, action, request, options); onRequestReceived(requestId, action); @@ -1437,8 +1437,8 @@ public void handleException(TransportException exp) { } @Override - public Executor executor(ThreadPool threadPool) { - return delegate.executor(threadPool); + public Executor executor() { + return delegate.executor(); } @Override @@ -1465,14 +1465,12 @@ static class DirectResponseChannel implements TransportChannel { private final String action; private final long requestId; final TransportService service; - final ThreadPool threadPool; - DirectResponseChannel(DiscoveryNode localNode, String action, long requestId, TransportService service, ThreadPool threadPool) { + DirectResponseChannel(DiscoveryNode localNode, String action, long requestId, TransportService service) { this.localNode = localNode; this.action = action; this.requestId = requestId; this.service = service; - this.threadPool = threadPool; } @Override @@ -1493,12 +1491,12 @@ public void sendResponse(TransportResponse response) throws IOException { // handler already completed, likely by a timeout which is logged elsewhere return; } - final var executor = handler.executor(threadPool); + final var executor = handler.executor(); if (executor == EsExecutors.DIRECT_EXECUTOR_SERVICE) { processResponse(handler, response); } else { response.mustIncRef(); - executor.execute(new ForkingResponseHandlerRunnable(handler, null, threadPool) { + executor.execute(new ForkingResponseHandlerRunnable(handler, null) { @Override protected void doRun() { processResponse(handler, response); @@ -1541,11 +1539,11 @@ public void sendResponse(Exception exception) throws IOException { return; } final RemoteTransportException rtx = wrapInRemote(exception); - final var executor = handler.executor(threadPool); + final var executor = handler.executor(); if (executor == EsExecutors.DIRECT_EXECUTOR_SERVICE) { processException(handler, rtx); } else { - executor.execute(new ForkingResponseHandlerRunnable(handler, rtx, threadPool) { + executor.execute(new ForkingResponseHandlerRunnable(handler, rtx) { @Override protected void doRun() { processException(handler, rtx); @@ -1714,8 +1712,8 @@ public void handleException(TransportException exp) { } @Override - public Executor executor(ThreadPool threadPool) { - return handler.executor(threadPool); + public Executor executor() { + return handler.executor(); } @Override diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/configuration/TransportAddVotingConfigExclusionsActionTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/configuration/TransportAddVotingConfigExclusionsActionTests.java index 5f6540d46c719..02ec4dc508c0b 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/configuration/TransportAddVotingConfigExclusionsActionTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/configuration/TransportAddVotingConfigExclusionsActionTests.java @@ -531,7 +531,7 @@ public ActionResponse.Empty read(StreamInput in) { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/configuration/TransportClearVotingConfigExclusionsActionTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/configuration/TransportClearVotingConfigExclusionsActionTests.java index 17a22ff8e82fd..22aa5e9869afa 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/configuration/TransportClearVotingConfigExclusionsActionTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/configuration/TransportClearVotingConfigExclusionsActionTests.java @@ -218,7 +218,7 @@ public ActionResponse.Empty read(StreamInput in) { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/test/java/org/elasticsearch/action/support/replication/TransportReplicationAllPermitsAcquisitionTests.java b/server/src/test/java/org/elasticsearch/action/support/replication/TransportReplicationAllPermitsAcquisitionTests.java index e687b3b1c377f..7969f049acc44 100644 --- a/server/src/test/java/org/elasticsearch/action/support/replication/TransportReplicationAllPermitsAcquisitionTests.java +++ b/server/src/test/java/org/elasticsearch/action/support/replication/TransportReplicationAllPermitsAcquisitionTests.java @@ -181,7 +181,7 @@ private TransportResponseHandler get } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/test/java/org/elasticsearch/cluster/coordination/FollowersCheckerTests.java b/server/src/test/java/org/elasticsearch/cluster/coordination/FollowersCheckerTests.java index ee5b8b652d2d9..d634d1f5818ae 100644 --- a/server/src/test/java/org/elasticsearch/cluster/coordination/FollowersCheckerTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/coordination/FollowersCheckerTests.java @@ -29,7 +29,6 @@ import org.elasticsearch.test.EqualsHashCodeTestUtils.CopyFunction; import org.elasticsearch.test.transport.CapturingTransport; import org.elasticsearch.test.transport.MockTransport; -import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.AbstractSimpleTransportTestCase; import org.elasticsearch.transport.ConnectTransportException; import org.elasticsearch.transport.TransportException; @@ -547,7 +546,7 @@ protected void onSendRequest(long requestId, String action, TransportRequest req new FollowerCheckRequest(leaderTerm, leader), new TransportResponseHandler.Empty() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -636,7 +635,7 @@ protected void onSendRequest(long requestId, String action, TransportRequest req new FollowerCheckRequest(leaderTerm, leader), new TransportResponseHandler.Empty() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -703,7 +702,7 @@ public void handleException(TransportException exp) { new FollowerCheckRequest(term, leader), new TransportResponseHandler.Empty() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -739,7 +738,7 @@ public void handleException(TransportException exp) { new FollowerCheckRequest(term, leader), new TransportResponseHandler.Empty() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -828,7 +827,7 @@ private static class ExpectsSuccess extends TransportResponseHandler.Empty { private final AtomicBoolean responseReceived = new AtomicBoolean(); @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/test/java/org/elasticsearch/cluster/coordination/LeaderCheckerTests.java b/server/src/test/java/org/elasticsearch/cluster/coordination/LeaderCheckerTests.java index 93ebf894771e3..6585cd8f9bc13 100644 --- a/server/src/test/java/org/elasticsearch/cluster/coordination/LeaderCheckerTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/coordination/LeaderCheckerTests.java @@ -26,7 +26,6 @@ import org.elasticsearch.test.EqualsHashCodeTestUtils.CopyFunction; import org.elasticsearch.test.transport.CapturingTransport; import org.elasticsearch.test.transport.MockTransport; -import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.AbstractSimpleTransportTestCase; import org.elasticsearch.transport.ConnectTransportException; import org.elasticsearch.transport.ReceiveTimeoutTransportException; @@ -486,6 +485,7 @@ public void testLeaderBehaviour() { ); transportService.start(); transportService.acceptIncomingRequests(); + final var executor = transportService.getThreadPool().generic(); final LeaderChecker leaderChecker = new LeaderChecker( settings, @@ -503,7 +503,7 @@ public void testLeaderBehaviour() { { leaderChecker.setCurrentNodes(discoveryNodes); - final CapturingTransportResponseHandler handler = new CapturingTransportResponseHandler(); + final CapturingTransportResponseHandler handler = new CapturingTransportResponseHandler(executor); transportService.sendRequest(localNode, LEADER_CHECK_ACTION_NAME, new LeaderCheckRequest(otherNode), handler); deterministicTaskQueue.runAllTasks(); @@ -518,7 +518,7 @@ public void testLeaderBehaviour() { { leaderChecker.setCurrentNodes(discoveryNodes); - final CapturingTransportResponseHandler handler = new CapturingTransportResponseHandler(); + final CapturingTransportResponseHandler handler = new CapturingTransportResponseHandler(executor); transportService.sendRequest(localNode, LEADER_CHECK_ACTION_NAME, new LeaderCheckRequest(otherNode), handler); deterministicTaskQueue.runAllTasks(); @@ -531,7 +531,7 @@ public void testLeaderBehaviour() { { leaderChecker.setCurrentNodes(DiscoveryNodes.builder(discoveryNodes).add(otherNode).build()); - final CapturingTransportResponseHandler handler = new CapturingTransportResponseHandler(); + final CapturingTransportResponseHandler handler = new CapturingTransportResponseHandler(executor); transportService.sendRequest(localNode, LEADER_CHECK_ACTION_NAME, new LeaderCheckRequest(otherNode), handler); deterministicTaskQueue.runAllTasks(); @@ -542,7 +542,7 @@ public void testLeaderBehaviour() { { leaderChecker.setCurrentNodes(DiscoveryNodes.builder(discoveryNodes).add(otherNode).masterNodeId(null).build()); - final CapturingTransportResponseHandler handler = new CapturingTransportResponseHandler(); + final CapturingTransportResponseHandler handler = new CapturingTransportResponseHandler(executor); transportService.sendRequest(localNode, LEADER_CHECK_ACTION_NAME, new LeaderCheckRequest(otherNode), handler); deterministicTaskQueue.runAllTasks(); @@ -557,6 +557,11 @@ private static class CapturingTransportResponseHandler implements TransportRespo TransportException transportException; boolean successfulResponseReceived; + final Executor executor; + + private CapturingTransportResponseHandler(Executor executor) { + this.executor = executor; + } @Override public void handleResponse(TransportResponse.Empty response) { @@ -569,8 +574,8 @@ public void handleException(TransportException exp) { } @Override - public Executor executor(ThreadPool threadPool) { - return threadPool.generic(); + public Executor executor() { + return executor; } @Override diff --git a/server/src/test/java/org/elasticsearch/cluster/coordination/StatefulPreVoteCollectorTests.java b/server/src/test/java/org/elasticsearch/cluster/coordination/StatefulPreVoteCollectorTests.java index c430771342669..d1b81c4d9c601 100644 --- a/server/src/test/java/org/elasticsearch/cluster/coordination/StatefulPreVoteCollectorTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/coordination/StatefulPreVoteCollectorTests.java @@ -19,7 +19,6 @@ import org.elasticsearch.monitor.StatusInfo; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.transport.MockTransport; -import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.ConnectTransportException; import org.elasticsearch.transport.RemoteTransportException; import org.elasticsearch.transport.TransportException; @@ -314,7 +313,7 @@ public PreVoteResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/test/java/org/elasticsearch/discovery/PeerFinderTests.java b/server/src/test/java/org/elasticsearch/discovery/PeerFinderTests.java index 209261e8dce70..6ff61d72d43f5 100644 --- a/server/src/test/java/org/elasticsearch/discovery/PeerFinderTests.java +++ b/server/src/test/java/org/elasticsearch/discovery/PeerFinderTests.java @@ -542,7 +542,7 @@ public PeersResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/test/java/org/elasticsearch/tasks/BanFailureLoggingTests.java b/server/src/test/java/org/elasticsearch/tasks/BanFailureLoggingTests.java index 56e72c25802e3..348ff8d10d8b1 100644 --- a/server/src/test/java/org/elasticsearch/tasks/BanFailureLoggingTests.java +++ b/server/src/test/java/org/elasticsearch/tasks/BanFailureLoggingTests.java @@ -229,7 +229,7 @@ private static class ChildResponseHandler extends TransportResponseHandler.Empty } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/test/java/org/elasticsearch/transport/InboundHandlerTests.java b/server/src/test/java/org/elasticsearch/transport/InboundHandlerTests.java index 39d5d768f81ab..3d3026a6788ac 100644 --- a/server/src/test/java/org/elasticsearch/transport/InboundHandlerTests.java +++ b/server/src/test/java/org/elasticsearch/transport/InboundHandlerTests.java @@ -139,7 +139,7 @@ public void testRequestAndResponse() throws Exception { long requestId = responseHandlers.add(new TransportResponseHandler() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/test/java/org/elasticsearch/transport/TransportActionProxyTests.java b/server/src/test/java/org/elasticsearch/transport/TransportActionProxyTests.java index cd460c2a0e22d..93986aefe9f25 100644 --- a/server/src/test/java/org/elasticsearch/transport/TransportActionProxyTests.java +++ b/server/src/test/java/org/elasticsearch/transport/TransportActionProxyTests.java @@ -179,7 +179,7 @@ public SimpleTestResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -231,7 +231,7 @@ public SimpleTestResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -297,7 +297,7 @@ public SimpleTestResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -377,7 +377,7 @@ public SimpleTestResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/test/java/org/elasticsearch/transport/TransportServiceDeserializationFailureTests.java b/server/src/test/java/org/elasticsearch/transport/TransportServiceDeserializationFailureTests.java index 2eb77c706a3a2..a3b44c702e692 100644 --- a/server/src/test/java/org/elasticsearch/transport/TransportServiceDeserializationFailureTests.java +++ b/server/src/test/java/org/elasticsearch/transport/TransportServiceDeserializationFailureTests.java @@ -25,7 +25,6 @@ import org.elasticsearch.tasks.TaskId; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.transport.MockTransport; -import org.elasticsearch.threadpool.ThreadPool; import java.util.Collections; import java.util.List; @@ -91,7 +90,7 @@ protected void onSendRequest(long requestId, String action, TransportRequest req TransportRequestOptions.EMPTY, new TransportResponseHandler() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -157,7 +156,7 @@ public Task createTask(long id, String type, String action, TaskId parentTaskId, TransportRequestOptions.EMPTY, new TransportResponseHandler() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/server/src/test/java/org/elasticsearch/transport/TransportServiceLifecycleTests.java b/server/src/test/java/org/elasticsearch/transport/TransportServiceLifecycleTests.java index 2c10f47955c4c..0d91e244ac9f5 100644 --- a/server/src/test/java/org/elasticsearch/transport/TransportServiceLifecycleTests.java +++ b/server/src/test/java/org/elasticsearch/transport/TransportServiceLifecycleTests.java @@ -82,8 +82,8 @@ public TransportResponse.Empty read(StreamInput in) { } @Override - public Executor executor(ThreadPool threadPool) { - return threadPool.executor(executor); + public Executor executor() { + return nodeB.transportService.getThreadPool().executor(executor); } } ); diff --git a/test/framework/src/integTest/java/org/elasticsearch/test/disruption/NetworkDisruptionIT.java b/test/framework/src/integTest/java/org/elasticsearch/test/disruption/NetworkDisruptionIT.java index 88958063dbbf3..a9196a3bb1377 100644 --- a/test/framework/src/integTest/java/org/elasticsearch/test/disruption/NetworkDisruptionIT.java +++ b/test/framework/src/integTest/java/org/elasticsearch/test/disruption/NetworkDisruptionIT.java @@ -19,7 +19,6 @@ import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.test.disruption.NetworkDisruption.TwoPartitions; import org.elasticsearch.test.transport.MockTransportService; -import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportException; import org.elasticsearch.transport.TransportResponse; import org.elasticsearch.transport.TransportResponseHandler; @@ -170,7 +169,7 @@ private static void sendRequest(TransportService source, TransportService target private AtomicBoolean responded = new AtomicBoolean(); @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/test/framework/src/main/java/org/elasticsearch/transport/AbstractSimpleTransportTestCase.java b/test/framework/src/main/java/org/elasticsearch/transport/AbstractSimpleTransportTestCase.java index b835a56a6384c..86ed912741796 100644 --- a/test/framework/src/main/java/org/elasticsearch/transport/AbstractSimpleTransportTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/transport/AbstractSimpleTransportTestCase.java @@ -340,7 +340,7 @@ public StringMessageResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return threadPool.generic(); } @@ -371,7 +371,7 @@ public StringMessageResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return threadPool.generic(); } @@ -423,7 +423,7 @@ public StringMessageResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return threadPool.executor(executor); } @@ -497,7 +497,7 @@ public void handleException(TransportException exp) { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return threadPool.generic(); } } @@ -675,7 +675,7 @@ public TransportResponse.Empty read(StreamInput in) { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return threadPool.generic(); } @@ -732,7 +732,7 @@ public StringMessageResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return threadPool.generic(); } @@ -798,7 +798,7 @@ public StringMessageResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return threadPool.generic(); } @@ -862,7 +862,7 @@ public StringMessageResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return threadPool.generic(); } @@ -1120,7 +1120,7 @@ public StringMessageResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return threadPool.generic(); } @@ -1187,7 +1187,7 @@ public StringMessageResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return threadPool.generic(); } @@ -1226,7 +1226,7 @@ public StringMessageResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return threadPool.generic(); } @@ -1281,7 +1281,7 @@ public StringMessageResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -1649,7 +1649,7 @@ public Version0Response read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -1697,7 +1697,7 @@ public Version1Response read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -1750,7 +1750,7 @@ public Version1Response read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -1801,7 +1801,7 @@ public Version0Response read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -1846,7 +1846,7 @@ public StringMessageResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return threadPool.generic(); } @@ -1903,7 +1903,7 @@ public StringMessageResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return threadPool.generic(); } @@ -1949,7 +1949,7 @@ public TestResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -2006,7 +2006,7 @@ public TestResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -2041,7 +2041,7 @@ public TestResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -2213,7 +2213,7 @@ public void handleException(TransportException exp) { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return executor; } } @@ -2276,7 +2276,7 @@ public void handleException(TransportException exp) { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return threadPool.executor(executor); } } @@ -2585,7 +2585,7 @@ public void handleException(TransportException exp) { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return threadPool.executor(executor); } }; @@ -2638,7 +2638,7 @@ public void handleException(TransportException exp) { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return threadPool.executor(randomFrom(executors)); } }; @@ -2696,7 +2696,7 @@ protected void doRun() throws Exception { CountDownLatch responseLatch = new CountDownLatch(1); TransportResponseHandler transportResponseHandler = new TransportResponseHandler.Empty() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -2768,7 +2768,7 @@ protected void doRun() throws Exception { CountDownLatch responseLatch = new CountDownLatch(1); TransportResponseHandler transportResponseHandler = new TransportResponseHandler.Empty() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -2886,7 +2886,7 @@ protected void doRun() throws Exception { AtomicReference receivedException = new AtomicReference<>(null); TransportResponseHandler transportResponseHandler = new TransportResponseHandler.Empty() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -3461,7 +3461,7 @@ public void onFailure(final Exception e) { TransportRequestOptions.EMPTY, new TransportResponseHandler.Empty() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -3550,7 +3550,7 @@ public static Future submitRequest( final TransportResponseHandler futureHandler = new ActionListenerResponseHandler<>( responseListener, handler, - handler.executor(transportService.threadPool) + handler.executor() ); responseListener.addListener(ActionListener.wrap(handler::handleResponse, e -> handler.handleException((TransportException) e))); final PlainActionFuture future = new PlainActionFuture<>(); diff --git a/test/framework/src/test/java/org/elasticsearch/transport/DisruptableMockTransportTests.java b/test/framework/src/test/java/org/elasticsearch/transport/DisruptableMockTransportTests.java index 0491f175b758e..9582d28327122 100644 --- a/test/framework/src/test/java/org/elasticsearch/transport/DisruptableMockTransportTests.java +++ b/test/framework/src/test/java/org/elasticsearch/transport/DisruptableMockTransportTests.java @@ -258,7 +258,7 @@ public T read(StreamInput in) { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -282,7 +282,7 @@ public TestResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -308,7 +308,7 @@ public T read(StreamInput in) { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/termsenum/action/TransportTermsEnumAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/termsenum/action/TransportTermsEnumAction.java index 97504940270de..0b9e29224a4c5 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/termsenum/action/TransportTermsEnumAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/termsenum/action/TransportTermsEnumAction.java @@ -598,7 +598,7 @@ public NodeTermsEnumResponse read(StreamInput in) throws IOException { } @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportInterceptorTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportInterceptorTests.java index 46b0fac78ad8e..d49c1be8a7e0a 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportInterceptorTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportInterceptorTests.java @@ -492,7 +492,7 @@ public void testContextRestoreResponseHandler() throws Exception { threadContext.wrapRestorable(storedContext), new TransportResponseHandler.Empty() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -527,7 +527,7 @@ public void testContextRestoreResponseHandlerRestoreOriginalContext() throws Exc threadContext.newRestorableContext(true), new TransportResponseHandler.Empty() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -626,7 +626,7 @@ public void testSendWithCrossClusterAccessHeadersWithUnsupportedLicense() throws final AtomicReference actualException = new AtomicReference<>(); sender.sendRequest(connection, "action", mock(TransportRequest.class), null, new TransportResponseHandler<>() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -788,7 +788,7 @@ public void sendRequest( sender.sendRequest(connection, action, request, null, new TransportResponseHandler<>() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -974,7 +974,7 @@ public void sendRequest( final AtomicReference actualException = new AtomicReference<>(); sender.sendRequest(connection, "action", mock(TransportRequest.class), null, new TransportResponseHandler<>() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } @@ -1068,7 +1068,7 @@ public void sendRequest( final var actualException = new AtomicReference(); sender.sendRequest(connection, "action", mock(TransportRequest.class), null, new TransportResponseHandler<>() { @Override - public Executor executor(ThreadPool threadPool) { + public Executor executor() { return TransportResponseHandler.TRANSPORT_WORKER; } diff --git a/x-pack/plugin/voting-only-node/src/main/java/org/elasticsearch/cluster/coordination/votingonly/VotingOnlyNodePlugin.java b/x-pack/plugin/voting-only-node/src/main/java/org/elasticsearch/cluster/coordination/votingonly/VotingOnlyNodePlugin.java index 7b8355ec41e90..8bd951cff40da 100644 --- a/x-pack/plugin/voting-only-node/src/main/java/org/elasticsearch/cluster/coordination/votingonly/VotingOnlyNodePlugin.java +++ b/x-pack/plugin/voting-only-node/src/main/java/org/elasticsearch/cluster/coordination/votingonly/VotingOnlyNodePlugin.java @@ -200,8 +200,8 @@ public void handleException(TransportException exp) { } @Override - public Executor executor(ThreadPool threadPool) { - return handler.executor(threadPool); + public Executor executor() { + return handler.executor(); } @Override From 82c4cc75cb353af1758867bd503cd2c4ad89ed31 Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Thu, 25 Jan 2024 11:44:54 +0100 Subject: [PATCH 23/37] Fix dependency check for ignored licenses (#104736) if there are no dependencies declared and the license file is marked as ignored, no exception should be thrown and dependencylicense check should pass. Fixes issues we identified in #104628 --- .../internal/precommit/DependencyLicensesTask.java | 7 ++++++- .../internal/precommit/DependencyLicensesTaskTests.java | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/DependencyLicensesTask.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/DependencyLicensesTask.java index 092230a2b12ea..f71973c2fb15c 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/DependencyLicensesTask.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/DependencyLicensesTask.java @@ -28,6 +28,7 @@ import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -187,7 +188,7 @@ public void checkDependencies() { } File licensesDirAsFile = licensesDir.get().getAsFile(); if (dependencies.isEmpty()) { - if (licensesDirAsFile.exists()) { + if (licensesDirAsFile.exists() && allIgnored() == false) { throw new GradleException("Licenses dir " + licensesDirAsFile + " exists, but there are no dependencies"); } return; // no dependencies to check @@ -227,6 +228,10 @@ public void checkDependencies() { sources.forEach((item, exists) -> failIfAnyMissing(item, exists, "sources")); } + private boolean allIgnored() { + return Arrays.asList(getLicensesDir().listFiles()).stream().map(f -> f.getName()).allMatch(ignoreFiles::contains); + } + // This is just a marker output folder to allow this task being up-to-date. // The check logic is exception driven so a failed tasks will not be defined // by this output but when successful we can safely mark the task as up-to-date. diff --git a/build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/precommit/DependencyLicensesTaskTests.java b/build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/precommit/DependencyLicensesTaskTests.java index 1a9284276043c..b909970638753 100644 --- a/build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/precommit/DependencyLicensesTaskTests.java +++ b/build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/precommit/DependencyLicensesTaskTests.java @@ -63,8 +63,17 @@ public void execute(DependencyLicensesTask dependencyLicensesTask) { public void givenProjectWithLicensesDirButNoDependenciesThenShouldThrowException() throws Exception { expectedException.expect(GradleException.class); expectedException.expectMessage(containsString("exists, but there are no dependencies")); + getLicensesDir(project).mkdir(); + createFileIn(getLicensesDir(project), "groovy-LICENSE.txt", PERMISSIVE_LICENSE_TEXT); + task.get().checkDependencies(); + } + @Test + public void givenProjectWithLicensesDirButAllIgnoreFileAndNoDependencies() throws Exception { getLicensesDir(project).mkdir(); + String licenseFileName = "cloudcarbonfootprint-LICENSE.txt"; + createFileIn(getLicensesDir(project), licenseFileName, PERMISSIVE_LICENSE_TEXT); + task.get().ignoreFile(licenseFileName); task.get().checkDependencies(); } From b4345d9d9118494d22fdf228be87bcc52902f547 Mon Sep 17 00:00:00 2001 From: Navarone Feekery <13634519+navarone-feekery@users.noreply.github.com> Date: Thu, 25 Jan 2024 13:56:07 +0100 Subject: [PATCH 24/37] [Enterprise Search] Add `.connector-secrets` system index and GET/POST requests (#103683) - Introduce new internal system index called .connector-secrets - Add GET and POST requests for connector secrets - Create read_connector_secrets and write_connector_secrets role permissions --- .../security/get-builtin-privileges.asciidoc | 2 + .../api/connector_secret.get.json | 28 +++++ .../api/connector_secret.post.json | 26 +++++ .../privilege/ClusterPrivilegeResolver.java | 14 ++- .../src/main/resources/connector-secrets.json | 26 +++++ x-pack/plugin/ent-search/build.gradle | 7 ++ x-pack/plugin/ent-search/qa/rest/roles.yml | 2 + .../entsearch/500_connector_secret_post.yml | 55 +++++++++ .../entsearch/510_connector_secret_get.yml | 60 ++++++++++ .../ConnectorSecretsSystemIndexIT.java | 94 ++++++++++++++++ .../ent-search/src/main/java/module-info.java | 2 + .../xpack/application/EnterpriseSearch.java | 31 +++++- .../secrets/ConnectorSecretsFeature.java | 32 ++++++ .../secrets/ConnectorSecretsIndexService.java | 96 ++++++++++++++++ .../action/GetConnectorSecretAction.java | 21 ++++ .../action/GetConnectorSecretRequest.java | 67 +++++++++++ .../action/GetConnectorSecretResponse.java | 70 ++++++++++++ .../action/PostConnectorSecretAction.java | 21 ++++ .../action/PostConnectorSecretRequest.java | 99 +++++++++++++++++ .../action/PostConnectorSecretResponse.java | 61 ++++++++++ .../action/RestGetConnectorSecretAction.java | 42 +++++++ .../action/RestPostConnectorSecretAction.java | 45 ++++++++ .../TransportGetConnectorSecretAction.java | 39 +++++++ .../TransportPostConnectorSecretAction.java | 39 +++++++ .../ConnectorSecretsIndexServiceTests.java | 104 ++++++++++++++++++ .../secrets/ConnectorSecretsTestUtils.java | 37 +++++++ .../action/GetConnectorSecretActionTests.java | 34 ++++++ ...ectorSecretRequestBWCSerializingTests.java | 37 +++++++ ...ctorSecretResponseBWCSerializingTests.java | 46 ++++++++ .../PostConnectorSecretActionTests.java | 34 ++++++ ...ectorSecretRequestBWCSerializingTests.java | 38 +++++++ ...ctorSecretResponseBWCSerializingTests.java | 39 +++++++ ...ransportGetConnectorSecretActionTests.java | 72 ++++++++++++ ...ansportPostConnectorSecretActionTests.java | 72 ++++++++++++ .../xpack/security/operator/Constants.java | 2 + .../authc/service/ServiceAccountIT.java | 4 +- .../authc/service/ElasticServiceAccounts.java | 2 +- .../service/ElasticServiceAccountsTests.java | 4 + .../test/privileges/11_builtin.yml | 2 +- 39 files changed, 1501 insertions(+), 5 deletions(-) create mode 100644 rest-api-spec/src/main/resources/rest-api-spec/api/connector_secret.get.json create mode 100644 rest-api-spec/src/main/resources/rest-api-spec/api/connector_secret.post.json create mode 100644 x-pack/plugin/core/template-resources/src/main/resources/connector-secrets.json create mode 100644 x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/500_connector_secret_post.yml create mode 100644 x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/510_connector_secret_get.yml create mode 100644 x-pack/plugin/ent-search/src/javaRestTest/java/org/elasticsearch/xpack/entsearch/ConnectorSecretsSystemIndexIT.java create mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsFeature.java create mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsIndexService.java create mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretAction.java create mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretRequest.java create mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretResponse.java create mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretAction.java create mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretRequest.java create mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretResponse.java create mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/RestGetConnectorSecretAction.java create mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/RestPostConnectorSecretAction.java create mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportGetConnectorSecretAction.java create mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportPostConnectorSecretAction.java create mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsIndexServiceTests.java create mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsTestUtils.java create mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretActionTests.java create mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretRequestBWCSerializingTests.java create mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretResponseBWCSerializingTests.java create mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretActionTests.java create mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretRequestBWCSerializingTests.java create mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretResponseBWCSerializingTests.java create mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportGetConnectorSecretActionTests.java create mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportPostConnectorSecretActionTests.java diff --git a/docs/reference/rest-api/security/get-builtin-privileges.asciidoc b/docs/reference/rest-api/security/get-builtin-privileges.asciidoc index 8f75293e2c1a4..bd2d21317212b 100644 --- a/docs/reference/rest-api/security/get-builtin-privileges.asciidoc +++ b/docs/reference/rest-api/security/get-builtin-privileges.asciidoc @@ -108,12 +108,14 @@ A successful call returns an object with "cluster" and "index" fields. "none", "post_behavioral_analytics_event", "read_ccr", + "read_connector_secrets", "read_fleet_secrets", "read_ilm", "read_pipeline", "read_security", "read_slm", "transport_client", + "write_connector_secrets", "write_fleet_secrets" ], "index" : [ diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/connector_secret.get.json b/rest-api-spec/src/main/resources/rest-api-spec/api/connector_secret.get.json new file mode 100644 index 0000000000000..f1037bedddfc6 --- /dev/null +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/connector_secret.get.json @@ -0,0 +1,28 @@ +{ + "connector_secret.get": { + "documentation": { + "url": null, + "description": "Retrieves a secret stored by Connectors." + }, + "stability": "experimental", + "visibility":"private", + "headers":{ + "accept": [ "application/json"] + }, + "url":{ + "paths":[ + { + "path":"/_connector/_secret/{id}", + "methods":[ "GET" ], + "parts":{ + "id":{ + "type":"string", + "description":"The ID of the secret" + } + } + } + ] + }, + "params":{} + } +} diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/connector_secret.post.json b/rest-api-spec/src/main/resources/rest-api-spec/api/connector_secret.post.json new file mode 100644 index 0000000000000..48657cf389446 --- /dev/null +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/connector_secret.post.json @@ -0,0 +1,26 @@ +{ + "connector_secret.post": { + "documentation": { + "url": null, + "description": "Creates a secret for a Connector." + }, + "stability": "experimental", + "visibility":"private", + "headers":{ + "accept": [ "application/json" ] + }, + "url":{ + "paths":[ + { + "path":"/_connector/_secret", + "methods":[ "POST" ] + } + ] + }, + "params":{}, + "body": { + "description":"The secret value to store", + "required":true + } + } +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilegeResolver.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilegeResolver.java index ba6bca802070a..4637ca7edd8dd 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilegeResolver.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilegeResolver.java @@ -326,6 +326,16 @@ public class ClusterPrivilegeResolver { CROSS_CLUSTER_REPLICATION_PATTERN ); + public static final NamedClusterPrivilege READ_CONNECTOR_SECRETS = new ActionClusterPrivilege( + "read_connector_secrets", + Set.of("cluster:admin/xpack/connector/secret/get") + ); + + public static final NamedClusterPrivilege WRITE_CONNECTOR_SECRETS = new ActionClusterPrivilege( + "write_connector_secrets", + Set.of("cluster:admin/xpack/connector/secret/post") + ); + private static final Map VALUES = sortByAccessLevel( Stream.of( NONE, @@ -380,7 +390,9 @@ public class ClusterPrivilegeResolver { POST_BEHAVIORAL_ANALYTICS_EVENT, MANAGE_SEARCH_QUERY_RULES, CROSS_CLUSTER_SEARCH, - CROSS_CLUSTER_REPLICATION + CROSS_CLUSTER_REPLICATION, + READ_CONNECTOR_SECRETS, + WRITE_CONNECTOR_SECRETS ).filter(Objects::nonNull).toList() ); diff --git a/x-pack/plugin/core/template-resources/src/main/resources/connector-secrets.json b/x-pack/plugin/core/template-resources/src/main/resources/connector-secrets.json new file mode 100644 index 0000000000000..96fa641726fa3 --- /dev/null +++ b/x-pack/plugin/core/template-resources/src/main/resources/connector-secrets.json @@ -0,0 +1,26 @@ +{ + "settings": { + "index": { + "auto_expand_replicas": "0-1", + "number_of_shards": 1, + "number_of_replicas": 0, + "priority": 100, + "refresh_interval": "1s" + } + }, + "mappings": { + "_doc" : { + "dynamic": false, + "_meta": { + "version": "${connector-secrets.version}", + "managed_index_mappings_version": ${connector-secrets.managed.index.version} + }, + "properties": { + "value": { + "type": "keyword", + "index": false + } + } + } + } +} diff --git a/x-pack/plugin/ent-search/build.gradle b/x-pack/plugin/ent-search/build.gradle index 92a1c007f72bf..4551011b03ca1 100644 --- a/x-pack/plugin/ent-search/build.gradle +++ b/x-pack/plugin/ent-search/build.gradle @@ -38,6 +38,13 @@ dependencies { module ':modules:search-business-rules' } +testClusters.configureEach { + testDistribution = 'DEFAULT' + setting 'xpack.security.enabled', 'true' + setting 'xpack.security.autoconfiguration.enabled', 'false' + user username: 'x_pack_rest_user', password: 'x-pack-test-password' +} + tasks.named("dependencyLicenses").configure { mapping from: /jackson.*/, to: 'jackson' } diff --git a/x-pack/plugin/ent-search/qa/rest/roles.yml b/x-pack/plugin/ent-search/qa/rest/roles.yml index 4d868f41e78b3..9dac14709db8d 100644 --- a/x-pack/plugin/ent-search/qa/rest/roles.yml +++ b/x-pack/plugin/ent-search/qa/rest/roles.yml @@ -16,6 +16,8 @@ user: cluster: - post_behavioral_analytics_event - manage_api_key + - read_connector_secrets + - write_connector_secrets indices: - names: [ "test-index1", diff --git a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/500_connector_secret_post.yml b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/500_connector_secret_post.yml new file mode 100644 index 0000000000000..6a4ee3ba7f6cb --- /dev/null +++ b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/500_connector_secret_post.yml @@ -0,0 +1,55 @@ +setup: + - skip: + version: " - 8.12.99" + reason: Introduced in 8.13.0 + +--- +'Post connector secret - admin': + - do: + connector_secret.post: + body: + value: my-secret + - set: { id: id } + - match: { id: $id } + - do: + connector_secret.get: + id: $id + - match: { value: my-secret } + +--- +'Post connector secret - authorized user': + - skip: + features: headers + + - do: + headers: { Authorization: "Basic ZW50c2VhcmNoLXVzZXI6ZW50c2VhcmNoLXVzZXItcGFzc3dvcmQ=" } # user + connector_secret.post: + body: + value: my-secret + - set: { id: id } + - match: { id: $id } + - do: + headers: { Authorization: "Basic ZW50c2VhcmNoLXVzZXI6ZW50c2VhcmNoLXVzZXItcGFzc3dvcmQ=" } # user + connector_secret.get: + id: $id + - match: { value: my-secret } + +--- +'Post connector secret - unauthorized user': + - skip: + features: headers + + - do: + headers: { Authorization: "Basic ZW50c2VhcmNoLXVucHJpdmlsZWdlZDplbnRzZWFyY2gtdW5wcml2aWxlZ2VkLXVzZXI=" } # unprivileged + connector_secret.post: + body: + value: my-secret + catch: unauthorized + +--- +'Post connector secret when id is missing should fail': + - do: + connector_secret.post: + body: + value: null + catch: bad_request diff --git a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/510_connector_secret_get.yml b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/510_connector_secret_get.yml new file mode 100644 index 0000000000000..4b2d3777ffe9d --- /dev/null +++ b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/510_connector_secret_get.yml @@ -0,0 +1,60 @@ +setup: + - skip: + version: " - 8.12.99" + reason: Introduced in 8.13.0 + +--- +'Get connector secret - admin': + - do: + connector_secret.post: + body: + value: my-secret + - set: { id: id } + - match: { id: $id } + - do: + connector_secret.get: + id: $id + - match: { value: my-secret } + +--- +'Get connector secret - user with privileges': + - skip: + features: headers + + - do: + headers: { Authorization: "Basic ZW50c2VhcmNoLXVzZXI6ZW50c2VhcmNoLXVzZXItcGFzc3dvcmQ=" } # user + connector_secret.post: + body: + value: my-secret + - set: { id: id } + - match: { id: $id } + - do: + headers: { Authorization: "Basic ZW50c2VhcmNoLXVzZXI6ZW50c2VhcmNoLXVzZXItcGFzc3dvcmQ=" } # user + connector_secret.get: + id: $id + - match: { value: my-secret } + +--- +'Get connector secret - user without privileges': + - skip: + features: headers + + - do: + headers: { Authorization: "Basic ZW50c2VhcmNoLXVzZXI6ZW50c2VhcmNoLXVzZXItcGFzc3dvcmQ=" } # user + connector_secret.post: + body: + value: my-secret + - set: { id: id } + - match: { id: $id } + - do: + headers: { Authorization: "Basic ZW50c2VhcmNoLXVucHJpdmlsZWdlZDplbnRzZWFyY2gtdW5wcml2aWxlZ2VkLXVzZXI=" } # unprivileged + connector_secret.get: + id: $id + catch: unauthorized + +--- +'Get connector secret - Missing secret id': + - do: + connector_secret.get: + id: non-existing-secret-id + catch: missing diff --git a/x-pack/plugin/ent-search/src/javaRestTest/java/org/elasticsearch/xpack/entsearch/ConnectorSecretsSystemIndexIT.java b/x-pack/plugin/ent-search/src/javaRestTest/java/org/elasticsearch/xpack/entsearch/ConnectorSecretsSystemIndexIT.java new file mode 100644 index 0000000000000..730ad1d83a318 --- /dev/null +++ b/x-pack/plugin/ent-search/src/javaRestTest/java/org/elasticsearch/xpack/entsearch/ConnectorSecretsSystemIndexIT.java @@ -0,0 +1,94 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.entsearch; + +import org.apache.http.util.EntityUtils; +import org.elasticsearch.client.Request; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.ResponseException; +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.concurrent.ThreadContext; +import org.elasticsearch.common.xcontent.XContentHelper; +import org.elasticsearch.test.SecuritySettingsSourceField; +import org.elasticsearch.test.rest.ESRestTestCase; +import org.elasticsearch.xcontent.XContentBuilder; +import org.elasticsearch.xcontent.XContentType; +import org.elasticsearch.xcontent.json.JsonXContent; + +import java.io.IOException; +import java.util.Map; + +import static org.hamcrest.Matchers.is; + +public class ConnectorSecretsSystemIndexIT extends ESRestTestCase { + + static final String BASIC_AUTH_VALUE = basicAuthHeaderValue( + "x_pack_rest_user", + SecuritySettingsSourceField.TEST_PASSWORD_SECURE_STRING + ); + + @Override + protected Settings restClientSettings() { + return Settings.builder().put(ThreadContext.PREFIX + ".Authorization", BASIC_AUTH_VALUE).build(); + } + + public void testConnectorSecretsCRUD() throws Exception { + // post secret + final String secretJson = getPostSecretJson(); + Request postRequest = new Request("POST", "/_connector/_secret/"); + postRequest.setJsonEntity(secretJson); + Response postResponse = client().performRequest(postRequest); + assertThat(postResponse.getStatusLine().getStatusCode(), is(200)); + Map responseMap = getResponseMap(postResponse); + assertThat(responseMap.size(), is(1)); + assertTrue(responseMap.containsKey("id")); + final String id = responseMap.get("id").toString(); + + // get secret + Request getRequest = new Request("GET", "/_connector/_secret/" + id); + Response getResponse = client().performRequest(getRequest); + assertThat(getResponse.getStatusLine().getStatusCode(), is(200)); + responseMap = getResponseMap(getResponse); + assertThat(responseMap.size(), is(2)); + assertTrue(responseMap.containsKey("id")); + assertTrue(responseMap.containsKey("value")); + assertThat(responseMap.get("value"), is("test secret")); + } + + public void testPostInvalidSecretBody() throws Exception { + Request postRequest = new Request("POST", "/_connector/_secret/"); + postRequest.setJsonEntity(""" + {"something":"else"}"""); + ResponseException re = expectThrows(ResponseException.class, () -> client().performRequest(postRequest)); + Response getResponse = re.getResponse(); + assertThat(getResponse.getStatusLine().getStatusCode(), is(400)); + } + + public void testGetNonExistingSecret() { + Request getRequest = new Request("GET", "/_connector/_secret/123"); + ResponseException re = expectThrows(ResponseException.class, () -> client().performRequest(getRequest)); + Response getResponse = re.getResponse(); + assertThat(getResponse.getStatusLine().getStatusCode(), is(404)); + } + + private String getPostSecretJson() throws IOException { + try (XContentBuilder builder = JsonXContent.contentBuilder()) { + builder.startObject(); + { + builder.field("value", "test secret"); + } + builder.endObject(); + return BytesReference.bytes(builder).utf8ToString(); + } + } + + private Map getResponseMap(Response response) throws IOException { + return XContentHelper.convertToMap(XContentType.JSON.xContent(), EntityUtils.toString(response.getEntity()), false); + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/module-info.java b/x-pack/plugin/ent-search/src/main/java/module-info.java index d8cbceda4d8a3..5850b279f8b09 100644 --- a/x-pack/plugin/ent-search/src/main/java/module-info.java +++ b/x-pack/plugin/ent-search/src/main/java/module-info.java @@ -39,4 +39,6 @@ exports org.elasticsearch.xpack.application.connector.syncjob.action; provides org.elasticsearch.features.FeatureSpecification with org.elasticsearch.xpack.application.EnterpriseSearchFeatures; + + exports org.elasticsearch.xpack.application.connector.secrets.action to org.elasticsearch.server; } diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java index 4b31778d469ac..d344bd60a22bd 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java @@ -88,6 +88,14 @@ import org.elasticsearch.xpack.application.connector.action.UpdateConnectorPipelineAction; import org.elasticsearch.xpack.application.connector.action.UpdateConnectorSchedulingAction; import org.elasticsearch.xpack.application.connector.action.UpdateConnectorServiceTypeAction; +import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsFeature; +import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsIndexService; +import org.elasticsearch.xpack.application.connector.secrets.action.GetConnectorSecretAction; +import org.elasticsearch.xpack.application.connector.secrets.action.PostConnectorSecretAction; +import org.elasticsearch.xpack.application.connector.secrets.action.RestGetConnectorSecretAction; +import org.elasticsearch.xpack.application.connector.secrets.action.RestPostConnectorSecretAction; +import org.elasticsearch.xpack.application.connector.secrets.action.TransportGetConnectorSecretAction; +import org.elasticsearch.xpack.application.connector.secrets.action.TransportPostConnectorSecretAction; import org.elasticsearch.xpack.application.connector.syncjob.action.CancelConnectorSyncJobAction; import org.elasticsearch.xpack.application.connector.syncjob.action.CheckInConnectorSyncJobAction; import org.elasticsearch.xpack.application.connector.syncjob.action.DeleteConnectorSyncJobAction; @@ -260,6 +268,15 @@ protected XPackLicenseState getLicenseState() { ); } + if (ConnectorSecretsFeature.isEnabled()) { + actionHandlers.addAll( + List.of( + new ActionHandler<>(GetConnectorSecretAction.INSTANCE, TransportGetConnectorSecretAction.class), + new ActionHandler<>(PostConnectorSecretAction.INSTANCE, TransportPostConnectorSecretAction.class) + ) + ); + } + return Collections.unmodifiableList(actionHandlers); } @@ -337,6 +354,10 @@ public List getRestHandlers( ); } + if (ConnectorSecretsFeature.isEnabled()) { + restHandlers.addAll(List.of(new RestGetConnectorSecretAction(), new RestPostConnectorSecretAction())); + } + return Collections.unmodifiableList(restHandlers); } @@ -371,7 +392,15 @@ public Collection createComponents(PluginServices services) { @Override public Collection getSystemIndexDescriptors(Settings settings) { - return Arrays.asList(SearchApplicationIndexService.getSystemIndexDescriptor(), QueryRulesIndexService.getSystemIndexDescriptor()); + Collection systemIndices = new ArrayList<>( + List.of(SearchApplicationIndexService.getSystemIndexDescriptor(), QueryRulesIndexService.getSystemIndexDescriptor()) + ); + + if (ConnectorSecretsFeature.isEnabled()) { + systemIndices.add(ConnectorSecretsIndexService.getSystemIndexDescriptor()); + } + + return systemIndices; } @Override diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsFeature.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsFeature.java new file mode 100644 index 0000000000000..7fd109db40470 --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsFeature.java @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets; + +import org.elasticsearch.common.util.FeatureFlag; + +/** + * Connector Secrets feature flag. When the feature is complete, this flag will be removed. + */ +public class ConnectorSecretsFeature { + + private static final FeatureFlag SECRETS_FEATURE_FLAG = new FeatureFlag("connector_secrets"); + + /** + * Enables the Connectors Secrets feature by default for the tech preview phase. + * As documented, the Connectors Secrets is currently a tech preview feature, + * and customers should be aware that no SLAs or support are guaranteed during + * its pre-General Availability (GA) stage. + * + * Instead of removing the feature flag from the code, we enable it by default. + * This approach allows for the complete deactivation of the feature during the QA phase, + * should any critical bugs be discovered, with a single, trackable code change. + */ + public static boolean isEnabled() { + return true; + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsIndexService.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsIndexService.java new file mode 100644 index 0000000000000..633909ac2aa89 --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsIndexService.java @@ -0,0 +1,96 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets; + +import org.elasticsearch.ResourceNotFoundException; +import org.elasticsearch.Version; +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest; +import org.elasticsearch.client.internal.Client; +import org.elasticsearch.client.internal.OriginSettingClient; +import org.elasticsearch.indices.SystemIndexDescriptor; +import org.elasticsearch.xcontent.XContentType; +import org.elasticsearch.xpack.application.connector.secrets.action.GetConnectorSecretResponse; +import org.elasticsearch.xpack.application.connector.secrets.action.PostConnectorSecretRequest; +import org.elasticsearch.xpack.application.connector.secrets.action.PostConnectorSecretResponse; +import org.elasticsearch.xpack.core.template.TemplateUtils; + +import java.util.Map; + +import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder; +import static org.elasticsearch.xpack.core.ClientHelper.CONNECTORS_ORIGIN; + +/** + * A service that manages persistent Connector Secrets. + */ +public class ConnectorSecretsIndexService { + + private final Client clientWithOrigin; + + public static final String CONNECTOR_SECRETS_INDEX_NAME = ".connector-secrets"; + private static final int CURRENT_INDEX_VERSION = 1; + private static final String MAPPING_VERSION_VARIABLE = "connector-secrets.version"; + private static final String MAPPING_MANAGED_VERSION_VARIABLE = "connector-secrets.managed.index.version"; + + public ConnectorSecretsIndexService(Client client) { + this.clientWithOrigin = new OriginSettingClient(client, CONNECTORS_ORIGIN); + } + + /** + * Returns the {@link SystemIndexDescriptor} for the Connector Secrets system index. + * + * @return The {@link SystemIndexDescriptor} for the Connector Secrets system index. + */ + public static SystemIndexDescriptor getSystemIndexDescriptor() { + PutIndexTemplateRequest request = new PutIndexTemplateRequest(); + + String templateSource = TemplateUtils.loadTemplate( + "/connector-secrets.json", + Version.CURRENT.toString(), + MAPPING_VERSION_VARIABLE, + Map.of(MAPPING_MANAGED_VERSION_VARIABLE, Integer.toString(CURRENT_INDEX_VERSION)) + ); + request.source(templateSource, XContentType.JSON); + + return SystemIndexDescriptor.builder() + .setIndexPattern(CONNECTOR_SECRETS_INDEX_NAME + "*") + .setPrimaryIndex(CONNECTOR_SECRETS_INDEX_NAME + "-" + CURRENT_INDEX_VERSION) + .setDescription("Secret values managed by Connectors") + .setMappings(request.mappings()) + .setSettings(request.settings()) + .setAliasName(CONNECTOR_SECRETS_INDEX_NAME) + .setVersionMetaKey("version") + .setOrigin(CONNECTORS_ORIGIN) + .setType(SystemIndexDescriptor.Type.INTERNAL_MANAGED) + .build(); + } + + public void getSecret(String id, ActionListener listener) { + clientWithOrigin.prepareGet(CONNECTOR_SECRETS_INDEX_NAME, id).execute(listener.delegateFailureAndWrap((delegate, getResponse) -> { + if (getResponse.isSourceEmpty()) { + delegate.onFailure(new ResourceNotFoundException("No secret with id [" + id + "]")); + return; + } + delegate.onResponse(new GetConnectorSecretResponse(getResponse.getId(), getResponse.getSource().get("value").toString())); + })); + } + + public void createSecret(PostConnectorSecretRequest request, ActionListener listener) { + try { + clientWithOrigin.prepareIndex(CONNECTOR_SECRETS_INDEX_NAME) + .setSource(request.toXContent(jsonBuilder())) + .execute( + listener.delegateFailureAndWrap( + (l, indexResponse) -> l.onResponse(new PostConnectorSecretResponse(indexResponse.getId())) + ) + ); + } catch (Exception e) { + listener.onFailure(e); + } + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretAction.java new file mode 100644 index 0000000000000..cc0601336242c --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretAction.java @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.action.ActionType; + +public class GetConnectorSecretAction extends ActionType { + + public static final String NAME = "cluster:admin/xpack/connector/secret/get"; + + public static final GetConnectorSecretAction INSTANCE = new GetConnectorSecretAction(); + + private GetConnectorSecretAction() { + super(NAME, GetConnectorSecretResponse::new); + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretRequest.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretRequest.java new file mode 100644 index 0000000000000..cf1cc0f563eba --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretRequest.java @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.action.ActionRequest; +import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; + +import java.io.IOException; +import java.util.Objects; + +import static org.elasticsearch.action.ValidateActions.addValidationError; + +public class GetConnectorSecretRequest extends ActionRequest { + + private final String id; + + public GetConnectorSecretRequest(String id) { + this.id = Objects.requireNonNull(id); + } + + public GetConnectorSecretRequest(StreamInput in) throws IOException { + super(in); + id = in.readString(); + } + + public String id() { + return id; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeString(id); + } + + @Override + public ActionRequestValidationException validate() { + ActionRequestValidationException validationException = null; + + if (Strings.isNullOrEmpty(id)) { + validationException = addValidationError("id missing", validationException); + } + + return validationException; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + GetConnectorSecretRequest that = (GetConnectorSecretRequest) o; + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretResponse.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretResponse.java new file mode 100644 index 0000000000000..3bbcb8212d51c --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretResponse.java @@ -0,0 +1,70 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.xcontent.ToXContent; +import org.elasticsearch.xcontent.ToXContentObject; +import org.elasticsearch.xcontent.XContentBuilder; + +import java.io.IOException; +import java.util.Objects; + +public class GetConnectorSecretResponse extends ActionResponse implements ToXContentObject { + + private final String id; + private final String value; + + public GetConnectorSecretResponse(StreamInput in) throws IOException { + super(in); + id = in.readString(); + value = in.readString(); + } + + public GetConnectorSecretResponse(String id, String value) { + this.id = id; + this.value = value; + } + + public String id() { + return id; + } + + public String value() { + return value; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(id); + out.writeString(value); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException { + builder.startObject(); + builder.field("id", id); + builder.field("value", value); + return builder.endObject(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + GetConnectorSecretResponse that = (GetConnectorSecretResponse) o; + return Objects.equals(id, that.id) && Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(id, value); + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretAction.java new file mode 100644 index 0000000000000..44bc3a03be5c8 --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretAction.java @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.action.ActionType; + +public class PostConnectorSecretAction extends ActionType { + + public static final String NAME = "cluster:admin/xpack/connector/secret/post"; + + public static final PostConnectorSecretAction INSTANCE = new PostConnectorSecretAction(); + + private PostConnectorSecretAction() { + super(NAME, PostConnectorSecretResponse::new); + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretRequest.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretRequest.java new file mode 100644 index 0000000000000..2e565dece7eca --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretRequest.java @@ -0,0 +1,99 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.action.ActionRequest; +import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.xcontent.ConstructingObjectParser; +import org.elasticsearch.xcontent.ObjectParser; +import org.elasticsearch.xcontent.ParseField; +import org.elasticsearch.xcontent.XContentBuilder; +import org.elasticsearch.xcontent.XContentParser; + +import java.io.IOException; +import java.util.Objects; + +public class PostConnectorSecretRequest extends ActionRequest { + + public static final ParseField VALUE_FIELD = new ParseField("value"); + + public static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( + "post_secret_request", + args -> { + return new PostConnectorSecretRequest((String) args[0]); + } + ); + + static { + PARSER.declareField( + ConstructingObjectParser.optionalConstructorArg(), + (p, c) -> p.text(), + VALUE_FIELD, + ObjectParser.ValueType.STRING + ); + } + + public static PostConnectorSecretRequest fromXContent(XContentParser parser) throws IOException { + return PARSER.parse(parser, null); + } + + private final String value; + + public PostConnectorSecretRequest(String value) { + this.value = value; + } + + public PostConnectorSecretRequest(StreamInput in) throws IOException { + super(in); + this.value = in.readString(); + } + + public String value() { + return value; + } + + public XContentBuilder toXContent(XContentBuilder builder) throws IOException { + builder.startObject(); + builder.field(VALUE_FIELD.getPreferredName(), this.value); + builder.endObject(); + return builder; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeString(value); + } + + @Override + public ActionRequestValidationException validate() { + if (Strings.isNullOrEmpty(this.value)) { + ActionRequestValidationException exception = new ActionRequestValidationException(); + exception.addValidationError("value is missing"); + return exception; + } + + return null; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PostConnectorSecretRequest that = (PostConnectorSecretRequest) o; + return Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretResponse.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretResponse.java new file mode 100644 index 0000000000000..068b510c5fad5 --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretResponse.java @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.xcontent.ToXContent; +import org.elasticsearch.xcontent.ToXContentObject; +import org.elasticsearch.xcontent.XContentBuilder; + +import java.io.IOException; +import java.util.Objects; + +public class PostConnectorSecretResponse extends ActionResponse implements ToXContentObject { + + private final String id; + + public PostConnectorSecretResponse(String id) { + this.id = id; + } + + public PostConnectorSecretResponse(StreamInput in) throws IOException { + super(in); + this.id = in.readString(); + } + + public String id() { + return id; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(id); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException { + builder.startObject(); + builder.field("id", id); + return builder.endObject(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PostConnectorSecretResponse that = (PostConnectorSecretResponse) o; + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/RestGetConnectorSecretAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/RestGetConnectorSecretAction.java new file mode 100644 index 0000000000000..6ab5c1055c3a4 --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/RestGetConnectorSecretAction.java @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.client.internal.node.NodeClient; +import org.elasticsearch.rest.BaseRestHandler; +import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.Scope; +import org.elasticsearch.rest.ServerlessScope; +import org.elasticsearch.rest.action.RestToXContentListener; + +import java.io.IOException; +import java.util.List; + +@ServerlessScope(Scope.INTERNAL) +public class RestGetConnectorSecretAction extends BaseRestHandler { + + @Override + public String getName() { + return "connector_get_secret"; + } + + @Override + public List routes() { + return List.of(new Route(RestRequest.Method.GET, "/_connector/_secret/{id}")); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + final String id = request.param("id"); + return restChannel -> client.execute( + GetConnectorSecretAction.INSTANCE, + new GetConnectorSecretRequest(id), + new RestToXContentListener<>(restChannel) + ); + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/RestPostConnectorSecretAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/RestPostConnectorSecretAction.java new file mode 100644 index 0000000000000..eeacde1bdb3c5 --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/RestPostConnectorSecretAction.java @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.client.internal.node.NodeClient; +import org.elasticsearch.rest.BaseRestHandler; +import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.Scope; +import org.elasticsearch.rest.ServerlessScope; +import org.elasticsearch.rest.action.RestToXContentListener; +import org.elasticsearch.xcontent.XContentParser; + +import java.io.IOException; +import java.util.List; + +@ServerlessScope(Scope.INTERNAL) +public class RestPostConnectorSecretAction extends BaseRestHandler { + + @Override + public String getName() { + return "connector_post_secret"; + } + + @Override + public List routes() { + return List.of(new Route(RestRequest.Method.POST, "/_connector/_secret")); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + try (XContentParser parser = request.contentParser()) { + PostConnectorSecretRequest postSecretRequest = PostConnectorSecretRequest.fromXContent(parser); + return restChannel -> client.execute( + PostConnectorSecretAction.INSTANCE, + postSecretRequest, + new RestToXContentListener<>(restChannel) + ); + } + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportGetConnectorSecretAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportGetConnectorSecretAction.java new file mode 100644 index 0000000000000..aaa03fa13298f --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportGetConnectorSecretAction.java @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.action.support.HandledTransportAction; +import org.elasticsearch.client.internal.Client; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.util.concurrent.EsExecutors; +import org.elasticsearch.tasks.Task; +import org.elasticsearch.transport.TransportService; +import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsIndexService; + +public class TransportGetConnectorSecretAction extends HandledTransportAction { + + private final ConnectorSecretsIndexService connectorSecretsIndexService; + + @Inject + public TransportGetConnectorSecretAction(TransportService transportService, ActionFilters actionFilters, Client client) { + super( + GetConnectorSecretAction.NAME, + transportService, + actionFilters, + GetConnectorSecretRequest::new, + EsExecutors.DIRECT_EXECUTOR_SERVICE + ); + this.connectorSecretsIndexService = new ConnectorSecretsIndexService(client); + } + + protected void doExecute(Task task, GetConnectorSecretRequest request, ActionListener listener) { + connectorSecretsIndexService.getSecret(request.id(), listener); + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportPostConnectorSecretAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportPostConnectorSecretAction.java new file mode 100644 index 0000000000000..7cc3195ccbbf2 --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportPostConnectorSecretAction.java @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.action.support.HandledTransportAction; +import org.elasticsearch.client.internal.Client; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.util.concurrent.EsExecutors; +import org.elasticsearch.tasks.Task; +import org.elasticsearch.transport.TransportService; +import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsIndexService; + +public class TransportPostConnectorSecretAction extends HandledTransportAction { + + private final ConnectorSecretsIndexService connectorSecretsIndexService; + + @Inject + public TransportPostConnectorSecretAction(TransportService transportService, ActionFilters actionFilters, Client client) { + super( + PostConnectorSecretAction.NAME, + transportService, + actionFilters, + PostConnectorSecretRequest::new, + EsExecutors.DIRECT_EXECUTOR_SERVICE + ); + this.connectorSecretsIndexService = new ConnectorSecretsIndexService(client); + } + + protected void doExecute(Task task, PostConnectorSecretRequest request, ActionListener listener) { + connectorSecretsIndexService.createSecret(request, listener); + } +} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsIndexServiceTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsIndexServiceTests.java new file mode 100644 index 0000000000000..f9a548a47feb3 --- /dev/null +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsIndexServiceTests.java @@ -0,0 +1,104 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.test.ESSingleNodeTestCase; +import org.elasticsearch.xpack.application.connector.secrets.action.GetConnectorSecretResponse; +import org.elasticsearch.xpack.application.connector.secrets.action.PostConnectorSecretRequest; +import org.elasticsearch.xpack.application.connector.secrets.action.PostConnectorSecretResponse; +import org.junit.Before; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; + +public class ConnectorSecretsIndexServiceTests extends ESSingleNodeTestCase { + + private static final int TIMEOUT_SECONDS = 10; + + private ConnectorSecretsIndexService connectorSecretsIndexService; + + @Before + public void setup() throws Exception { + this.connectorSecretsIndexService = new ConnectorSecretsIndexService(client()); + } + + public void testCreateAndGetConnectorSecret() throws Exception { + PostConnectorSecretRequest createSecretRequest = ConnectorSecretsTestUtils.getRandomPostConnectorSecretRequest(); + PostConnectorSecretResponse createdSecret = awaitPostConnectorSecret(createSecretRequest); + + GetConnectorSecretResponse gotSecret = awaitGetConnectorSecret(createdSecret.id()); + + assertThat(gotSecret.id(), equalTo(createdSecret.id())); + assertThat(gotSecret.value(), notNullValue()); + } + + private PostConnectorSecretResponse awaitPostConnectorSecret(PostConnectorSecretRequest secretRequest) throws Exception { + CountDownLatch latch = new CountDownLatch(1); + + final AtomicReference responseRef = new AtomicReference<>(null); + final AtomicReference exception = new AtomicReference<>(null); + + connectorSecretsIndexService.createSecret(secretRequest, new ActionListener<>() { + @Override + public void onResponse(PostConnectorSecretResponse postConnectorSecretResponse) { + responseRef.set(postConnectorSecretResponse); + latch.countDown(); + } + + @Override + public void onFailure(Exception e) { + exception.set(e); + latch.countDown(); + } + }); + + if (exception.get() != null) { + throw exception.get(); + } + + boolean requestTimedOut = latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS); + PostConnectorSecretResponse response = responseRef.get(); + + assertTrue("Timeout waiting for post request", requestTimedOut); + assertNotNull("Received null response from post request", response); + + return response; + } + + private GetConnectorSecretResponse awaitGetConnectorSecret(String connectorSecretId) throws Exception { + CountDownLatch latch = new CountDownLatch(1); + final AtomicReference resp = new AtomicReference<>(null); + final AtomicReference exc = new AtomicReference<>(null); + + connectorSecretsIndexService.getSecret(connectorSecretId, new ActionListener() { + @Override + public void onResponse(GetConnectorSecretResponse response) { + resp.set(response); + latch.countDown(); + } + + @Override + public void onFailure(Exception e) { + exc.set(e); + latch.countDown(); + } + }); + + assertTrue("Timeout waiting for get request", latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS)); + if (exc.get() != null) { + throw exc.get(); + } + assertNotNull("Received null response from get request", resp.get()); + return resp.get(); + } +} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsTestUtils.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsTestUtils.java new file mode 100644 index 0000000000000..c7cec3a263af0 --- /dev/null +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsTestUtils.java @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets; + +import org.elasticsearch.xpack.application.connector.secrets.action.GetConnectorSecretRequest; +import org.elasticsearch.xpack.application.connector.secrets.action.GetConnectorSecretResponse; +import org.elasticsearch.xpack.application.connector.secrets.action.PostConnectorSecretRequest; +import org.elasticsearch.xpack.application.connector.secrets.action.PostConnectorSecretResponse; + +import static org.elasticsearch.test.ESTestCase.randomAlphaOfLength; +import static org.elasticsearch.test.ESTestCase.randomAlphaOfLengthBetween; + +public class ConnectorSecretsTestUtils { + + public static GetConnectorSecretRequest getRandomGetConnectorSecretRequest() { + return new GetConnectorSecretRequest(randomAlphaOfLength(10)); + } + + public static GetConnectorSecretResponse getRandomGetConnectorSecretResponse() { + final String id = randomAlphaOfLength(10); + final String value = randomAlphaOfLength(10); + return new GetConnectorSecretResponse(id, value); + } + + public static PostConnectorSecretRequest getRandomPostConnectorSecretRequest() { + return new PostConnectorSecretRequest(randomAlphaOfLengthBetween(0, 20)); + } + + public static PostConnectorSecretResponse getRandomPostConnectorSecretResponse() { + return new PostConnectorSecretResponse(randomAlphaOfLength(10)); + } +} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretActionTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretActionTests.java new file mode 100644 index 0000000000000..9fc01e56ee5a0 --- /dev/null +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretActionTests.java @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsTestUtils; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; + +public class GetConnectorSecretActionTests extends ESTestCase { + + public void testValidate_WhenConnectorSecretIdIsPresent_ExpectNoValidationError() { + GetConnectorSecretRequest request = ConnectorSecretsTestUtils.getRandomGetConnectorSecretRequest(); + ActionRequestValidationException exception = request.validate(); + + assertThat(exception, nullValue()); + } + + public void testValidate_WhenConnectorSecretIdIsEmpty_ExpectValidationError() { + GetConnectorSecretRequest requestWithMissingConnectorId = new GetConnectorSecretRequest(""); + ActionRequestValidationException exception = requestWithMissingConnectorId.validate(); + + assertThat(exception, notNullValue()); + assertThat(exception.getMessage(), containsString("id missing")); + } +} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretRequestBWCSerializingTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretRequestBWCSerializingTests.java new file mode 100644 index 0000000000000..abac910aa1dac --- /dev/null +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretRequestBWCSerializingTests.java @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.TransportVersion; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.xpack.core.ml.AbstractBWCWireSerializationTestCase; + +import java.io.IOException; + +public class GetConnectorSecretRequestBWCSerializingTests extends AbstractBWCWireSerializationTestCase { + + @Override + protected Writeable.Reader instanceReader() { + return GetConnectorSecretRequest::new; + } + + @Override + protected GetConnectorSecretRequest createTestInstance() { + return new GetConnectorSecretRequest(randomAlphaOfLengthBetween(1, 10)); + } + + @Override + protected GetConnectorSecretRequest mutateInstance(GetConnectorSecretRequest instance) throws IOException { + return randomValueOtherThan(instance, this::createTestInstance); + } + + @Override + protected GetConnectorSecretRequest mutateInstanceForVersion(GetConnectorSecretRequest instance, TransportVersion version) { + return new GetConnectorSecretRequest(instance.id()); + } +} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretResponseBWCSerializingTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretResponseBWCSerializingTests.java new file mode 100644 index 0000000000000..4448024814df3 --- /dev/null +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretResponseBWCSerializingTests.java @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.TransportVersion; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.xpack.application.connector.Connector; +import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsTestUtils; +import org.elasticsearch.xpack.core.ml.AbstractBWCWireSerializationTestCase; + +import java.io.IOException; +import java.util.List; + +public class GetConnectorSecretResponseBWCSerializingTests extends AbstractBWCWireSerializationTestCase { + + @Override + public NamedWriteableRegistry getNamedWriteableRegistry() { + return new NamedWriteableRegistry(List.of(new NamedWriteableRegistry.Entry(Connector.class, Connector.NAME, Connector::new))); + } + + @Override + protected Writeable.Reader instanceReader() { + return GetConnectorSecretResponse::new; + } + + @Override + protected GetConnectorSecretResponse createTestInstance() { + return ConnectorSecretsTestUtils.getRandomGetConnectorSecretResponse(); + } + + @Override + protected GetConnectorSecretResponse mutateInstance(GetConnectorSecretResponse instance) throws IOException { + return randomValueOtherThan(instance, this::createTestInstance); + } + + @Override + protected GetConnectorSecretResponse mutateInstanceForVersion(GetConnectorSecretResponse instance, TransportVersion version) { + return instance; + } +} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretActionTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretActionTests.java new file mode 100644 index 0000000000000..f1e1a670b2748 --- /dev/null +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretActionTests.java @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsTestUtils; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; + +public class PostConnectorSecretActionTests extends ESTestCase { + + public void testValidate_WhenConnectorSecretIdIsPresent_ExpectNoValidationError() { + PostConnectorSecretRequest request = ConnectorSecretsTestUtils.getRandomPostConnectorSecretRequest(); + ActionRequestValidationException exception = request.validate(); + + assertThat(exception, nullValue()); + } + + public void testValidate_WhenConnectorSecretIdIsEmpty_ExpectValidationError() { + PostConnectorSecretRequest requestWithMissingValue = new PostConnectorSecretRequest(""); + ActionRequestValidationException exception = requestWithMissingValue.validate(); + + assertThat(exception, notNullValue()); + assertThat(exception.getMessage(), containsString("value is missing")); + } +} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretRequestBWCSerializingTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretRequestBWCSerializingTests.java new file mode 100644 index 0000000000000..b7f8c501a91e8 --- /dev/null +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretRequestBWCSerializingTests.java @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.TransportVersion; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsTestUtils; +import org.elasticsearch.xpack.core.ml.AbstractBWCWireSerializationTestCase; + +import java.io.IOException; + +public class PostConnectorSecretRequestBWCSerializingTests extends AbstractBWCWireSerializationTestCase { + + @Override + protected Writeable.Reader instanceReader() { + return PostConnectorSecretRequest::new; + } + + @Override + protected PostConnectorSecretRequest createTestInstance() { + return ConnectorSecretsTestUtils.getRandomPostConnectorSecretRequest(); + } + + @Override + protected PostConnectorSecretRequest mutateInstance(PostConnectorSecretRequest instance) throws IOException { + return randomValueOtherThan(instance, this::createTestInstance); + } + + @Override + protected PostConnectorSecretRequest mutateInstanceForVersion(PostConnectorSecretRequest instance, TransportVersion version) { + return instance; + } +} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretResponseBWCSerializingTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretResponseBWCSerializingTests.java new file mode 100644 index 0000000000000..e114181270e95 --- /dev/null +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretResponseBWCSerializingTests.java @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.TransportVersion; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsTestUtils; +import org.elasticsearch.xpack.core.ml.AbstractBWCWireSerializationTestCase; + +import java.io.IOException; + +public class PostConnectorSecretResponseBWCSerializingTests extends AbstractBWCWireSerializationTestCase { + + @Override + protected Writeable.Reader instanceReader() { + return PostConnectorSecretResponse::new; + } + + @Override + protected PostConnectorSecretResponse createTestInstance() { + return ConnectorSecretsTestUtils.getRandomPostConnectorSecretResponse(); + } + + @Override + protected PostConnectorSecretResponse mutateInstance(PostConnectorSecretResponse instance) throws IOException { + return randomValueOtherThan(instance, this::createTestInstance); + } + + @Override + protected PostConnectorSecretResponse mutateInstanceForVersion(PostConnectorSecretResponse instance, TransportVersion version) { + return instance; + } + +} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportGetConnectorSecretActionTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportGetConnectorSecretActionTests.java new file mode 100644 index 0000000000000..6b046c7e44506 --- /dev/null +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportGetConnectorSecretActionTests.java @@ -0,0 +1,72 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.tasks.Task; +import org.elasticsearch.test.ESSingleNodeTestCase; +import org.elasticsearch.threadpool.TestThreadPool; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.transport.Transport; +import org.elasticsearch.transport.TransportService; +import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsTestUtils; +import org.junit.Before; + +import java.util.Collections; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static org.mockito.Mockito.mock; + +public class TransportGetConnectorSecretActionTests extends ESSingleNodeTestCase { + + private static final Long TIMEOUT_SECONDS = 10L; + + private final ThreadPool threadPool = new TestThreadPool(getClass().getName()); + private TransportGetConnectorSecretAction action; + + @Before + public void setup() { + TransportService transportService = new TransportService( + Settings.EMPTY, + mock(Transport.class), + threadPool, + TransportService.NOOP_TRANSPORT_INTERCEPTOR, + x -> null, + null, + Collections.emptySet() + ); + + action = new TransportGetConnectorSecretAction(transportService, mock(ActionFilters.class), client()); + } + + @Override + public void tearDown() throws Exception { + super.tearDown(); + ThreadPool.terminate(threadPool, TIMEOUT_SECONDS, TimeUnit.SECONDS); + } + + public void testGetConnectorSecret_ExpectNoWarnings() throws InterruptedException { + GetConnectorSecretRequest request = ConnectorSecretsTestUtils.getRandomGetConnectorSecretRequest(); + + executeRequest(request); + + ensureNoWarnings(); + } + + private void executeRequest(GetConnectorSecretRequest request) throws InterruptedException { + final CountDownLatch latch = new CountDownLatch(1); + action.doExecute(mock(Task.class), request, ActionListener.wrap(response -> latch.countDown(), exception -> latch.countDown())); + + boolean requestTimedOut = latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS); + + assertTrue("Timeout waiting for get request", requestTimedOut); + } +} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportPostConnectorSecretActionTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportPostConnectorSecretActionTests.java new file mode 100644 index 0000000000000..056d2786de1d7 --- /dev/null +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportPostConnectorSecretActionTests.java @@ -0,0 +1,72 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.secrets.action; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.tasks.Task; +import org.elasticsearch.test.ESSingleNodeTestCase; +import org.elasticsearch.threadpool.TestThreadPool; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.transport.Transport; +import org.elasticsearch.transport.TransportService; +import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsTestUtils; +import org.junit.Before; + +import java.util.Collections; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static org.mockito.Mockito.mock; + +public class TransportPostConnectorSecretActionTests extends ESSingleNodeTestCase { + + private static final Long TIMEOUT_SECONDS = 10L; + + private final ThreadPool threadPool = new TestThreadPool(getClass().getName()); + private TransportPostConnectorSecretAction action; + + @Before + public void setup() { + TransportService transportService = new TransportService( + Settings.EMPTY, + mock(Transport.class), + threadPool, + TransportService.NOOP_TRANSPORT_INTERCEPTOR, + x -> null, + null, + Collections.emptySet() + ); + + action = new TransportPostConnectorSecretAction(transportService, mock(ActionFilters.class), client()); + } + + @Override + public void tearDown() throws Exception { + super.tearDown(); + ThreadPool.terminate(threadPool, TIMEOUT_SECONDS, TimeUnit.SECONDS); + } + + public void testPostConnectorSecret_ExpectNoWarnings() throws InterruptedException { + PostConnectorSecretRequest request = ConnectorSecretsTestUtils.getRandomPostConnectorSecretRequest(); + + executeRequest(request); + + ensureNoWarnings(); + } + + private void executeRequest(PostConnectorSecretRequest request) throws InterruptedException { + final CountDownLatch latch = new CountDownLatch(1); + action.doExecute(mock(Task.class), request, ActionListener.wrap(response -> latch.countDown(), exception -> latch.countDown())); + + boolean requestTimedOut = latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS); + + assertTrue("Timeout waiting for post request", requestTimedOut); + } +} diff --git a/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java b/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java index d4d0bded045f6..ce9db5015a0da 100644 --- a/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java +++ b/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java @@ -138,6 +138,8 @@ public class Constants { "cluster:admin/xpack/connector/update_pipeline", "cluster:admin/xpack/connector/update_scheduling", "cluster:admin/xpack/connector/update_service_type", + "cluster:admin/xpack/connector/secret/get", + "cluster:admin/xpack/connector/secret/post", "cluster:admin/xpack/connector/sync_job/cancel", "cluster:admin/xpack/connector/sync_job/check_in", "cluster:admin/xpack/connector/sync_job/delete", diff --git a/x-pack/plugin/security/qa/service-account/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/service/ServiceAccountIT.java b/x-pack/plugin/security/qa/service-account/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/service/ServiceAccountIT.java index f66631a57b4bb..e790866cf3d77 100644 --- a/x-pack/plugin/security/qa/service-account/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/service/ServiceAccountIT.java +++ b/x-pack/plugin/security/qa/service-account/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/service/ServiceAccountIT.java @@ -280,7 +280,9 @@ public class ServiceAccountIT extends ESRestTestCase { { "cluster": [ "manage", - "manage_security" + "manage_security", + "read_connector_secrets", + "write_connector_secrets" ], "indices": [ { diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccounts.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccounts.java index 777fe5f71b0a0..abd586920f2d8 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccounts.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccounts.java @@ -26,7 +26,7 @@ final class ElasticServiceAccounts { "enterprise-search-server", new RoleDescriptor( NAMESPACE + "/enterprise-search-server", - new String[] { "manage", "manage_security" }, + new String[] { "manage", "manage_security", "read_connector_secrets", "write_connector_secrets" }, new RoleDescriptor.IndicesPrivileges[] { RoleDescriptor.IndicesPrivileges.builder() .indices( diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccountsTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccountsTests.java index ecef71f1c4a68..46fde61690017 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccountsTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccountsTests.java @@ -344,6 +344,10 @@ public void testElasticEnterpriseSearchServerAccount() { assertThat(role.cluster().check(GetLifecycleAction.NAME, request, authentication), is(true)); assertThat(role.cluster().check(ILMActions.PUT.name(), request, authentication), is(true)); + // Connector secrets. Enterprise Search has read and write access. + assertThat(role.cluster().check("cluster:admin/xpack/connector/secret/get", request, authentication), is(true)); + assertThat(role.cluster().check("cluster:admin/xpack/connector/secret/post", request, authentication), is(true)); + List.of( "search-" + randomAlphaOfLengthBetween(1, 20), ".search-acl-filter-" + randomAlphaOfLengthBetween(1, 20), diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/privileges/11_builtin.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/privileges/11_builtin.yml index e2e220aa55456..319b84e855aaf 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/privileges/11_builtin.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/privileges/11_builtin.yml @@ -15,5 +15,5 @@ setup: # This is fragile - it needs to be updated every time we add a new cluster/index privilege # I would much prefer we could just check that specific entries are in the array, but we don't have # an assertion for that - - length: { "cluster" : 53 } + - length: { "cluster" : 55 } - length: { "index" : 22 } From 4e91d690e548a3952712a9c80c9081a35d9b2bfd Mon Sep 17 00:00:00 2001 From: David Roberts Date: Thu, 25 Jan 2024 13:01:35 +0000 Subject: [PATCH 25/37] Export random sampler agg from server (#104747) The server module exports the classes needed to use most aggregations, but the random sampler aggregation was missed. (I think it's because the PRs to add random sampler and to add modularization in general were both long-running and were in flight around the same time.) This PR adds an export for the random sampler agg, so that it can be used from plugins. --- server/src/main/java/module-info.java | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/main/java/module-info.java b/server/src/main/java/module-info.java index e72cb6c53e8e5..eddc96764273c 100644 --- a/server/src/main/java/module-info.java +++ b/server/src/main/java/module-info.java @@ -333,6 +333,7 @@ exports org.elasticsearch.search.aggregations.bucket.nested; exports org.elasticsearch.search.aggregations.bucket.range; exports org.elasticsearch.search.aggregations.bucket.sampler; + exports org.elasticsearch.search.aggregations.bucket.sampler.random; exports org.elasticsearch.search.aggregations.bucket.terms; exports org.elasticsearch.search.aggregations.bucket.terms.heuristic; exports org.elasticsearch.search.aggregations.metrics; From e48b54958857ef8a6fa3ac8b08d70aeb137db4a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Istv=C3=A1n=20Zolt=C3=A1n=20Szab=C3=B3?= Date: Thu, 25 Jan 2024 14:22:17 +0100 Subject: [PATCH 26/37] [DOCS] Fixes asciidoc syntax in PUT trained models API docs. (#104741) --- .../ml/trained-models/apis/put-trained-models.asciidoc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/reference/ml/trained-models/apis/put-trained-models.asciidoc b/docs/reference/ml/trained-models/apis/put-trained-models.asciidoc index 45517b99c2177..27555070e9c5a 100644 --- a/docs/reference/ml/trained-models/apis/put-trained-models.asciidoc +++ b/docs/reference/ml/trained-models/apis/put-trained-models.asciidoc @@ -709,10 +709,12 @@ be applied to the input text before the input is evaluated. The prefix may be different depending on the intention. For asymmetric tasks such as infromation retrieval the prefix applied to a passage as it is indexed can be different to the prefix applied when searching those passages. - ++ +-- `prefix_strings` has 2 options, a prefix string that is always applied in the search context and one that is always applied when ingesting the docs. Both are optional. +-- + .Properties of `prefix_strings` [%collapsible%open] @@ -725,7 +727,8 @@ originating from a search query. `ingest`::: (Optional, string) The prefix string to prepend to the input text for requests -at ingest where the {infer} ingest processor is used. // TODO is there a shortcut for Inference ingest processor? +at ingest where the {infer} ingest processor is used. +// TODO is there a shortcut for Inference ingest processor? ==== //End prefix_strings From 209b655d0c90d7b90023bd63127da7ffb98f772d Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Thu, 25 Jan 2024 14:27:03 +0100 Subject: [PATCH 27/37] Avoid eager task realization (#103343) * Avoid eager task realization in esql qa projects * Fix eager task realization in PomValidationPrecommitPlugin * Make loadCsvSpecData task lazy created * Fix test task reference --- .../conventions/precommit/PomValidationPrecommitPlugin.java | 6 +++--- x-pack/plugin/esql/build.gradle | 2 +- x-pack/plugin/esql/qa/build.gradle | 2 +- x-pack/plugin/esql/qa/testFixtures/build.gradle | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/precommit/PomValidationPrecommitPlugin.java b/build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/precommit/PomValidationPrecommitPlugin.java index cf70cce6e166b..8bcb7f46475f9 100644 --- a/build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/precommit/PomValidationPrecommitPlugin.java +++ b/build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/precommit/PomValidationPrecommitPlugin.java @@ -30,11 +30,11 @@ public TaskProvider createTask(Project project) { .register("validate" + publicationName + "Pom", PomValidationTask.class); validatePom.configure(t -> t.dependsOn(validateTask)); validateTask.configure(task -> { - GenerateMavenPom generateMavenPom = project.getTasks() + TaskProvider generateMavenPom = project.getTasks() .withType(GenerateMavenPom.class) - .getByName("generatePomFileFor" + publicationName + "Publication"); + .named("generatePomFileFor" + publicationName + "Publication"); task.dependsOn(generateMavenPom); - task.getPomFile().fileValue(generateMavenPom.getDestination()); + task.getPomFile().fileProvider(generateMavenPom.map(GenerateMavenPom::getDestination)); }); }); diff --git a/x-pack/plugin/esql/build.gradle b/x-pack/plugin/esql/build.gradle index 15df4094fdec6..c8e94a94ebe7e 100644 --- a/x-pack/plugin/esql/build.gradle +++ b/x-pack/plugin/esql/build.gradle @@ -59,7 +59,7 @@ sourceSets.main.java { exclude 'generated/**' } -tasks.getByName('test') { +tasks.named("test").configure { if (BuildParams.isCi() == false) { systemProperty 'generateDocs', true doFirst { diff --git a/x-pack/plugin/esql/qa/build.gradle b/x-pack/plugin/esql/qa/build.gradle index 0b7d210bcd99e..d3109f6f9b307 100644 --- a/x-pack/plugin/esql/qa/build.gradle +++ b/x-pack/plugin/esql/qa/build.gradle @@ -1,5 +1,5 @@ description = 'Integration tests for ESQL' subprojects { - tasks.withType(Javadoc).all { enabled = false } + tasks.withType(Javadoc).configureEach { enabled = false } } diff --git a/x-pack/plugin/esql/qa/testFixtures/build.gradle b/x-pack/plugin/esql/qa/testFixtures/build.gradle index d313d615a1a42..cf1057452344c 100644 --- a/x-pack/plugin/esql/qa/testFixtures/build.gradle +++ b/x-pack/plugin/esql/qa/testFixtures/build.gradle @@ -23,7 +23,7 @@ dependencies { * If no arguments are specified, the default URL is http://localhost:9200 without authentication. * It also supports HTTPS. */ -task loadCsvSpecData(type: JavaExec) { +tasks.register("loadCsvSpecData", JavaExec) { group = "Execution" description = "Loads ESQL CSV Spec Tests data on a running stand-alone instance" classpath = sourceSets.main.runtimeClasspath From 05ea8c7a0f73ecad65bed7a50d58c02a21b7078b Mon Sep 17 00:00:00 2001 From: Navarone Feekery <13634519+navarone-feekery@users.noreply.github.com> Date: Thu, 25 Jan 2024 14:33:33 +0100 Subject: [PATCH 28/37] Revert "[Enterprise Search] Add `.connector-secrets` system index and GET/POST requests (#103683)" (#104760) This reverts commit b4345d9d9118494d22fdf228be87bcc52902f547. --- .../security/get-builtin-privileges.asciidoc | 2 - .../api/connector_secret.get.json | 28 ----- .../api/connector_secret.post.json | 26 ----- .../privilege/ClusterPrivilegeResolver.java | 14 +-- .../src/main/resources/connector-secrets.json | 26 ----- x-pack/plugin/ent-search/build.gradle | 7 -- x-pack/plugin/ent-search/qa/rest/roles.yml | 2 - .../entsearch/500_connector_secret_post.yml | 55 --------- .../entsearch/510_connector_secret_get.yml | 60 ---------- .../ConnectorSecretsSystemIndexIT.java | 94 ---------------- .../ent-search/src/main/java/module-info.java | 2 - .../xpack/application/EnterpriseSearch.java | 31 +----- .../secrets/ConnectorSecretsFeature.java | 32 ------ .../secrets/ConnectorSecretsIndexService.java | 96 ---------------- .../action/GetConnectorSecretAction.java | 21 ---- .../action/GetConnectorSecretRequest.java | 67 ----------- .../action/GetConnectorSecretResponse.java | 70 ------------ .../action/PostConnectorSecretAction.java | 21 ---- .../action/PostConnectorSecretRequest.java | 99 ----------------- .../action/PostConnectorSecretResponse.java | 61 ---------- .../action/RestGetConnectorSecretAction.java | 42 ------- .../action/RestPostConnectorSecretAction.java | 45 -------- .../TransportGetConnectorSecretAction.java | 39 ------- .../TransportPostConnectorSecretAction.java | 39 ------- .../ConnectorSecretsIndexServiceTests.java | 104 ------------------ .../secrets/ConnectorSecretsTestUtils.java | 37 ------- .../action/GetConnectorSecretActionTests.java | 34 ------ ...ectorSecretRequestBWCSerializingTests.java | 37 ------- ...ctorSecretResponseBWCSerializingTests.java | 46 -------- .../PostConnectorSecretActionTests.java | 34 ------ ...ectorSecretRequestBWCSerializingTests.java | 38 ------- ...ctorSecretResponseBWCSerializingTests.java | 39 ------- ...ransportGetConnectorSecretActionTests.java | 72 ------------ ...ansportPostConnectorSecretActionTests.java | 72 ------------ .../xpack/security/operator/Constants.java | 2 - .../authc/service/ServiceAccountIT.java | 4 +- .../authc/service/ElasticServiceAccounts.java | 2 +- .../service/ElasticServiceAccountsTests.java | 4 - .../test/privileges/11_builtin.yml | 2 +- 39 files changed, 5 insertions(+), 1501 deletions(-) delete mode 100644 rest-api-spec/src/main/resources/rest-api-spec/api/connector_secret.get.json delete mode 100644 rest-api-spec/src/main/resources/rest-api-spec/api/connector_secret.post.json delete mode 100644 x-pack/plugin/core/template-resources/src/main/resources/connector-secrets.json delete mode 100644 x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/500_connector_secret_post.yml delete mode 100644 x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/510_connector_secret_get.yml delete mode 100644 x-pack/plugin/ent-search/src/javaRestTest/java/org/elasticsearch/xpack/entsearch/ConnectorSecretsSystemIndexIT.java delete mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsFeature.java delete mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsIndexService.java delete mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretAction.java delete mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretRequest.java delete mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretResponse.java delete mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretAction.java delete mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretRequest.java delete mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretResponse.java delete mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/RestGetConnectorSecretAction.java delete mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/RestPostConnectorSecretAction.java delete mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportGetConnectorSecretAction.java delete mode 100644 x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportPostConnectorSecretAction.java delete mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsIndexServiceTests.java delete mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsTestUtils.java delete mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretActionTests.java delete mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretRequestBWCSerializingTests.java delete mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretResponseBWCSerializingTests.java delete mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretActionTests.java delete mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretRequestBWCSerializingTests.java delete mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretResponseBWCSerializingTests.java delete mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportGetConnectorSecretActionTests.java delete mode 100644 x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportPostConnectorSecretActionTests.java diff --git a/docs/reference/rest-api/security/get-builtin-privileges.asciidoc b/docs/reference/rest-api/security/get-builtin-privileges.asciidoc index bd2d21317212b..8f75293e2c1a4 100644 --- a/docs/reference/rest-api/security/get-builtin-privileges.asciidoc +++ b/docs/reference/rest-api/security/get-builtin-privileges.asciidoc @@ -108,14 +108,12 @@ A successful call returns an object with "cluster" and "index" fields. "none", "post_behavioral_analytics_event", "read_ccr", - "read_connector_secrets", "read_fleet_secrets", "read_ilm", "read_pipeline", "read_security", "read_slm", "transport_client", - "write_connector_secrets", "write_fleet_secrets" ], "index" : [ diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/connector_secret.get.json b/rest-api-spec/src/main/resources/rest-api-spec/api/connector_secret.get.json deleted file mode 100644 index f1037bedddfc6..0000000000000 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/connector_secret.get.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "connector_secret.get": { - "documentation": { - "url": null, - "description": "Retrieves a secret stored by Connectors." - }, - "stability": "experimental", - "visibility":"private", - "headers":{ - "accept": [ "application/json"] - }, - "url":{ - "paths":[ - { - "path":"/_connector/_secret/{id}", - "methods":[ "GET" ], - "parts":{ - "id":{ - "type":"string", - "description":"The ID of the secret" - } - } - } - ] - }, - "params":{} - } -} diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/connector_secret.post.json b/rest-api-spec/src/main/resources/rest-api-spec/api/connector_secret.post.json deleted file mode 100644 index 48657cf389446..0000000000000 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/connector_secret.post.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "connector_secret.post": { - "documentation": { - "url": null, - "description": "Creates a secret for a Connector." - }, - "stability": "experimental", - "visibility":"private", - "headers":{ - "accept": [ "application/json" ] - }, - "url":{ - "paths":[ - { - "path":"/_connector/_secret", - "methods":[ "POST" ] - } - ] - }, - "params":{}, - "body": { - "description":"The secret value to store", - "required":true - } - } -} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilegeResolver.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilegeResolver.java index 4637ca7edd8dd..ba6bca802070a 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilegeResolver.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilegeResolver.java @@ -326,16 +326,6 @@ public class ClusterPrivilegeResolver { CROSS_CLUSTER_REPLICATION_PATTERN ); - public static final NamedClusterPrivilege READ_CONNECTOR_SECRETS = new ActionClusterPrivilege( - "read_connector_secrets", - Set.of("cluster:admin/xpack/connector/secret/get") - ); - - public static final NamedClusterPrivilege WRITE_CONNECTOR_SECRETS = new ActionClusterPrivilege( - "write_connector_secrets", - Set.of("cluster:admin/xpack/connector/secret/post") - ); - private static final Map VALUES = sortByAccessLevel( Stream.of( NONE, @@ -390,9 +380,7 @@ public class ClusterPrivilegeResolver { POST_BEHAVIORAL_ANALYTICS_EVENT, MANAGE_SEARCH_QUERY_RULES, CROSS_CLUSTER_SEARCH, - CROSS_CLUSTER_REPLICATION, - READ_CONNECTOR_SECRETS, - WRITE_CONNECTOR_SECRETS + CROSS_CLUSTER_REPLICATION ).filter(Objects::nonNull).toList() ); diff --git a/x-pack/plugin/core/template-resources/src/main/resources/connector-secrets.json b/x-pack/plugin/core/template-resources/src/main/resources/connector-secrets.json deleted file mode 100644 index 96fa641726fa3..0000000000000 --- a/x-pack/plugin/core/template-resources/src/main/resources/connector-secrets.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "settings": { - "index": { - "auto_expand_replicas": "0-1", - "number_of_shards": 1, - "number_of_replicas": 0, - "priority": 100, - "refresh_interval": "1s" - } - }, - "mappings": { - "_doc" : { - "dynamic": false, - "_meta": { - "version": "${connector-secrets.version}", - "managed_index_mappings_version": ${connector-secrets.managed.index.version} - }, - "properties": { - "value": { - "type": "keyword", - "index": false - } - } - } - } -} diff --git a/x-pack/plugin/ent-search/build.gradle b/x-pack/plugin/ent-search/build.gradle index 4551011b03ca1..92a1c007f72bf 100644 --- a/x-pack/plugin/ent-search/build.gradle +++ b/x-pack/plugin/ent-search/build.gradle @@ -38,13 +38,6 @@ dependencies { module ':modules:search-business-rules' } -testClusters.configureEach { - testDistribution = 'DEFAULT' - setting 'xpack.security.enabled', 'true' - setting 'xpack.security.autoconfiguration.enabled', 'false' - user username: 'x_pack_rest_user', password: 'x-pack-test-password' -} - tasks.named("dependencyLicenses").configure { mapping from: /jackson.*/, to: 'jackson' } diff --git a/x-pack/plugin/ent-search/qa/rest/roles.yml b/x-pack/plugin/ent-search/qa/rest/roles.yml index 9dac14709db8d..4d868f41e78b3 100644 --- a/x-pack/plugin/ent-search/qa/rest/roles.yml +++ b/x-pack/plugin/ent-search/qa/rest/roles.yml @@ -16,8 +16,6 @@ user: cluster: - post_behavioral_analytics_event - manage_api_key - - read_connector_secrets - - write_connector_secrets indices: - names: [ "test-index1", diff --git a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/500_connector_secret_post.yml b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/500_connector_secret_post.yml deleted file mode 100644 index 6a4ee3ba7f6cb..0000000000000 --- a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/500_connector_secret_post.yml +++ /dev/null @@ -1,55 +0,0 @@ -setup: - - skip: - version: " - 8.12.99" - reason: Introduced in 8.13.0 - ---- -'Post connector secret - admin': - - do: - connector_secret.post: - body: - value: my-secret - - set: { id: id } - - match: { id: $id } - - do: - connector_secret.get: - id: $id - - match: { value: my-secret } - ---- -'Post connector secret - authorized user': - - skip: - features: headers - - - do: - headers: { Authorization: "Basic ZW50c2VhcmNoLXVzZXI6ZW50c2VhcmNoLXVzZXItcGFzc3dvcmQ=" } # user - connector_secret.post: - body: - value: my-secret - - set: { id: id } - - match: { id: $id } - - do: - headers: { Authorization: "Basic ZW50c2VhcmNoLXVzZXI6ZW50c2VhcmNoLXVzZXItcGFzc3dvcmQ=" } # user - connector_secret.get: - id: $id - - match: { value: my-secret } - ---- -'Post connector secret - unauthorized user': - - skip: - features: headers - - - do: - headers: { Authorization: "Basic ZW50c2VhcmNoLXVucHJpdmlsZWdlZDplbnRzZWFyY2gtdW5wcml2aWxlZ2VkLXVzZXI=" } # unprivileged - connector_secret.post: - body: - value: my-secret - catch: unauthorized - ---- -'Post connector secret when id is missing should fail': - - do: - connector_secret.post: - body: - value: null - catch: bad_request diff --git a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/510_connector_secret_get.yml b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/510_connector_secret_get.yml deleted file mode 100644 index 4b2d3777ffe9d..0000000000000 --- a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/510_connector_secret_get.yml +++ /dev/null @@ -1,60 +0,0 @@ -setup: - - skip: - version: " - 8.12.99" - reason: Introduced in 8.13.0 - ---- -'Get connector secret - admin': - - do: - connector_secret.post: - body: - value: my-secret - - set: { id: id } - - match: { id: $id } - - do: - connector_secret.get: - id: $id - - match: { value: my-secret } - ---- -'Get connector secret - user with privileges': - - skip: - features: headers - - - do: - headers: { Authorization: "Basic ZW50c2VhcmNoLXVzZXI6ZW50c2VhcmNoLXVzZXItcGFzc3dvcmQ=" } # user - connector_secret.post: - body: - value: my-secret - - set: { id: id } - - match: { id: $id } - - do: - headers: { Authorization: "Basic ZW50c2VhcmNoLXVzZXI6ZW50c2VhcmNoLXVzZXItcGFzc3dvcmQ=" } # user - connector_secret.get: - id: $id - - match: { value: my-secret } - ---- -'Get connector secret - user without privileges': - - skip: - features: headers - - - do: - headers: { Authorization: "Basic ZW50c2VhcmNoLXVzZXI6ZW50c2VhcmNoLXVzZXItcGFzc3dvcmQ=" } # user - connector_secret.post: - body: - value: my-secret - - set: { id: id } - - match: { id: $id } - - do: - headers: { Authorization: "Basic ZW50c2VhcmNoLXVucHJpdmlsZWdlZDplbnRzZWFyY2gtdW5wcml2aWxlZ2VkLXVzZXI=" } # unprivileged - connector_secret.get: - id: $id - catch: unauthorized - ---- -'Get connector secret - Missing secret id': - - do: - connector_secret.get: - id: non-existing-secret-id - catch: missing diff --git a/x-pack/plugin/ent-search/src/javaRestTest/java/org/elasticsearch/xpack/entsearch/ConnectorSecretsSystemIndexIT.java b/x-pack/plugin/ent-search/src/javaRestTest/java/org/elasticsearch/xpack/entsearch/ConnectorSecretsSystemIndexIT.java deleted file mode 100644 index 730ad1d83a318..0000000000000 --- a/x-pack/plugin/ent-search/src/javaRestTest/java/org/elasticsearch/xpack/entsearch/ConnectorSecretsSystemIndexIT.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.entsearch; - -import org.apache.http.util.EntityUtils; -import org.elasticsearch.client.Request; -import org.elasticsearch.client.Response; -import org.elasticsearch.client.ResponseException; -import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.util.concurrent.ThreadContext; -import org.elasticsearch.common.xcontent.XContentHelper; -import org.elasticsearch.test.SecuritySettingsSourceField; -import org.elasticsearch.test.rest.ESRestTestCase; -import org.elasticsearch.xcontent.XContentBuilder; -import org.elasticsearch.xcontent.XContentType; -import org.elasticsearch.xcontent.json.JsonXContent; - -import java.io.IOException; -import java.util.Map; - -import static org.hamcrest.Matchers.is; - -public class ConnectorSecretsSystemIndexIT extends ESRestTestCase { - - static final String BASIC_AUTH_VALUE = basicAuthHeaderValue( - "x_pack_rest_user", - SecuritySettingsSourceField.TEST_PASSWORD_SECURE_STRING - ); - - @Override - protected Settings restClientSettings() { - return Settings.builder().put(ThreadContext.PREFIX + ".Authorization", BASIC_AUTH_VALUE).build(); - } - - public void testConnectorSecretsCRUD() throws Exception { - // post secret - final String secretJson = getPostSecretJson(); - Request postRequest = new Request("POST", "/_connector/_secret/"); - postRequest.setJsonEntity(secretJson); - Response postResponse = client().performRequest(postRequest); - assertThat(postResponse.getStatusLine().getStatusCode(), is(200)); - Map responseMap = getResponseMap(postResponse); - assertThat(responseMap.size(), is(1)); - assertTrue(responseMap.containsKey("id")); - final String id = responseMap.get("id").toString(); - - // get secret - Request getRequest = new Request("GET", "/_connector/_secret/" + id); - Response getResponse = client().performRequest(getRequest); - assertThat(getResponse.getStatusLine().getStatusCode(), is(200)); - responseMap = getResponseMap(getResponse); - assertThat(responseMap.size(), is(2)); - assertTrue(responseMap.containsKey("id")); - assertTrue(responseMap.containsKey("value")); - assertThat(responseMap.get("value"), is("test secret")); - } - - public void testPostInvalidSecretBody() throws Exception { - Request postRequest = new Request("POST", "/_connector/_secret/"); - postRequest.setJsonEntity(""" - {"something":"else"}"""); - ResponseException re = expectThrows(ResponseException.class, () -> client().performRequest(postRequest)); - Response getResponse = re.getResponse(); - assertThat(getResponse.getStatusLine().getStatusCode(), is(400)); - } - - public void testGetNonExistingSecret() { - Request getRequest = new Request("GET", "/_connector/_secret/123"); - ResponseException re = expectThrows(ResponseException.class, () -> client().performRequest(getRequest)); - Response getResponse = re.getResponse(); - assertThat(getResponse.getStatusLine().getStatusCode(), is(404)); - } - - private String getPostSecretJson() throws IOException { - try (XContentBuilder builder = JsonXContent.contentBuilder()) { - builder.startObject(); - { - builder.field("value", "test secret"); - } - builder.endObject(); - return BytesReference.bytes(builder).utf8ToString(); - } - } - - private Map getResponseMap(Response response) throws IOException { - return XContentHelper.convertToMap(XContentType.JSON.xContent(), EntityUtils.toString(response.getEntity()), false); - } -} diff --git a/x-pack/plugin/ent-search/src/main/java/module-info.java b/x-pack/plugin/ent-search/src/main/java/module-info.java index 5850b279f8b09..d8cbceda4d8a3 100644 --- a/x-pack/plugin/ent-search/src/main/java/module-info.java +++ b/x-pack/plugin/ent-search/src/main/java/module-info.java @@ -39,6 +39,4 @@ exports org.elasticsearch.xpack.application.connector.syncjob.action; provides org.elasticsearch.features.FeatureSpecification with org.elasticsearch.xpack.application.EnterpriseSearchFeatures; - - exports org.elasticsearch.xpack.application.connector.secrets.action to org.elasticsearch.server; } diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java index d344bd60a22bd..4b31778d469ac 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java @@ -88,14 +88,6 @@ import org.elasticsearch.xpack.application.connector.action.UpdateConnectorPipelineAction; import org.elasticsearch.xpack.application.connector.action.UpdateConnectorSchedulingAction; import org.elasticsearch.xpack.application.connector.action.UpdateConnectorServiceTypeAction; -import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsFeature; -import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsIndexService; -import org.elasticsearch.xpack.application.connector.secrets.action.GetConnectorSecretAction; -import org.elasticsearch.xpack.application.connector.secrets.action.PostConnectorSecretAction; -import org.elasticsearch.xpack.application.connector.secrets.action.RestGetConnectorSecretAction; -import org.elasticsearch.xpack.application.connector.secrets.action.RestPostConnectorSecretAction; -import org.elasticsearch.xpack.application.connector.secrets.action.TransportGetConnectorSecretAction; -import org.elasticsearch.xpack.application.connector.secrets.action.TransportPostConnectorSecretAction; import org.elasticsearch.xpack.application.connector.syncjob.action.CancelConnectorSyncJobAction; import org.elasticsearch.xpack.application.connector.syncjob.action.CheckInConnectorSyncJobAction; import org.elasticsearch.xpack.application.connector.syncjob.action.DeleteConnectorSyncJobAction; @@ -268,15 +260,6 @@ protected XPackLicenseState getLicenseState() { ); } - if (ConnectorSecretsFeature.isEnabled()) { - actionHandlers.addAll( - List.of( - new ActionHandler<>(GetConnectorSecretAction.INSTANCE, TransportGetConnectorSecretAction.class), - new ActionHandler<>(PostConnectorSecretAction.INSTANCE, TransportPostConnectorSecretAction.class) - ) - ); - } - return Collections.unmodifiableList(actionHandlers); } @@ -354,10 +337,6 @@ public List getRestHandlers( ); } - if (ConnectorSecretsFeature.isEnabled()) { - restHandlers.addAll(List.of(new RestGetConnectorSecretAction(), new RestPostConnectorSecretAction())); - } - return Collections.unmodifiableList(restHandlers); } @@ -392,15 +371,7 @@ public Collection createComponents(PluginServices services) { @Override public Collection getSystemIndexDescriptors(Settings settings) { - Collection systemIndices = new ArrayList<>( - List.of(SearchApplicationIndexService.getSystemIndexDescriptor(), QueryRulesIndexService.getSystemIndexDescriptor()) - ); - - if (ConnectorSecretsFeature.isEnabled()) { - systemIndices.add(ConnectorSecretsIndexService.getSystemIndexDescriptor()); - } - - return systemIndices; + return Arrays.asList(SearchApplicationIndexService.getSystemIndexDescriptor(), QueryRulesIndexService.getSystemIndexDescriptor()); } @Override diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsFeature.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsFeature.java deleted file mode 100644 index 7fd109db40470..0000000000000 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsFeature.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets; - -import org.elasticsearch.common.util.FeatureFlag; - -/** - * Connector Secrets feature flag. When the feature is complete, this flag will be removed. - */ -public class ConnectorSecretsFeature { - - private static final FeatureFlag SECRETS_FEATURE_FLAG = new FeatureFlag("connector_secrets"); - - /** - * Enables the Connectors Secrets feature by default for the tech preview phase. - * As documented, the Connectors Secrets is currently a tech preview feature, - * and customers should be aware that no SLAs or support are guaranteed during - * its pre-General Availability (GA) stage. - * - * Instead of removing the feature flag from the code, we enable it by default. - * This approach allows for the complete deactivation of the feature during the QA phase, - * should any critical bugs be discovered, with a single, trackable code change. - */ - public static boolean isEnabled() { - return true; - } -} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsIndexService.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsIndexService.java deleted file mode 100644 index 633909ac2aa89..0000000000000 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsIndexService.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets; - -import org.elasticsearch.ResourceNotFoundException; -import org.elasticsearch.Version; -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest; -import org.elasticsearch.client.internal.Client; -import org.elasticsearch.client.internal.OriginSettingClient; -import org.elasticsearch.indices.SystemIndexDescriptor; -import org.elasticsearch.xcontent.XContentType; -import org.elasticsearch.xpack.application.connector.secrets.action.GetConnectorSecretResponse; -import org.elasticsearch.xpack.application.connector.secrets.action.PostConnectorSecretRequest; -import org.elasticsearch.xpack.application.connector.secrets.action.PostConnectorSecretResponse; -import org.elasticsearch.xpack.core.template.TemplateUtils; - -import java.util.Map; - -import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder; -import static org.elasticsearch.xpack.core.ClientHelper.CONNECTORS_ORIGIN; - -/** - * A service that manages persistent Connector Secrets. - */ -public class ConnectorSecretsIndexService { - - private final Client clientWithOrigin; - - public static final String CONNECTOR_SECRETS_INDEX_NAME = ".connector-secrets"; - private static final int CURRENT_INDEX_VERSION = 1; - private static final String MAPPING_VERSION_VARIABLE = "connector-secrets.version"; - private static final String MAPPING_MANAGED_VERSION_VARIABLE = "connector-secrets.managed.index.version"; - - public ConnectorSecretsIndexService(Client client) { - this.clientWithOrigin = new OriginSettingClient(client, CONNECTORS_ORIGIN); - } - - /** - * Returns the {@link SystemIndexDescriptor} for the Connector Secrets system index. - * - * @return The {@link SystemIndexDescriptor} for the Connector Secrets system index. - */ - public static SystemIndexDescriptor getSystemIndexDescriptor() { - PutIndexTemplateRequest request = new PutIndexTemplateRequest(); - - String templateSource = TemplateUtils.loadTemplate( - "/connector-secrets.json", - Version.CURRENT.toString(), - MAPPING_VERSION_VARIABLE, - Map.of(MAPPING_MANAGED_VERSION_VARIABLE, Integer.toString(CURRENT_INDEX_VERSION)) - ); - request.source(templateSource, XContentType.JSON); - - return SystemIndexDescriptor.builder() - .setIndexPattern(CONNECTOR_SECRETS_INDEX_NAME + "*") - .setPrimaryIndex(CONNECTOR_SECRETS_INDEX_NAME + "-" + CURRENT_INDEX_VERSION) - .setDescription("Secret values managed by Connectors") - .setMappings(request.mappings()) - .setSettings(request.settings()) - .setAliasName(CONNECTOR_SECRETS_INDEX_NAME) - .setVersionMetaKey("version") - .setOrigin(CONNECTORS_ORIGIN) - .setType(SystemIndexDescriptor.Type.INTERNAL_MANAGED) - .build(); - } - - public void getSecret(String id, ActionListener listener) { - clientWithOrigin.prepareGet(CONNECTOR_SECRETS_INDEX_NAME, id).execute(listener.delegateFailureAndWrap((delegate, getResponse) -> { - if (getResponse.isSourceEmpty()) { - delegate.onFailure(new ResourceNotFoundException("No secret with id [" + id + "]")); - return; - } - delegate.onResponse(new GetConnectorSecretResponse(getResponse.getId(), getResponse.getSource().get("value").toString())); - })); - } - - public void createSecret(PostConnectorSecretRequest request, ActionListener listener) { - try { - clientWithOrigin.prepareIndex(CONNECTOR_SECRETS_INDEX_NAME) - .setSource(request.toXContent(jsonBuilder())) - .execute( - listener.delegateFailureAndWrap( - (l, indexResponse) -> l.onResponse(new PostConnectorSecretResponse(indexResponse.getId())) - ) - ); - } catch (Exception e) { - listener.onFailure(e); - } - } -} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretAction.java deleted file mode 100644 index cc0601336242c..0000000000000 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretAction.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.action.ActionType; - -public class GetConnectorSecretAction extends ActionType { - - public static final String NAME = "cluster:admin/xpack/connector/secret/get"; - - public static final GetConnectorSecretAction INSTANCE = new GetConnectorSecretAction(); - - private GetConnectorSecretAction() { - super(NAME, GetConnectorSecretResponse::new); - } -} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretRequest.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretRequest.java deleted file mode 100644 index cf1cc0f563eba..0000000000000 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretRequest.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.action.ActionRequest; -import org.elasticsearch.action.ActionRequestValidationException; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.Objects; - -import static org.elasticsearch.action.ValidateActions.addValidationError; - -public class GetConnectorSecretRequest extends ActionRequest { - - private final String id; - - public GetConnectorSecretRequest(String id) { - this.id = Objects.requireNonNull(id); - } - - public GetConnectorSecretRequest(StreamInput in) throws IOException { - super(in); - id = in.readString(); - } - - public String id() { - return id; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(id); - } - - @Override - public ActionRequestValidationException validate() { - ActionRequestValidationException validationException = null; - - if (Strings.isNullOrEmpty(id)) { - validationException = addValidationError("id missing", validationException); - } - - return validationException; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GetConnectorSecretRequest that = (GetConnectorSecretRequest) o; - return Objects.equals(id, that.id); - } - - @Override - public int hashCode() { - return Objects.hash(id); - } -} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretResponse.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretResponse.java deleted file mode 100644 index 3bbcb8212d51c..0000000000000 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretResponse.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.action.ActionResponse; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.xcontent.ToXContent; -import org.elasticsearch.xcontent.ToXContentObject; -import org.elasticsearch.xcontent.XContentBuilder; - -import java.io.IOException; -import java.util.Objects; - -public class GetConnectorSecretResponse extends ActionResponse implements ToXContentObject { - - private final String id; - private final String value; - - public GetConnectorSecretResponse(StreamInput in) throws IOException { - super(in); - id = in.readString(); - value = in.readString(); - } - - public GetConnectorSecretResponse(String id, String value) { - this.id = id; - this.value = value; - } - - public String id() { - return id; - } - - public String value() { - return value; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeString(id); - out.writeString(value); - } - - @Override - public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException { - builder.startObject(); - builder.field("id", id); - builder.field("value", value); - return builder.endObject(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GetConnectorSecretResponse that = (GetConnectorSecretResponse) o; - return Objects.equals(id, that.id) && Objects.equals(value, that.value); - } - - @Override - public int hashCode() { - return Objects.hash(id, value); - } -} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretAction.java deleted file mode 100644 index 44bc3a03be5c8..0000000000000 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretAction.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.action.ActionType; - -public class PostConnectorSecretAction extends ActionType { - - public static final String NAME = "cluster:admin/xpack/connector/secret/post"; - - public static final PostConnectorSecretAction INSTANCE = new PostConnectorSecretAction(); - - private PostConnectorSecretAction() { - super(NAME, PostConnectorSecretResponse::new); - } -} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretRequest.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretRequest.java deleted file mode 100644 index 2e565dece7eca..0000000000000 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretRequest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.action.ActionRequest; -import org.elasticsearch.action.ActionRequestValidationException; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.xcontent.ConstructingObjectParser; -import org.elasticsearch.xcontent.ObjectParser; -import org.elasticsearch.xcontent.ParseField; -import org.elasticsearch.xcontent.XContentBuilder; -import org.elasticsearch.xcontent.XContentParser; - -import java.io.IOException; -import java.util.Objects; - -public class PostConnectorSecretRequest extends ActionRequest { - - public static final ParseField VALUE_FIELD = new ParseField("value"); - - public static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( - "post_secret_request", - args -> { - return new PostConnectorSecretRequest((String) args[0]); - } - ); - - static { - PARSER.declareField( - ConstructingObjectParser.optionalConstructorArg(), - (p, c) -> p.text(), - VALUE_FIELD, - ObjectParser.ValueType.STRING - ); - } - - public static PostConnectorSecretRequest fromXContent(XContentParser parser) throws IOException { - return PARSER.parse(parser, null); - } - - private final String value; - - public PostConnectorSecretRequest(String value) { - this.value = value; - } - - public PostConnectorSecretRequest(StreamInput in) throws IOException { - super(in); - this.value = in.readString(); - } - - public String value() { - return value; - } - - public XContentBuilder toXContent(XContentBuilder builder) throws IOException { - builder.startObject(); - builder.field(VALUE_FIELD.getPreferredName(), this.value); - builder.endObject(); - return builder; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(value); - } - - @Override - public ActionRequestValidationException validate() { - if (Strings.isNullOrEmpty(this.value)) { - ActionRequestValidationException exception = new ActionRequestValidationException(); - exception.addValidationError("value is missing"); - return exception; - } - - return null; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - PostConnectorSecretRequest that = (PostConnectorSecretRequest) o; - return Objects.equals(value, that.value); - } - - @Override - public int hashCode() { - return Objects.hash(value); - } -} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretResponse.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretResponse.java deleted file mode 100644 index 068b510c5fad5..0000000000000 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretResponse.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.action.ActionResponse; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.xcontent.ToXContent; -import org.elasticsearch.xcontent.ToXContentObject; -import org.elasticsearch.xcontent.XContentBuilder; - -import java.io.IOException; -import java.util.Objects; - -public class PostConnectorSecretResponse extends ActionResponse implements ToXContentObject { - - private final String id; - - public PostConnectorSecretResponse(String id) { - this.id = id; - } - - public PostConnectorSecretResponse(StreamInput in) throws IOException { - super(in); - this.id = in.readString(); - } - - public String id() { - return id; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeString(id); - } - - @Override - public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException { - builder.startObject(); - builder.field("id", id); - return builder.endObject(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - PostConnectorSecretResponse that = (PostConnectorSecretResponse) o; - return Objects.equals(id, that.id); - } - - @Override - public int hashCode() { - return Objects.hash(id); - } -} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/RestGetConnectorSecretAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/RestGetConnectorSecretAction.java deleted file mode 100644 index 6ab5c1055c3a4..0000000000000 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/RestGetConnectorSecretAction.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.client.internal.node.NodeClient; -import org.elasticsearch.rest.BaseRestHandler; -import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.rest.Scope; -import org.elasticsearch.rest.ServerlessScope; -import org.elasticsearch.rest.action.RestToXContentListener; - -import java.io.IOException; -import java.util.List; - -@ServerlessScope(Scope.INTERNAL) -public class RestGetConnectorSecretAction extends BaseRestHandler { - - @Override - public String getName() { - return "connector_get_secret"; - } - - @Override - public List routes() { - return List.of(new Route(RestRequest.Method.GET, "/_connector/_secret/{id}")); - } - - @Override - protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { - final String id = request.param("id"); - return restChannel -> client.execute( - GetConnectorSecretAction.INSTANCE, - new GetConnectorSecretRequest(id), - new RestToXContentListener<>(restChannel) - ); - } -} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/RestPostConnectorSecretAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/RestPostConnectorSecretAction.java deleted file mode 100644 index eeacde1bdb3c5..0000000000000 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/RestPostConnectorSecretAction.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.client.internal.node.NodeClient; -import org.elasticsearch.rest.BaseRestHandler; -import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.rest.Scope; -import org.elasticsearch.rest.ServerlessScope; -import org.elasticsearch.rest.action.RestToXContentListener; -import org.elasticsearch.xcontent.XContentParser; - -import java.io.IOException; -import java.util.List; - -@ServerlessScope(Scope.INTERNAL) -public class RestPostConnectorSecretAction extends BaseRestHandler { - - @Override - public String getName() { - return "connector_post_secret"; - } - - @Override - public List routes() { - return List.of(new Route(RestRequest.Method.POST, "/_connector/_secret")); - } - - @Override - protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { - try (XContentParser parser = request.contentParser()) { - PostConnectorSecretRequest postSecretRequest = PostConnectorSecretRequest.fromXContent(parser); - return restChannel -> client.execute( - PostConnectorSecretAction.INSTANCE, - postSecretRequest, - new RestToXContentListener<>(restChannel) - ); - } - } -} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportGetConnectorSecretAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportGetConnectorSecretAction.java deleted file mode 100644 index aaa03fa13298f..0000000000000 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportGetConnectorSecretAction.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.support.ActionFilters; -import org.elasticsearch.action.support.HandledTransportAction; -import org.elasticsearch.client.internal.Client; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.util.concurrent.EsExecutors; -import org.elasticsearch.tasks.Task; -import org.elasticsearch.transport.TransportService; -import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsIndexService; - -public class TransportGetConnectorSecretAction extends HandledTransportAction { - - private final ConnectorSecretsIndexService connectorSecretsIndexService; - - @Inject - public TransportGetConnectorSecretAction(TransportService transportService, ActionFilters actionFilters, Client client) { - super( - GetConnectorSecretAction.NAME, - transportService, - actionFilters, - GetConnectorSecretRequest::new, - EsExecutors.DIRECT_EXECUTOR_SERVICE - ); - this.connectorSecretsIndexService = new ConnectorSecretsIndexService(client); - } - - protected void doExecute(Task task, GetConnectorSecretRequest request, ActionListener listener) { - connectorSecretsIndexService.getSecret(request.id(), listener); - } -} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportPostConnectorSecretAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportPostConnectorSecretAction.java deleted file mode 100644 index 7cc3195ccbbf2..0000000000000 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportPostConnectorSecretAction.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.support.ActionFilters; -import org.elasticsearch.action.support.HandledTransportAction; -import org.elasticsearch.client.internal.Client; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.util.concurrent.EsExecutors; -import org.elasticsearch.tasks.Task; -import org.elasticsearch.transport.TransportService; -import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsIndexService; - -public class TransportPostConnectorSecretAction extends HandledTransportAction { - - private final ConnectorSecretsIndexService connectorSecretsIndexService; - - @Inject - public TransportPostConnectorSecretAction(TransportService transportService, ActionFilters actionFilters, Client client) { - super( - PostConnectorSecretAction.NAME, - transportService, - actionFilters, - PostConnectorSecretRequest::new, - EsExecutors.DIRECT_EXECUTOR_SERVICE - ); - this.connectorSecretsIndexService = new ConnectorSecretsIndexService(client); - } - - protected void doExecute(Task task, PostConnectorSecretRequest request, ActionListener listener) { - connectorSecretsIndexService.createSecret(request, listener); - } -} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsIndexServiceTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsIndexServiceTests.java deleted file mode 100644 index f9a548a47feb3..0000000000000 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsIndexServiceTests.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets; - -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.test.ESSingleNodeTestCase; -import org.elasticsearch.xpack.application.connector.secrets.action.GetConnectorSecretResponse; -import org.elasticsearch.xpack.application.connector.secrets.action.PostConnectorSecretRequest; -import org.elasticsearch.xpack.application.connector.secrets.action.PostConnectorSecretResponse; -import org.junit.Before; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; - -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.notNullValue; - -public class ConnectorSecretsIndexServiceTests extends ESSingleNodeTestCase { - - private static final int TIMEOUT_SECONDS = 10; - - private ConnectorSecretsIndexService connectorSecretsIndexService; - - @Before - public void setup() throws Exception { - this.connectorSecretsIndexService = new ConnectorSecretsIndexService(client()); - } - - public void testCreateAndGetConnectorSecret() throws Exception { - PostConnectorSecretRequest createSecretRequest = ConnectorSecretsTestUtils.getRandomPostConnectorSecretRequest(); - PostConnectorSecretResponse createdSecret = awaitPostConnectorSecret(createSecretRequest); - - GetConnectorSecretResponse gotSecret = awaitGetConnectorSecret(createdSecret.id()); - - assertThat(gotSecret.id(), equalTo(createdSecret.id())); - assertThat(gotSecret.value(), notNullValue()); - } - - private PostConnectorSecretResponse awaitPostConnectorSecret(PostConnectorSecretRequest secretRequest) throws Exception { - CountDownLatch latch = new CountDownLatch(1); - - final AtomicReference responseRef = new AtomicReference<>(null); - final AtomicReference exception = new AtomicReference<>(null); - - connectorSecretsIndexService.createSecret(secretRequest, new ActionListener<>() { - @Override - public void onResponse(PostConnectorSecretResponse postConnectorSecretResponse) { - responseRef.set(postConnectorSecretResponse); - latch.countDown(); - } - - @Override - public void onFailure(Exception e) { - exception.set(e); - latch.countDown(); - } - }); - - if (exception.get() != null) { - throw exception.get(); - } - - boolean requestTimedOut = latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS); - PostConnectorSecretResponse response = responseRef.get(); - - assertTrue("Timeout waiting for post request", requestTimedOut); - assertNotNull("Received null response from post request", response); - - return response; - } - - private GetConnectorSecretResponse awaitGetConnectorSecret(String connectorSecretId) throws Exception { - CountDownLatch latch = new CountDownLatch(1); - final AtomicReference resp = new AtomicReference<>(null); - final AtomicReference exc = new AtomicReference<>(null); - - connectorSecretsIndexService.getSecret(connectorSecretId, new ActionListener() { - @Override - public void onResponse(GetConnectorSecretResponse response) { - resp.set(response); - latch.countDown(); - } - - @Override - public void onFailure(Exception e) { - exc.set(e); - latch.countDown(); - } - }); - - assertTrue("Timeout waiting for get request", latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS)); - if (exc.get() != null) { - throw exc.get(); - } - assertNotNull("Received null response from get request", resp.get()); - return resp.get(); - } -} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsTestUtils.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsTestUtils.java deleted file mode 100644 index c7cec3a263af0..0000000000000 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/ConnectorSecretsTestUtils.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets; - -import org.elasticsearch.xpack.application.connector.secrets.action.GetConnectorSecretRequest; -import org.elasticsearch.xpack.application.connector.secrets.action.GetConnectorSecretResponse; -import org.elasticsearch.xpack.application.connector.secrets.action.PostConnectorSecretRequest; -import org.elasticsearch.xpack.application.connector.secrets.action.PostConnectorSecretResponse; - -import static org.elasticsearch.test.ESTestCase.randomAlphaOfLength; -import static org.elasticsearch.test.ESTestCase.randomAlphaOfLengthBetween; - -public class ConnectorSecretsTestUtils { - - public static GetConnectorSecretRequest getRandomGetConnectorSecretRequest() { - return new GetConnectorSecretRequest(randomAlphaOfLength(10)); - } - - public static GetConnectorSecretResponse getRandomGetConnectorSecretResponse() { - final String id = randomAlphaOfLength(10); - final String value = randomAlphaOfLength(10); - return new GetConnectorSecretResponse(id, value); - } - - public static PostConnectorSecretRequest getRandomPostConnectorSecretRequest() { - return new PostConnectorSecretRequest(randomAlphaOfLengthBetween(0, 20)); - } - - public static PostConnectorSecretResponse getRandomPostConnectorSecretResponse() { - return new PostConnectorSecretResponse(randomAlphaOfLength(10)); - } -} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretActionTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretActionTests.java deleted file mode 100644 index 9fc01e56ee5a0..0000000000000 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretActionTests.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.action.ActionRequestValidationException; -import org.elasticsearch.test.ESTestCase; -import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsTestUtils; - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; - -public class GetConnectorSecretActionTests extends ESTestCase { - - public void testValidate_WhenConnectorSecretIdIsPresent_ExpectNoValidationError() { - GetConnectorSecretRequest request = ConnectorSecretsTestUtils.getRandomGetConnectorSecretRequest(); - ActionRequestValidationException exception = request.validate(); - - assertThat(exception, nullValue()); - } - - public void testValidate_WhenConnectorSecretIdIsEmpty_ExpectValidationError() { - GetConnectorSecretRequest requestWithMissingConnectorId = new GetConnectorSecretRequest(""); - ActionRequestValidationException exception = requestWithMissingConnectorId.validate(); - - assertThat(exception, notNullValue()); - assertThat(exception.getMessage(), containsString("id missing")); - } -} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretRequestBWCSerializingTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretRequestBWCSerializingTests.java deleted file mode 100644 index abac910aa1dac..0000000000000 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretRequestBWCSerializingTests.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.TransportVersion; -import org.elasticsearch.common.io.stream.Writeable; -import org.elasticsearch.xpack.core.ml.AbstractBWCWireSerializationTestCase; - -import java.io.IOException; - -public class GetConnectorSecretRequestBWCSerializingTests extends AbstractBWCWireSerializationTestCase { - - @Override - protected Writeable.Reader instanceReader() { - return GetConnectorSecretRequest::new; - } - - @Override - protected GetConnectorSecretRequest createTestInstance() { - return new GetConnectorSecretRequest(randomAlphaOfLengthBetween(1, 10)); - } - - @Override - protected GetConnectorSecretRequest mutateInstance(GetConnectorSecretRequest instance) throws IOException { - return randomValueOtherThan(instance, this::createTestInstance); - } - - @Override - protected GetConnectorSecretRequest mutateInstanceForVersion(GetConnectorSecretRequest instance, TransportVersion version) { - return new GetConnectorSecretRequest(instance.id()); - } -} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretResponseBWCSerializingTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretResponseBWCSerializingTests.java deleted file mode 100644 index 4448024814df3..0000000000000 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/GetConnectorSecretResponseBWCSerializingTests.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.TransportVersion; -import org.elasticsearch.common.io.stream.NamedWriteableRegistry; -import org.elasticsearch.common.io.stream.Writeable; -import org.elasticsearch.xpack.application.connector.Connector; -import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsTestUtils; -import org.elasticsearch.xpack.core.ml.AbstractBWCWireSerializationTestCase; - -import java.io.IOException; -import java.util.List; - -public class GetConnectorSecretResponseBWCSerializingTests extends AbstractBWCWireSerializationTestCase { - - @Override - public NamedWriteableRegistry getNamedWriteableRegistry() { - return new NamedWriteableRegistry(List.of(new NamedWriteableRegistry.Entry(Connector.class, Connector.NAME, Connector::new))); - } - - @Override - protected Writeable.Reader instanceReader() { - return GetConnectorSecretResponse::new; - } - - @Override - protected GetConnectorSecretResponse createTestInstance() { - return ConnectorSecretsTestUtils.getRandomGetConnectorSecretResponse(); - } - - @Override - protected GetConnectorSecretResponse mutateInstance(GetConnectorSecretResponse instance) throws IOException { - return randomValueOtherThan(instance, this::createTestInstance); - } - - @Override - protected GetConnectorSecretResponse mutateInstanceForVersion(GetConnectorSecretResponse instance, TransportVersion version) { - return instance; - } -} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretActionTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretActionTests.java deleted file mode 100644 index f1e1a670b2748..0000000000000 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretActionTests.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.action.ActionRequestValidationException; -import org.elasticsearch.test.ESTestCase; -import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsTestUtils; - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; - -public class PostConnectorSecretActionTests extends ESTestCase { - - public void testValidate_WhenConnectorSecretIdIsPresent_ExpectNoValidationError() { - PostConnectorSecretRequest request = ConnectorSecretsTestUtils.getRandomPostConnectorSecretRequest(); - ActionRequestValidationException exception = request.validate(); - - assertThat(exception, nullValue()); - } - - public void testValidate_WhenConnectorSecretIdIsEmpty_ExpectValidationError() { - PostConnectorSecretRequest requestWithMissingValue = new PostConnectorSecretRequest(""); - ActionRequestValidationException exception = requestWithMissingValue.validate(); - - assertThat(exception, notNullValue()); - assertThat(exception.getMessage(), containsString("value is missing")); - } -} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretRequestBWCSerializingTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretRequestBWCSerializingTests.java deleted file mode 100644 index b7f8c501a91e8..0000000000000 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretRequestBWCSerializingTests.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.TransportVersion; -import org.elasticsearch.common.io.stream.Writeable; -import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsTestUtils; -import org.elasticsearch.xpack.core.ml.AbstractBWCWireSerializationTestCase; - -import java.io.IOException; - -public class PostConnectorSecretRequestBWCSerializingTests extends AbstractBWCWireSerializationTestCase { - - @Override - protected Writeable.Reader instanceReader() { - return PostConnectorSecretRequest::new; - } - - @Override - protected PostConnectorSecretRequest createTestInstance() { - return ConnectorSecretsTestUtils.getRandomPostConnectorSecretRequest(); - } - - @Override - protected PostConnectorSecretRequest mutateInstance(PostConnectorSecretRequest instance) throws IOException { - return randomValueOtherThan(instance, this::createTestInstance); - } - - @Override - protected PostConnectorSecretRequest mutateInstanceForVersion(PostConnectorSecretRequest instance, TransportVersion version) { - return instance; - } -} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretResponseBWCSerializingTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretResponseBWCSerializingTests.java deleted file mode 100644 index e114181270e95..0000000000000 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/PostConnectorSecretResponseBWCSerializingTests.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.TransportVersion; -import org.elasticsearch.common.io.stream.Writeable; -import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsTestUtils; -import org.elasticsearch.xpack.core.ml.AbstractBWCWireSerializationTestCase; - -import java.io.IOException; - -public class PostConnectorSecretResponseBWCSerializingTests extends AbstractBWCWireSerializationTestCase { - - @Override - protected Writeable.Reader instanceReader() { - return PostConnectorSecretResponse::new; - } - - @Override - protected PostConnectorSecretResponse createTestInstance() { - return ConnectorSecretsTestUtils.getRandomPostConnectorSecretResponse(); - } - - @Override - protected PostConnectorSecretResponse mutateInstance(PostConnectorSecretResponse instance) throws IOException { - return randomValueOtherThan(instance, this::createTestInstance); - } - - @Override - protected PostConnectorSecretResponse mutateInstanceForVersion(PostConnectorSecretResponse instance, TransportVersion version) { - return instance; - } - -} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportGetConnectorSecretActionTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportGetConnectorSecretActionTests.java deleted file mode 100644 index 6b046c7e44506..0000000000000 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportGetConnectorSecretActionTests.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.support.ActionFilters; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.tasks.Task; -import org.elasticsearch.test.ESSingleNodeTestCase; -import org.elasticsearch.threadpool.TestThreadPool; -import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.transport.Transport; -import org.elasticsearch.transport.TransportService; -import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsTestUtils; -import org.junit.Before; - -import java.util.Collections; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import static org.mockito.Mockito.mock; - -public class TransportGetConnectorSecretActionTests extends ESSingleNodeTestCase { - - private static final Long TIMEOUT_SECONDS = 10L; - - private final ThreadPool threadPool = new TestThreadPool(getClass().getName()); - private TransportGetConnectorSecretAction action; - - @Before - public void setup() { - TransportService transportService = new TransportService( - Settings.EMPTY, - mock(Transport.class), - threadPool, - TransportService.NOOP_TRANSPORT_INTERCEPTOR, - x -> null, - null, - Collections.emptySet() - ); - - action = new TransportGetConnectorSecretAction(transportService, mock(ActionFilters.class), client()); - } - - @Override - public void tearDown() throws Exception { - super.tearDown(); - ThreadPool.terminate(threadPool, TIMEOUT_SECONDS, TimeUnit.SECONDS); - } - - public void testGetConnectorSecret_ExpectNoWarnings() throws InterruptedException { - GetConnectorSecretRequest request = ConnectorSecretsTestUtils.getRandomGetConnectorSecretRequest(); - - executeRequest(request); - - ensureNoWarnings(); - } - - private void executeRequest(GetConnectorSecretRequest request) throws InterruptedException { - final CountDownLatch latch = new CountDownLatch(1); - action.doExecute(mock(Task.class), request, ActionListener.wrap(response -> latch.countDown(), exception -> latch.countDown())); - - boolean requestTimedOut = latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS); - - assertTrue("Timeout waiting for get request", requestTimedOut); - } -} diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportPostConnectorSecretActionTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportPostConnectorSecretActionTests.java deleted file mode 100644 index 056d2786de1d7..0000000000000 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/secrets/action/TransportPostConnectorSecretActionTests.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.application.connector.secrets.action; - -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.support.ActionFilters; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.tasks.Task; -import org.elasticsearch.test.ESSingleNodeTestCase; -import org.elasticsearch.threadpool.TestThreadPool; -import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.transport.Transport; -import org.elasticsearch.transport.TransportService; -import org.elasticsearch.xpack.application.connector.secrets.ConnectorSecretsTestUtils; -import org.junit.Before; - -import java.util.Collections; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import static org.mockito.Mockito.mock; - -public class TransportPostConnectorSecretActionTests extends ESSingleNodeTestCase { - - private static final Long TIMEOUT_SECONDS = 10L; - - private final ThreadPool threadPool = new TestThreadPool(getClass().getName()); - private TransportPostConnectorSecretAction action; - - @Before - public void setup() { - TransportService transportService = new TransportService( - Settings.EMPTY, - mock(Transport.class), - threadPool, - TransportService.NOOP_TRANSPORT_INTERCEPTOR, - x -> null, - null, - Collections.emptySet() - ); - - action = new TransportPostConnectorSecretAction(transportService, mock(ActionFilters.class), client()); - } - - @Override - public void tearDown() throws Exception { - super.tearDown(); - ThreadPool.terminate(threadPool, TIMEOUT_SECONDS, TimeUnit.SECONDS); - } - - public void testPostConnectorSecret_ExpectNoWarnings() throws InterruptedException { - PostConnectorSecretRequest request = ConnectorSecretsTestUtils.getRandomPostConnectorSecretRequest(); - - executeRequest(request); - - ensureNoWarnings(); - } - - private void executeRequest(PostConnectorSecretRequest request) throws InterruptedException { - final CountDownLatch latch = new CountDownLatch(1); - action.doExecute(mock(Task.class), request, ActionListener.wrap(response -> latch.countDown(), exception -> latch.countDown())); - - boolean requestTimedOut = latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS); - - assertTrue("Timeout waiting for post request", requestTimedOut); - } -} diff --git a/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java b/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java index ce9db5015a0da..d4d0bded045f6 100644 --- a/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java +++ b/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java @@ -138,8 +138,6 @@ public class Constants { "cluster:admin/xpack/connector/update_pipeline", "cluster:admin/xpack/connector/update_scheduling", "cluster:admin/xpack/connector/update_service_type", - "cluster:admin/xpack/connector/secret/get", - "cluster:admin/xpack/connector/secret/post", "cluster:admin/xpack/connector/sync_job/cancel", "cluster:admin/xpack/connector/sync_job/check_in", "cluster:admin/xpack/connector/sync_job/delete", diff --git a/x-pack/plugin/security/qa/service-account/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/service/ServiceAccountIT.java b/x-pack/plugin/security/qa/service-account/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/service/ServiceAccountIT.java index e790866cf3d77..f66631a57b4bb 100644 --- a/x-pack/plugin/security/qa/service-account/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/service/ServiceAccountIT.java +++ b/x-pack/plugin/security/qa/service-account/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/service/ServiceAccountIT.java @@ -280,9 +280,7 @@ public class ServiceAccountIT extends ESRestTestCase { { "cluster": [ "manage", - "manage_security", - "read_connector_secrets", - "write_connector_secrets" + "manage_security" ], "indices": [ { diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccounts.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccounts.java index abd586920f2d8..777fe5f71b0a0 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccounts.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccounts.java @@ -26,7 +26,7 @@ final class ElasticServiceAccounts { "enterprise-search-server", new RoleDescriptor( NAMESPACE + "/enterprise-search-server", - new String[] { "manage", "manage_security", "read_connector_secrets", "write_connector_secrets" }, + new String[] { "manage", "manage_security" }, new RoleDescriptor.IndicesPrivileges[] { RoleDescriptor.IndicesPrivileges.builder() .indices( diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccountsTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccountsTests.java index 46fde61690017..ecef71f1c4a68 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccountsTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccountsTests.java @@ -344,10 +344,6 @@ public void testElasticEnterpriseSearchServerAccount() { assertThat(role.cluster().check(GetLifecycleAction.NAME, request, authentication), is(true)); assertThat(role.cluster().check(ILMActions.PUT.name(), request, authentication), is(true)); - // Connector secrets. Enterprise Search has read and write access. - assertThat(role.cluster().check("cluster:admin/xpack/connector/secret/get", request, authentication), is(true)); - assertThat(role.cluster().check("cluster:admin/xpack/connector/secret/post", request, authentication), is(true)); - List.of( "search-" + randomAlphaOfLengthBetween(1, 20), ".search-acl-filter-" + randomAlphaOfLengthBetween(1, 20), diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/privileges/11_builtin.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/privileges/11_builtin.yml index 319b84e855aaf..e2e220aa55456 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/privileges/11_builtin.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/privileges/11_builtin.yml @@ -15,5 +15,5 @@ setup: # This is fragile - it needs to be updated every time we add a new cluster/index privilege # I would much prefer we could just check that specific entries are in the array, but we don't have # an assertion for that - - length: { "cluster" : 55 } + - length: { "cluster" : 53 } - length: { "index" : 22 } From 35aff349128514341bfefbcde41241dab0d27c39 Mon Sep 17 00:00:00 2001 From: David Roberts Date: Thu, 25 Jan 2024 14:31:24 +0000 Subject: [PATCH 29/37] [ML] Add an important note about a gotcha with the delayed data check (#104725) Recently a user saw spurious delayed data warnings. These turned out to be due to accidentally setting `summary_count_field` to a field that was always zero. This meant that every document was considered delayed. --- .../ml-delayed-data-detection.asciidoc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/reference/ml/anomaly-detection/ml-delayed-data-detection.asciidoc b/docs/reference/ml/anomaly-detection/ml-delayed-data-detection.asciidoc index 5d72b4682d4ea..f55ab207a2689 100644 --- a/docs/reference/ml/anomaly-detection/ml-delayed-data-detection.asciidoc +++ b/docs/reference/ml/anomaly-detection/ml-delayed-data-detection.asciidoc @@ -52,6 +52,22 @@ for the periods where these delays occur: [role="screenshot"] image::images/ml-annotations.png["Delayed data annotations in the Single Metric Viewer"] +[IMPORTANT] +==== +As the `doc_count` from an aggregation is compared with the +bucket results of the job, the delayed data check will not work correctly in the +following cases: + +* if the datafeed uses aggregations and the job's `analysis_config` does not have its +`summary_count_field_name` set to `doc_count`, +* if the datafeed is _not_ using aggregations and `summary_count_field_name` is set to +any value. + +If the datafeed is using aggregations then it's highly likely that the job's +`summary_count_field_name` should be set to `doc_count`. If +`summary_count_field_name` is set to any value other than `doc_count`, the +delayed data check for the datafeed must be disabled. +==== There is another tool for visualizing the delayed data on the *Annotations* tab in the {anomaly-detect} job management page: From 05c7377f6b01c8ce870a8aca729d9c3cb384ee0a Mon Sep 17 00:00:00 2001 From: Jonathan Buttner <56361221+jonathan-buttner@users.noreply.github.com> Date: Thu, 25 Jan 2024 09:38:55 -0500 Subject: [PATCH 30/37] Closing services (#104726) Co-authored-by: Elastic Machine --- .../inference/InferenceServiceRegistry.java | 20 ++++++------------- .../xpack/inference/InferencePlugin.java | 8 ++------ 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/inference/InferenceServiceRegistry.java b/server/src/main/java/org/elasticsearch/inference/InferenceServiceRegistry.java index a0ed7bbd82b24..d5973807d9d78 100644 --- a/server/src/main/java/org/elasticsearch/inference/InferenceServiceRegistry.java +++ b/server/src/main/java/org/elasticsearch/inference/InferenceServiceRegistry.java @@ -9,9 +9,9 @@ package org.elasticsearch.inference; import org.elasticsearch.client.internal.Client; -import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -20,7 +20,7 @@ import java.util.function.Function; import java.util.stream.Collectors; -public class InferenceServiceRegistry extends AbstractLifecycleComponent { +public class InferenceServiceRegistry implements Closeable { private final Map services; private final List namedWriteables = new ArrayList<>(); @@ -53,17 +53,9 @@ public List getNamedWriteables() { } @Override - protected void doStart() { - - } - - @Override - protected void doStop() { - - } - - @Override - protected void doClose() throws IOException { - + public void close() throws IOException { + for (var service : services.values()) { + service.close(); + } } } diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java index e25b223742edd..ea62ca8620bf5 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java @@ -72,8 +72,6 @@ public class InferencePlugin extends Plugin implements ActionPlugin, ExtensibleP public static final String NAME = "inference"; public static final String UTILITY_THREAD_POOL_NAME = "inference_utility"; private final Settings settings; - // We'll keep a reference to the http manager just in case the inference services don't get closed individually - private final SetOnce httpManager = new SetOnce<>(); private final SetOnce httpFactory = new SetOnce<>(); private final SetOnce serviceComponents = new SetOnce<>(); @@ -120,11 +118,9 @@ public Collection createComponents(PluginServices services) { var truncator = new Truncator(settings, services.clusterService()); serviceComponents.set(new ServiceComponents(services.threadPool(), throttlerManager, settings, truncator)); - httpManager.set(HttpClientManager.create(settings, services.threadPool(), services.clusterService(), throttlerManager)); - var httpRequestSenderFactory = new HttpRequestSenderFactory( services.threadPool(), - httpManager.get(), + HttpClientManager.create(settings, services.threadPool(), services.clusterService(), throttlerManager), services.clusterService(), settings ); @@ -236,6 +232,6 @@ public void close() { var serviceComponentsRef = serviceComponents.get(); var throttlerToClose = serviceComponentsRef != null ? serviceComponentsRef.throttlerManager() : null; - IOUtils.closeWhileHandlingException(httpManager.get(), throttlerToClose); + IOUtils.closeWhileHandlingException(inferenceServiceRegistry.get(), throttlerToClose); } } From e87c49cb4bdb7ee537d18f09a15abc16b82405b3 Mon Sep 17 00:00:00 2001 From: Abdon Pijpelink Date: Thu, 25 Jan 2024 16:32:24 +0100 Subject: [PATCH 31/37] [DOCS] Improve ES|QL functions reference for functions E-Z (#104623) * Functions E-Z * Incorporate changes from #103686 * More functions * More functions * Update docs/reference/esql/functions/floor.asciidoc Co-authored-by: Liam Thompson <32779855+leemthompo@users.noreply.github.com> * Update docs/reference/esql/functions/left.asciidoc Co-authored-by: Liam Thompson <32779855+leemthompo@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Alexander Spies * Review feedback * Fix geo_shape description * Change 'colum'/'field' into 'expressions' * Review feedback * One more --------- Co-authored-by: Liam Thompson <32779855+leemthompo@users.noreply.github.com> Co-authored-by: Alexander Spies Co-authored-by: Elastic Machine --- docs/reference/esql/functions/asin.asciidoc | 5 +- docs/reference/esql/functions/atan.asciidoc | 5 +- docs/reference/esql/functions/atan2.asciidoc | 5 +- .../esql/functions/auto_bucket.asciidoc | 4 +- docs/reference/esql/functions/avg.asciidoc | 8 ++-- docs/reference/esql/functions/cos.asciidoc | 4 +- docs/reference/esql/functions/cosh.asciidoc | 9 ++-- .../esql/functions/count-distinct.asciidoc | 18 ++++--- docs/reference/esql/functions/e.asciidoc | 9 +++- .../esql/functions/ends_with.asciidoc | 25 ++++++++-- docs/reference/esql/functions/floor.asciidoc | 30 ++++++++---- .../esql/functions/greatest.asciidoc | 35 ++++++++++---- docs/reference/esql/functions/least.asciidoc | 35 ++++++++++---- docs/reference/esql/functions/left.asciidoc | 26 ++++++++-- docs/reference/esql/functions/length.asciidoc | 27 +++++++++-- docs/reference/esql/functions/log10.asciidoc | 24 +++++++--- docs/reference/esql/functions/ltrim.asciidoc | 22 +++++++-- docs/reference/esql/functions/max.asciidoc | 19 +++++++- .../median-absolute-deviation.asciidoc | 43 ++++++++++++----- docs/reference/esql/functions/median.asciidoc | 33 +++++++++---- docs/reference/esql/functions/min.asciidoc | 19 +++++++- docs/reference/esql/functions/mv_avg.asciidoc | 28 +++++++++-- .../esql/functions/mv_concat.asciidoc | 29 ++++++++--- .../esql/functions/mv_count.asciidoc | 24 +++++++--- .../esql/functions/mv_dedupe.asciidoc | 26 +++++++--- .../esql/functions/mv_first.asciidoc | 37 +++++++++----- .../reference/esql/functions/mv_last.asciidoc | 37 +++++++++----- docs/reference/esql/functions/mv_max.asciidoc | 27 ++++++++--- .../esql/functions/mv_median.asciidoc | 28 +++++++++-- docs/reference/esql/functions/mv_min.asciidoc | 27 ++++++++--- docs/reference/esql/functions/mv_sum.asciidoc | 25 ++++++++-- docs/reference/esql/functions/now.asciidoc | 21 +++++++- .../esql/functions/percentile.asciidoc | 37 ++++++++++---- docs/reference/esql/functions/pi.asciidoc | 9 +++- docs/reference/esql/functions/pow.asciidoc | 36 ++++++++------ .../reference/esql/functions/replace.asciidoc | 33 +++++++++++-- docs/reference/esql/functions/right.asciidoc | 26 ++++++++-- docs/reference/esql/functions/round.asciidoc | 21 ++++++++ docs/reference/esql/functions/rtrim.asciidoc | 20 ++++++-- docs/reference/esql/functions/sin.asciidoc | 23 +++++++-- docs/reference/esql/functions/sinh.asciidoc | 22 +++++++-- docs/reference/esql/functions/split.asciidoc | 31 ++++++++---- docs/reference/esql/functions/sqrt.asciidoc | 27 ++++++++--- .../esql/functions/starts_with.asciidoc | 25 ++++++++-- .../esql/functions/substring.asciidoc | 30 +++++++++++- docs/reference/esql/functions/sum.asciidoc | 17 ++++++- docs/reference/esql/functions/tan.asciidoc | 23 +++++++-- docs/reference/esql/functions/tanh.asciidoc | 22 +++++++-- docs/reference/esql/functions/tau.asciidoc | 10 +++- .../esql/functions/to_boolean.asciidoc | 38 +++++++++++---- .../esql/functions/to_cartesianpoint.asciidoc | 30 ++++++++---- .../esql/functions/to_cartesianshape.asciidoc | 29 ++++++++--- .../esql/functions/to_datetime.asciidoc | 37 ++++++++++---- .../esql/functions/to_degrees.asciidoc | 26 ++++++++-- .../esql/functions/to_double.asciidoc | 48 ++++++++++++------- .../esql/functions/to_geopoint.asciidoc | 29 ++++++++--- .../esql/functions/to_geoshape.asciidoc | 31 ++++++++---- .../esql/functions/to_integer.asciidoc | 40 +++++++++++----- docs/reference/esql/functions/to_ip.asciidoc | 27 ++++++++--- .../reference/esql/functions/to_long.asciidoc | 34 +++++++++---- .../esql/functions/to_lower.asciidoc | 22 +++++++-- .../esql/functions/to_radians.asciidoc | 26 ++++++++-- .../esql/functions/to_string.asciidoc | 26 +++++++--- .../esql/functions/to_unsigned_long.asciidoc | 41 +++++++++++----- .../esql/functions/to_upper.asciidoc | 22 +++++++-- .../esql/functions/to_version.asciidoc | 30 ++++++++---- docs/reference/esql/functions/trim.asciidoc | 20 ++++++-- .../esql/processing-commands/where.asciidoc | 8 ++++ .../src/main/resources/date.csv-spec | 26 ++++++++++ .../src/main/resources/eval.csv-spec | 18 +++++++ 70 files changed, 1330 insertions(+), 404 deletions(-) diff --git a/docs/reference/esql/functions/asin.asciidoc b/docs/reference/esql/functions/asin.asciidoc index 222f6879785ef..a326852e9b016 100644 --- a/docs/reference/esql/functions/asin.asciidoc +++ b/docs/reference/esql/functions/asin.asciidoc @@ -14,9 +14,8 @@ Numeric expression. If `null`, the function returns `null`. *Description* -Returns the -https://en.wikipedia.org/wiki/Inverse_trigonometric_functions[arcsine] -of the input numeric expression as an angle, expressed in radians. +Returns the {wikipedia}/Inverse_trigonometric_functions[arcsine] of the input +numeric expression as an angle, expressed in radians. *Supported types* diff --git a/docs/reference/esql/functions/atan.asciidoc b/docs/reference/esql/functions/atan.asciidoc index bdbbd07cbba60..604fc4d0bbecc 100644 --- a/docs/reference/esql/functions/atan.asciidoc +++ b/docs/reference/esql/functions/atan.asciidoc @@ -14,9 +14,8 @@ Numeric expression. If `null`, the function returns `null`. *Description* -Returns the -https://en.wikipedia.org/wiki/Inverse_trigonometric_functions[arctangent] of the -input numeric expression as an angle, expressed in radians. +Returns the {wikipedia}/Inverse_trigonometric_functions[arctangent] of the input +numeric expression as an angle, expressed in radians. *Supported types* diff --git a/docs/reference/esql/functions/atan2.asciidoc b/docs/reference/esql/functions/atan2.asciidoc index 3ecc0ff86fe26..1920b4b7ac1a0 100644 --- a/docs/reference/esql/functions/atan2.asciidoc +++ b/docs/reference/esql/functions/atan2.asciidoc @@ -17,9 +17,8 @@ Numeric expression. If `null`, the function returns `null`. *Description* -The https://en.wikipedia.org/wiki/Atan2[angle] between the positive x-axis and -the ray from the origin to the point (x , y) in the Cartesian plane, expressed -in radians. +The {wikipedia}/Atan2[angle] between the positive x-axis and the ray from the +origin to the point (x , y) in the Cartesian plane, expressed in radians. *Supported types* diff --git a/docs/reference/esql/functions/auto_bucket.asciidoc b/docs/reference/esql/functions/auto_bucket.asciidoc index 2301939cf5050..aedfdaa7c0e12 100644 --- a/docs/reference/esql/functions/auto_bucket.asciidoc +++ b/docs/reference/esql/functions/auto_bucket.asciidoc @@ -6,13 +6,13 @@ [source,esql] ---- -AUTO_BUCKET(field, buckets, from, to) +AUTO_BUCKET(expression, buckets, from, to) ---- *Parameters* `field`:: -Numeric or date column from which to derive buckets. +Numeric or date expression from which to derive buckets. `buckets`:: Target number of buckets. diff --git a/docs/reference/esql/functions/avg.asciidoc b/docs/reference/esql/functions/avg.asciidoc index 6345be99c5d6d..9a6f5a82d1959 100644 --- a/docs/reference/esql/functions/avg.asciidoc +++ b/docs/reference/esql/functions/avg.asciidoc @@ -6,15 +6,15 @@ [source,esql] ---- -AVG(column) +AVG(expression) ---- -`column`:: -Numeric column. If `null`, the function returns `null`. +`expression`:: +Numeric expression. If `null`, the function returns `null`. *Description* -The average of a numeric field. +The average of a numeric expression. *Supported types* diff --git a/docs/reference/esql/functions/cos.asciidoc b/docs/reference/esql/functions/cos.asciidoc index f7874d46c558a..a5a0251bbd70a 100644 --- a/docs/reference/esql/functions/cos.asciidoc +++ b/docs/reference/esql/functions/cos.asciidoc @@ -14,8 +14,8 @@ Numeric expression. If `null`, the function returns `null`. *Description* -Returns the https://en.wikipedia.org/wiki/Sine_and_cosine[cosine] of `n`. Input -expected in radians. +Returns the {wikipedia}/Sine_and_cosine[cosine] of `n`. Input expected in +radians. *Supported types* diff --git a/docs/reference/esql/functions/cosh.asciidoc b/docs/reference/esql/functions/cosh.asciidoc index ae813e91ec9bb..5883bc4b9d0c4 100644 --- a/docs/reference/esql/functions/cosh.asciidoc +++ b/docs/reference/esql/functions/cosh.asciidoc @@ -12,14 +12,13 @@ image::esql/functions/signature/cosh.svg[Embedded,opts=inline] `n`:: Numeric expression. If `null`, the function returns `null`. -*Supported types* +*Description* -include::types/cosh.asciidoc[] +Returns the {wikipedia}/Hyperbolic_functions[hyperbolic cosine]. -*Description* +*Supported types* -Returns the https://en.wikipedia.org/wiki/Hyperbolic_functions[hyperbolic -cosine]. +include::types/cosh.asciidoc[] *Example* diff --git a/docs/reference/esql/functions/count-distinct.asciidoc b/docs/reference/esql/functions/count-distinct.asciidoc index 14fa6eff39d4c..04a200935cd48 100644 --- a/docs/reference/esql/functions/count-distinct.asciidoc +++ b/docs/reference/esql/functions/count-distinct.asciidoc @@ -6,7 +6,7 @@ [source,esql] ---- -COUNT_DISTINCT(column[, precision]) +COUNT_DISTINCT(column[, precision_threshold]) ---- *Parameters* @@ -14,8 +14,10 @@ COUNT_DISTINCT(column[, precision]) `column`:: Column for which to count the number of distinct values. -`precision`:: -Precision. Refer to <>. +`precision_threshold`:: +Precision threshold. Refer to <>. The +maximum supported value is 40000. Thresholds above this number will have the +same effect as a threshold of 40000. The default value is 3000. *Description* @@ -37,8 +39,12 @@ properties: include::../../aggregations/metrics/cardinality-aggregation.asciidoc[tag=explanation] -The `COUNT_DISTINCT` function takes an optional second parameter to configure the -precision. +The `COUNT_DISTINCT` function takes an optional second parameter to configure +the precision threshold. The precision_threshold options allows to trade memory +for accuracy, and defines a unique count below which counts are expected to be +close to accurate. Above this value, counts might become a bit more fuzzy. The +maximum supported value is 40000, thresholds above this number will have the +same effect as a threshold of 40000. The default value is `3000`. *Supported types* @@ -55,7 +61,7 @@ include::{esql-specs}/stats_count_distinct.csv-spec[tag=count-distinct] include::{esql-specs}/stats_count_distinct.csv-spec[tag=count-distinct-result] |=== -With the optional second parameter to configure the precision: +With the optional second parameter to configure the precision threshold: [source.merge.styled,esql] ---- diff --git a/docs/reference/esql/functions/e.asciidoc b/docs/reference/esql/functions/e.asciidoc index 56bf97fd01740..ac082c1a68a07 100644 --- a/docs/reference/esql/functions/e.asciidoc +++ b/docs/reference/esql/functions/e.asciidoc @@ -1,10 +1,17 @@ [discrete] [[esql-e]] === `E` + +*Syntax* + [.text-center] image::esql/functions/signature/e.svg[Embedded,opts=inline] -{wikipedia}/E_(mathematical_constant)[Euler's number]. +*Description* + +Returns {wikipedia}/E_(mathematical_constant)[Euler's number]. + +*Example* [source.merge.styled,esql] ---- diff --git a/docs/reference/esql/functions/ends_with.asciidoc b/docs/reference/esql/functions/ends_with.asciidoc index fd2d99931163a..49477996ada19 100644 --- a/docs/reference/esql/functions/ends_with.asciidoc +++ b/docs/reference/esql/functions/ends_with.asciidoc @@ -1,11 +1,30 @@ [discrete] [[esql-ends_with]] === `ENDS_WITH` + +*Syntax* + [.text-center] image::esql/functions/signature/ends_with.svg[Embedded,opts=inline] +*Parameters* + +`str`:: +String expression. If `null`, the function returns `null`. + +`suffix`:: +String expression. If `null`, the function returns `null`. + +*Description* + Returns a boolean that indicates whether a keyword string ends with another -string: +string. + +*Supported types* + +include::types/ends_with.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -15,7 +34,3 @@ include::{esql-specs}/string.csv-spec[tag=endsWith] |=== include::{esql-specs}/string.csv-spec[tag=endsWith-result] |=== - -Supported types: - -include::types/ends_with.asciidoc[] diff --git a/docs/reference/esql/functions/floor.asciidoc b/docs/reference/esql/functions/floor.asciidoc index 109033bb18827..0730a87e595fd 100644 --- a/docs/reference/esql/functions/floor.asciidoc +++ b/docs/reference/esql/functions/floor.asciidoc @@ -1,10 +1,30 @@ [discrete] [[esql-floor]] === `FLOOR` + +*Syntax* + [.text-center] image::esql/functions/signature/floor.svg[Embedded,opts=inline] -Round a number down to the nearest integer. +*Parameters* + +`n`:: +Numeric expression. If `null`, the function returns `null`. + +*Description* + +Rounds a number down to the nearest integer. + +NOTE: This is a noop for `long` (including unsigned) and `integer`. + For `double` this picks the closest `double` value to the integer + similar to {javadoc}/java.base/java/lang/Math.html#floor(double)[Math.floor]. + +*Supported types* + +include::types/floor.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -14,11 +34,3 @@ include::{esql-specs}/math.csv-spec[tag=floor] |=== include::{esql-specs}/math.csv-spec[tag=floor-result] |=== - -NOTE: This is a noop for `long` (including unsigned) and `integer`. - For `double` this picks the the closest `double` value to the integer ala - {javadoc}/java.base/java/lang/Math.html#floor(double)[Math.floor]. - -Supported types: - -include::types/floor.asciidoc[] diff --git a/docs/reference/esql/functions/greatest.asciidoc b/docs/reference/esql/functions/greatest.asciidoc index 24dd08de2819c..b9fc114d39ec6 100644 --- a/docs/reference/esql/functions/greatest.asciidoc +++ b/docs/reference/esql/functions/greatest.asciidoc @@ -1,11 +1,34 @@ [discrete] [[esql-greatest]] === `GREATEST` + +*Syntax* + [.text-center] image::esql/functions/signature/greatest.svg[Embedded,opts=inline] -Returns the maximum value from many columns. This is similar to <> -except it's intended to run on multiple columns at once. +*Parameters* + +`first`:: +First of the columns to evaluate. + +`rest`:: +The rest of the columns to evaluate. + +*Description* + +Returns the maximum value from multiple columns. This is similar to <> +except it is intended to run on multiple columns at once. + +NOTE: When run on `keyword` or `text` fields, this returns the last string + in alphabetical order. When run on `boolean` columns this will return + `true` if any values are `true`. + +*Supported types* + +include::types/greatest.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -15,11 +38,3 @@ include::{esql-specs}/math.csv-spec[tag=greatest] |=== include::{esql-specs}/math.csv-spec[tag=greatest-result] |=== - -NOTE: When run on `keyword` or `text` fields, this'll return the last string - in alphabetical order. When run on `boolean` columns this will return - `true` if any values are `true`. - -Supported types: - -include::types/greatest.asciidoc[] diff --git a/docs/reference/esql/functions/least.asciidoc b/docs/reference/esql/functions/least.asciidoc index 62d7406199cd4..41f58b0d415c2 100644 --- a/docs/reference/esql/functions/least.asciidoc +++ b/docs/reference/esql/functions/least.asciidoc @@ -1,11 +1,34 @@ [discrete] [[esql-least]] === `LEAST` + +*Syntax* + [.text-center] image::esql/functions/signature/least.svg[Embedded,opts=inline] -Returns the minimum value from many columns. This is similar to <> -except it's intended to run on multiple columns at once. +*Parameters* + +`first`:: +First of the columns to evaluate. + +`rest`:: +The rest of the columns to evaluate. + +*Description* + +Returns the minimum value from multiple columns. This is similar to +<> except it is intended to run on multiple columns at once. + +NOTE: When run on `keyword` or `text` fields, this returns the first string + in alphabetical order. When run on `boolean` columns this will return + `false` if any values are `false`. + +*Supported types* + +include::types/least.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -15,11 +38,3 @@ include::{esql-specs}/math.csv-spec[tag=least] |=== include::{esql-specs}/math.csv-spec[tag=least-result] |=== - -NOTE: When run on `keyword` or `text` fields, this'll return the first string - in alphabetical order. When run on `boolean` columns this will return - `false` if any values are `false`. - -Supported types: - -include::types/least.asciidoc[] diff --git a/docs/reference/esql/functions/left.asciidoc b/docs/reference/esql/functions/left.asciidoc index 67e739377aa46..5d666656b1ee4 100644 --- a/docs/reference/esql/functions/left.asciidoc +++ b/docs/reference/esql/functions/left.asciidoc @@ -1,10 +1,30 @@ [discrete] [[esql-left]] === `LEFT` + +*Syntax* + [.text-center] image::esql/functions/signature/left.svg[Embedded,opts=inline] -Return the substring that extracts 'length' chars from the 'string' starting from the left. +*Parameters* + +`str`:: +The string from which to return a substring. + +`length`:: +The number of characters to return. + +*Description* + +Returns the substring that extracts 'length' chars from 'str' starting +from the left. + +*Supported types* + +include::types/left.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -14,7 +34,3 @@ include::{esql-specs}/string.csv-spec[tag=left] |=== include::{esql-specs}/string.csv-spec[tag=left-result] |=== - -Supported types: - -include::types/left.asciidoc[] diff --git a/docs/reference/esql/functions/length.asciidoc b/docs/reference/esql/functions/length.asciidoc index 12e1bed3d0a66..b89b75a702460 100644 --- a/docs/reference/esql/functions/length.asciidoc +++ b/docs/reference/esql/functions/length.asciidoc @@ -1,11 +1,30 @@ [discrete] [[esql-length]] === `LENGTH` -Returns the character length of a string. + +*Syntax* [source,esql] ---- -FROM employees -| KEEP first_name, last_name, height -| EVAL fn_length = LENGTH(first_name) +LENGTH(str) +---- + +*Parameters* + +`str`:: +String expression. If `null`, the function returns `null`. + +*Description* + +Returns the character length of a string. + +*Example* + +[source.merge.styled,esql] +---- +include::{esql-specs}/eval.csv-spec[tag=length] ---- +[%header.monospaced.styled,format=dsv,separator=|] +|=== +include::{esql-specs}/eval.csv-spec[tag=length-result] +|=== diff --git a/docs/reference/esql/functions/log10.asciidoc b/docs/reference/esql/functions/log10.asciidoc index 219519ca2a0d7..d806da3173818 100644 --- a/docs/reference/esql/functions/log10.asciidoc +++ b/docs/reference/esql/functions/log10.asciidoc @@ -1,13 +1,27 @@ [discrete] [[esql-log10]] === `LOG10` + +*Syntax* + [.text-center] image::esql/functions/signature/log10.svg[Embedded,opts=inline] -Returns the log base 10. The input can be any numeric value, the return value -is always a double. +`n`:: +Numeric expression. If `null`, the function returns `null`. + +*Description* -Logs of negative numbers are NaN. Logs of infinites are infinite, as is the log of 0. +Returns the logarithm to base 10. The input can be any numeric value, the return +value is always a double. + +Logs of 0, negative numbers, and infinites return `null` as well as a warning. + +*Supported types* + +include::types/log10.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -17,7 +31,3 @@ include::{esql-specs}/math.csv-spec[tag=log10] |=== include::{esql-specs}/math.csv-spec[tag=log10-result] |=== - -Supported types: - -include::types/log10.asciidoc[] diff --git a/docs/reference/esql/functions/ltrim.asciidoc b/docs/reference/esql/functions/ltrim.asciidoc index e5230e4edd41a..4b7b619d06afc 100644 --- a/docs/reference/esql/functions/ltrim.asciidoc +++ b/docs/reference/esql/functions/ltrim.asciidoc @@ -1,11 +1,27 @@ [discrete] [[esql-ltrim]] === `LTRIM` + +*Syntax* + [.text-center] image::esql/functions/signature/ltrim.svg[Embedded,opts=inline] +*Parameters* + +`str`:: +String expression. If `null`, the function returns `null`. + +*Description* + Removes leading whitespaces from strings. +*Supported types* + +include::types/rtrim.asciidoc[] + +*Example* + [source.merge.styled,esql] ---- include::{esql-specs}/string.csv-spec[tag=ltrim] @@ -13,8 +29,4 @@ include::{esql-specs}/string.csv-spec[tag=ltrim] [%header.monospaced.styled,format=dsv,separator=|] |=== include::{esql-specs}/string.csv-spec[tag=ltrim-result] -|=== - -Supported types: - -include::types/rtrim.asciidoc[] +|=== \ No newline at end of file diff --git a/docs/reference/esql/functions/max.asciidoc b/docs/reference/esql/functions/max.asciidoc index 53997e501b37f..4bc62de341d9d 100644 --- a/docs/reference/esql/functions/max.asciidoc +++ b/docs/reference/esql/functions/max.asciidoc @@ -1,7 +1,24 @@ [discrete] [[esql-agg-max]] === `MAX` -The maximum value of a numeric field. + +*Syntax* + +[source,esql] +---- +MAX(column) +---- + +*Parameters* + +`column`:: +Column from which to return the maximum value. + +*Description* + +Returns the maximum value of a numeric column. + +*Example* [source.merge.styled,esql] ---- diff --git a/docs/reference/esql/functions/median-absolute-deviation.asciidoc b/docs/reference/esql/functions/median-absolute-deviation.asciidoc index fe0923da1fb88..301d344489643 100644 --- a/docs/reference/esql/functions/median-absolute-deviation.asciidoc +++ b/docs/reference/esql/functions/median-absolute-deviation.asciidoc @@ -1,23 +1,29 @@ [discrete] [[esql-agg-median-absolute-deviation]] === `MEDIAN_ABSOLUTE_DEVIATION` -The median absolute deviation, a measure of variability. It is a robust -statistic, meaning that it is useful for describing data that may have outliers, -or may not be normally distributed. For such data it can be more descriptive than -standard deviation. -It is calculated as the median of each data point’s deviation from the median of -the entire sample. That is, for a random variable `X`, the median absolute deviation -is `median(|median(X) - Xi|)`. +*Syntax* -[source.merge.styled,esql] +[source,esql] ---- -include::{esql-specs}/stats_percentile.csv-spec[tag=median-absolute-deviation] +MEDIAN_ABSOLUTE_DEVIATION(column) ---- -[%header.monospaced.styled,format=dsv,separator=|] -|=== -include::{esql-specs}/stats_percentile.csv-spec[tag=median-absolute-deviation-result] -|=== + +*Parameters* + +`column`:: +Column from which to return the median absolute deviation. + +*Description* + +Returns the median absolute deviation, a measure of variability. It is a robust +statistic, meaning that it is useful for describing data that may have outliers, +or may not be normally distributed. For such data it can be more descriptive +than standard deviation. + +It is calculated as the median of each data point's deviation from the median of +the entire sample. That is, for a random variable `X`, the median absolute +deviation is `median(|median(X) - X|)`. NOTE: Like <>, `MEDIAN_ABSOLUTE_DEVIATION` is <>. @@ -27,3 +33,14 @@ NOTE: Like <>, `MEDIAN_ABSOLUTE_DEVIATION` is `MEDIAN_ABSOLUTE_DEVIATION` is also {wikipedia}/Nondeterministic_algorithm[non-deterministic]. This means you can get slightly different results using the same data. ==== + +*Example* + +[source.merge.styled,esql] +---- +include::{esql-specs}/stats_percentile.csv-spec[tag=median-absolute-deviation] +---- +[%header.monospaced.styled,format=dsv,separator=|] +|=== +include::{esql-specs}/stats_percentile.csv-spec[tag=median-absolute-deviation-result] +|=== diff --git a/docs/reference/esql/functions/median.asciidoc b/docs/reference/esql/functions/median.asciidoc index 5a0d0c049602e..17b51d9c50b26 100644 --- a/docs/reference/esql/functions/median.asciidoc +++ b/docs/reference/esql/functions/median.asciidoc @@ -1,17 +1,23 @@ [discrete] [[esql-agg-median]] === `MEDIAN` -The value that is greater than half of all values and less than half of -all values, also known as the 50% <>. -[source.merge.styled,esql] +*Syntax* + +[source,esql] ---- -include::{esql-specs}/stats_percentile.csv-spec[tag=median] +MEDIAN(column) ---- -[%header.monospaced.styled,format=dsv,separator=|] -|=== -include::{esql-specs}/stats_percentile.csv-spec[tag=median-result] -|=== + +*Parameters* + +`column`:: +Column from which to return the median value. + +*Description* + +Returns the value that is greater than half of all values and less than half of +all values, also known as the 50% <>. NOTE: Like <>, `MEDIAN` is <>. @@ -20,3 +26,14 @@ NOTE: Like <>, `MEDIAN` is <> on them first: +To concat non-string columns, call <> first: [source.merge.styled,esql] ---- @@ -26,7 +45,3 @@ include::{esql-specs}/string.csv-spec[tag=mv_concat-to_string] |=== include::{esql-specs}/string.csv-spec[tag=mv_concat-to_string-result] |=== - -Supported types: - -include::types/mv_concat.asciidoc[] diff --git a/docs/reference/esql/functions/mv_count.asciidoc b/docs/reference/esql/functions/mv_count.asciidoc index e6a61cd6e9c63..0545335556030 100644 --- a/docs/reference/esql/functions/mv_count.asciidoc +++ b/docs/reference/esql/functions/mv_count.asciidoc @@ -1,11 +1,27 @@ [discrete] [[esql-mv_count]] === `MV_COUNT` + +*Syntax* + [.text-center] image::esql/functions/signature/mv_count.svg[Embedded,opts=inline] -Converts a multivalued field into a single valued field containing a count of the number -of values: +*Parameters* + +`v`:: +Multivalue expression. + +*Description* + +Converts a multivalued expression into a single valued column containing a count +of the number of values. + +*Supported types* + +include::types/mv_count.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -15,7 +31,3 @@ include::{esql-specs}/string.csv-spec[tag=mv_count] |=== include::{esql-specs}/string.csv-spec[tag=mv_count-result] |=== - -Supported types: - -include::types/mv_count.asciidoc[] diff --git a/docs/reference/esql/functions/mv_dedupe.asciidoc b/docs/reference/esql/functions/mv_dedupe.asciidoc index c85c6ddff4354..09b3827c45e45 100644 --- a/docs/reference/esql/functions/mv_dedupe.asciidoc +++ b/docs/reference/esql/functions/mv_dedupe.asciidoc @@ -1,10 +1,28 @@ [discrete] [[esql-mv_dedupe]] === `MV_DEDUPE` + +*Syntax* + [.text-center] image::esql/functions/signature/mv_dedupe.svg[Embedded,opts=inline] -Removes duplicates from a multivalued field. For example: +*Parameters* + +`v`:: +Multivalue expression. + +*Description* + +Removes duplicates from a multivalue expression. + +NOTE: `MV_DEDUPE` may, but won't always, sort the values in the column. + +*Supported types* + +include::types/mv_dedupe.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -14,9 +32,3 @@ include::{esql-specs}/string.csv-spec[tag=mv_dedupe] |=== include::{esql-specs}/string.csv-spec[tag=mv_dedupe-result] |=== - -Supported types: - -include::types/mv_dedupe.asciidoc[] - -NOTE: `MV_DEDUPE` may, but won't always, sort the values in the field. diff --git a/docs/reference/esql/functions/mv_first.asciidoc b/docs/reference/esql/functions/mv_first.asciidoc index 42ac8930136cc..13d21b15f958e 100644 --- a/docs/reference/esql/functions/mv_first.asciidoc +++ b/docs/reference/esql/functions/mv_first.asciidoc @@ -1,11 +1,34 @@ [discrete] [[esql-mv_first]] === `MV_FIRST` + +*Syntax* + [.text-center] image::esql/functions/signature/mv_first.svg[Embedded,opts=inline] -Converts a multivalued field into a single valued field containing the first value. This is most -useful when reading from a function that emits multivalued fields in a known order like <>: +*Parameters* + +`v`:: +Multivalue expression. + +*Description* + +Converts a multivalued expression into a single valued column containing the +first value. This is most useful when reading from a function that emits +multivalued columns in a known order like <>. + +The order that <> are read from +underlying storage is not guaranteed. It is *frequently* ascending, but don't +rely on that. If you need the minimum value use <> instead of +`MV_FIRST`. `MV_MIN` has optimizations for sorted values so there isn't a +performance benefit to `MV_FIRST`. + +*Supported types* + +include::types/mv_first.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -15,13 +38,3 @@ include::{esql-specs}/string.csv-spec[tag=mv_first] |=== include::{esql-specs}/string.csv-spec[tag=mv_first-result] |=== - -The order that <> are read from underlying storage is not -guaranteed. It is *frequently* ascending, but don't rely on that. If you need the minimum field value -use <> instead of `MV_FIRST`. `MV_MIN` has optimizations for sorted values so there isn't -a performance benefit to `MV_FIRST`. `MV_FIRST` is mostly useful with functions that create multivalued -fields like `SPLIT`. - -Supported types: - -include::types/mv_first.asciidoc[] diff --git a/docs/reference/esql/functions/mv_last.asciidoc b/docs/reference/esql/functions/mv_last.asciidoc index aa6fc40d0af07..ee6a4a8fed8ba 100644 --- a/docs/reference/esql/functions/mv_last.asciidoc +++ b/docs/reference/esql/functions/mv_last.asciidoc @@ -1,11 +1,34 @@ [discrete] [[esql-mv_last]] === `MV_LAST` + +*Syntax* + [.text-center] image::esql/functions/signature/mv_last.svg[Embedded,opts=inline] -Converts a multivalued field into a single valued field containing the last value. This is most -useful when reading from a function that emits multivalued fields in a known order like <>: +*Parameters* + +`v`:: +Multivalue expression. + +*Description* + +Converts a multivalue expression into a single valued column containing the last +value. This is most useful when reading from a function that emits multivalued +columns in a known order like <>. + +The order that <> are read from +underlying storage is not guaranteed. It is *frequently* ascending, but don't +rely on that. If you need the maximum value use <> instead of +`MV_LAST`. `MV_MAX` has optimizations for sorted values so there isn't a +performance benefit to `MV_LAST`. + +*Supported types* + +include::types/mv_last.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -15,13 +38,3 @@ include::{esql-specs}/string.csv-spec[tag=mv_last] |=== include::{esql-specs}/string.csv-spec[tag=mv_last-result] |=== - -The order that <> are read from underlying storage is not -guaranteed. It is *frequently* ascending, but don't rely on that. If you need the maximum field value -use <> instead of `MV_LAST`. `MV_MAX` has optimizations for sorted values so there isn't -a performance benefit to `MV_LAST`. `MV_LAST` is mostly useful with functions that create multivalued -fields like `SPLIT`. - -Supported types: - -include::types/mv_last.asciidoc[] diff --git a/docs/reference/esql/functions/mv_max.asciidoc b/docs/reference/esql/functions/mv_max.asciidoc index ed433b64a2813..e13e61e0d123d 100644 --- a/docs/reference/esql/functions/mv_max.asciidoc +++ b/docs/reference/esql/functions/mv_max.asciidoc @@ -1,10 +1,27 @@ [discrete] [[esql-mv_max]] === `MV_MAX` + +*Syntax* + [.text-center] image::esql/functions/signature/mv_max.svg[Embedded,opts=inline] -Converts a multivalued field into a single valued field containing the maximum value. For example: +*Parameters* + +`v`:: +Multivalue expression. + +*Description* + +Converts a multivalued expression into a single valued column containing the +maximum value. + +*Supported types* + +include::types/mv_max.asciidoc[] + +*Examples* [source.merge.styled,esql] ---- @@ -15,8 +32,8 @@ include::{esql-specs}/math.csv-spec[tag=mv_max] include::{esql-specs}/math.csv-spec[tag=mv_max-result] |=== -It can be used by any field type, including `keyword` fields. In that case picks the -last string, comparing their utf-8 representation byte by byte: +It can be used by any column type, including `keyword` columns. In that case +it picks the last string, comparing their utf-8 representation byte by byte: [source.merge.styled,esql] ---- @@ -26,7 +43,3 @@ include::{esql-specs}/string.csv-spec[tag=mv_max] |=== include::{esql-specs}/string.csv-spec[tag=mv_max-result] |=== - -Supported types: - -include::types/mv_max.asciidoc[] diff --git a/docs/reference/esql/functions/mv_median.asciidoc b/docs/reference/esql/functions/mv_median.asciidoc index c84cf7a895da5..05c54342c0f74 100644 --- a/docs/reference/esql/functions/mv_median.asciidoc +++ b/docs/reference/esql/functions/mv_median.asciidoc @@ -1,7 +1,27 @@ [discrete] [[esql-mv_median]] === `MV_MEDIAN` -Converts a multivalued field into a single valued field containing the median value. For example: + +[source,esql] +---- +MV_MEDIAN(v) +---- + +*Parameters* + +`v`:: +Multivalue expression. + +*Description* + +Converts a multivalued column into a single valued column containing the median +value. + +*Supported types* + +include::types/mv_median.asciidoc[] + +*Examples* [source.merge.styled,esql] ---- @@ -12,9 +32,9 @@ include::{esql-specs}/math.csv-spec[tag=mv_median] include::{esql-specs}/math.csv-spec[tag=mv_median-result] |=== -It can be used by any numeric field type and returns a value of the same type. If the -row has an even number of values for a column the result will be the average of the -middle two entries. If the field is not floating point then the average rounds *down*: +If the row has an even number of values for a column, the result will be the +average of the middle two entries. If the column is not floating point, the +average rounds *down*: [source.merge.styled,esql] ---- diff --git a/docs/reference/esql/functions/mv_min.asciidoc b/docs/reference/esql/functions/mv_min.asciidoc index b0c8dd51c97fc..b851f480fd619 100644 --- a/docs/reference/esql/functions/mv_min.asciidoc +++ b/docs/reference/esql/functions/mv_min.asciidoc @@ -1,10 +1,27 @@ [discrete] [[esql-mv_min]] === `MV_MIN` + +*Syntax* + [.text-center] image::esql/functions/signature/mv_min.svg[Embedded,opts=inline] -Converts a multivalued field into a single valued field containing the minimum value. For example: +*Parameters* + +`v`:: +Multivalue expression. + +*Description* + +Converts a multivalued expression into a single valued column containing the +minimum value. + +*Supported types* + +include::types/mv_min.asciidoc[] + +*Examples* [source.merge.styled,esql] ---- @@ -15,8 +32,8 @@ include::{esql-specs}/math.csv-spec[tag=mv_min] include::{esql-specs}/math.csv-spec[tag=mv_min-result] |=== -It can be used by any field type, including `keyword` fields. In that case picks the -first string, comparing their utf-8 representation byte by byte: +It can be used by any column type, including `keyword` columns. In that case, +it picks the first string, comparing their utf-8 representation byte by byte: [source.merge.styled,esql] ---- @@ -26,7 +43,3 @@ include::{esql-specs}/string.csv-spec[tag=mv_min] |=== include::{esql-specs}/string.csv-spec[tag=mv_min-result] |=== - -Supported types: - -include::types/mv_min.asciidoc[] diff --git a/docs/reference/esql/functions/mv_sum.asciidoc b/docs/reference/esql/functions/mv_sum.asciidoc index 646af03305954..bc252bc9d3fa0 100644 --- a/docs/reference/esql/functions/mv_sum.asciidoc +++ b/docs/reference/esql/functions/mv_sum.asciidoc @@ -1,8 +1,27 @@ [discrete] [[esql-mv_sum]] === `MV_SUM` -Converts a multivalued field into a single valued field containing the sum -of all of the values. For example: + +[source,esql] +---- +MV_SUM(v) +---- + +*Parameters* + +`v`:: +Multivalue expression. + +*Description* + +Converts a multivalued column into a single valued column containing the sum +of all of the values. + +*Supported types* + +include::types/mv_sum.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -12,5 +31,3 @@ include::{esql-specs}/math.csv-spec[tag=mv_sum] |=== include::{esql-specs}/math.csv-spec[tag=mv_sum-result] |=== - -NOTE: The input type can be any number and the output type is the same as the input type. diff --git a/docs/reference/esql/functions/now.asciidoc b/docs/reference/esql/functions/now.asciidoc index 5d33449a1e906..3c46f557acd1f 100644 --- a/docs/reference/esql/functions/now.asciidoc +++ b/docs/reference/esql/functions/now.asciidoc @@ -1,9 +1,28 @@ [discrete] [[esql-now]] === `NOW` + +*Syntax* + +[source,esql] +---- +NOW() +---- + +*Description* + Returns current date and time. +*Example* + [source,esql] ---- -ROW current_date = NOW() +include::{esql-specs}/date.csv-spec[tag=docsNow] +---- + +To retrieve logs from the last hour: + +[source,esql] ---- +include::{esql-specs}/date.csv-spec[tag=docsNowWhere] +---- \ No newline at end of file diff --git a/docs/reference/esql/functions/percentile.asciidoc b/docs/reference/esql/functions/percentile.asciidoc index 917a4a81e7b4f..ab3f14af70486 100644 --- a/docs/reference/esql/functions/percentile.asciidoc +++ b/docs/reference/esql/functions/percentile.asciidoc @@ -1,18 +1,27 @@ [discrete] [[esql-agg-percentile]] === `PERCENTILE` -The value at which a certain percentage of observed values occur. For example, -the 95th percentile is the value which is greater than 95% of the observed values and -the 50th percentile is the <>. -[source.merge.styled,esql] +*Syntax* + +[source,esql] ---- -include::{esql-specs}/stats_percentile.csv-spec[tag=percentile] +PERCENTILE(column, percentile) ---- -[%header.monospaced.styled,format=dsv,separator=|] -|=== -include::{esql-specs}/stats_percentile.csv-spec[tag=percentile-result] -|=== + +*Parameters* + +`column`:: +Column to convert from multiple values to single value. + +`percentile`:: +A constant numeric expression. + +*Description* + +Returns the value at which a certain percentage of observed values occur. For +example, the 95th percentile is the value which is greater than 95% of the +observed values and the 50th percentile is the <>. [discrete] [[esql-agg-percentile-approximate]] @@ -26,5 +35,13 @@ include::../../aggregations/metrics/percentile-aggregation.asciidoc[tag=approxim This means you can get slightly different results using the same data. ==== +*Example* - +[source.merge.styled,esql] +---- +include::{esql-specs}/stats_percentile.csv-spec[tag=percentile] +---- +[%header.monospaced.styled,format=dsv,separator=|] +|=== +include::{esql-specs}/stats_percentile.csv-spec[tag=percentile-result] +|=== diff --git a/docs/reference/esql/functions/pi.asciidoc b/docs/reference/esql/functions/pi.asciidoc index cd630aaabadcd..fb88cbffc99d0 100644 --- a/docs/reference/esql/functions/pi.asciidoc +++ b/docs/reference/esql/functions/pi.asciidoc @@ -1,10 +1,17 @@ [discrete] [[esql-pi]] === `PI` + +*Syntax* + [.text-center] image::esql/functions/signature/pi.svg[Embedded,opts=inline] -The {wikipedia}/Pi[ratio] of a circle's circumference to its diameter. +*Description* + +Returns the {wikipedia}/Pi[ratio] of a circle's circumference to its diameter. + +*Example* [source.merge.styled,esql] ---- diff --git a/docs/reference/esql/functions/pow.asciidoc b/docs/reference/esql/functions/pow.asciidoc index b13151c8cbd76..8c31bd21e8a46 100644 --- a/docs/reference/esql/functions/pow.asciidoc +++ b/docs/reference/esql/functions/pow.asciidoc @@ -1,12 +1,31 @@ [discrete] [[esql-pow]] === `POW` + +*Syntax* + [.text-center] image::esql/functions/signature/pow.svg[Embedded,opts=inline] -Returns the value of a base (first argument) raised to the power of an exponent (second argument). -Both arguments must be numeric. The output is always a double. Note that it is still possible to overflow -a double result here; in that case, null will be returned. +*Parameters* + +`base`:: +Numeric expression. If `null`, the function returns `null`. + +`exponent`:: +Numeric expression. If `null`, the function returns `null`. + +*Description* + +Returns the value of `base` raised to the power of `exponent`. Both arguments +must be numeric. The output is always a double. Note that it is still possible +to overflow a double result here; in that case, null will be returned. + +*Supported types* + +include::types/pow.asciidoc[] + +*Examples* [source.merge.styled,esql] ---- @@ -17,10 +36,6 @@ include::{esql-specs}/math.csv-spec[tag=powDI] include::{esql-specs}/math.csv-spec[tag=powDI-result] |=== - -[discrete] -==== Fractional exponents - The exponent can be a fraction, which is similar to performing a root. For example, the exponent of `0.5` will give the square root of the base: @@ -32,10 +47,3 @@ include::{esql-specs}/math.csv-spec[tag=powID-sqrt] |=== include::{esql-specs}/math.csv-spec[tag=powID-sqrt-result] |=== - -[discrete] -==== Table of supported input and output types - -For clarity, the following table describes the output result type for all combinations of numeric input types: - -include::types/pow.asciidoc[] diff --git a/docs/reference/esql/functions/replace.asciidoc b/docs/reference/esql/functions/replace.asciidoc index 9bc0f85fdddce..05856829eb193 100644 --- a/docs/reference/esql/functions/replace.asciidoc +++ b/docs/reference/esql/functions/replace.asciidoc @@ -1,11 +1,38 @@ [discrete] [[esql-replace]] === `REPLACE` -The function substitutes in the string (1st argument) any match of the regular expression (2nd argument) with the replacement string (3rd argument). -If any of the arguments are `NULL`, the result is `NULL`. +*Syntax* -. This example replaces an occurrence of the word "World" with the word "Universe": +[.text-center] +image::esql/functions/signature/replace.svg[Embedded,opts=inline] + +*Parameters* + +`str`:: +String expression. + +`regex`:: +Regular expression. + +`newStr`:: +Replacement string. + +*Description* + +The function substitutes in the string `str` any match of the regular expression +`regex` with the replacement string `newStr`. + +If any of the arguments is `null`, the result is `null`. + +*Supported types* + +include::types/replace.asciidoc[] + +*Example* + +This example replaces any occurrence of the word "World" with the word +"Universe": [source.merge.styled,esql] ---- diff --git a/docs/reference/esql/functions/right.asciidoc b/docs/reference/esql/functions/right.asciidoc index a0f18192d410d..1b291e53729ee 100644 --- a/docs/reference/esql/functions/right.asciidoc +++ b/docs/reference/esql/functions/right.asciidoc @@ -1,10 +1,30 @@ [discrete] [[esql-right]] === `RIGHT` + +*Syntax* + [.text-center] image::esql/functions/signature/right.svg[Embedded,opts=inline] -Return the substring that extracts 'length' chars from the 'string' starting from the right. +*Parameters* + +`str`:: +The string from which to returns a substring. + +`length`:: +The number of characters to return. + +*Description* + +Return the substring that extracts 'length' chars from 'str' starting +from the right. + +*Supported types* + +include::types/right.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -14,7 +34,3 @@ include::{esql-specs}/string.csv-spec[tag=right] |=== include::{esql-specs}/string.csv-spec[tag=right-result] |=== - -Supported types: - -include::types/right.asciidoc[] diff --git a/docs/reference/esql/functions/round.asciidoc b/docs/reference/esql/functions/round.asciidoc index 4ec71cf682d0f..7f1285e85f664 100644 --- a/docs/reference/esql/functions/round.asciidoc +++ b/docs/reference/esql/functions/round.asciidoc @@ -1,10 +1,31 @@ [discrete] [[esql-round]] === `ROUND` +*Syntax* + +[.text-center] +image::esql/functions/signature/round.svg[Embedded,opts=inline] + +*Parameters* + +`value`:: +Numeric expression. If `null`, the function returns `null`. + +`decimals`:: +Numeric expression. If `null`, the function returns `null`. + +*Description* + Rounds a number to the closest number with the specified number of digits. Defaults to 0 digits if no number of digits is provided. If the specified number of digits is negative, rounds to the number of digits left of the decimal point. +*Supported types* + +include::types/round.asciidoc[] + +*Example* + [source.merge.styled,esql] ---- include::{esql-specs}/docs.csv-spec[tag=round] diff --git a/docs/reference/esql/functions/rtrim.asciidoc b/docs/reference/esql/functions/rtrim.asciidoc index 8eb0494e90d9e..588b7b9fc5433 100644 --- a/docs/reference/esql/functions/rtrim.asciidoc +++ b/docs/reference/esql/functions/rtrim.asciidoc @@ -1,11 +1,27 @@ [discrete] [[esql-rtrim]] === `RTRIM` + +*Syntax* + [.text-center] image::esql/functions/signature/rtrim.svg[Embedded,opts=inline] +*Parameters* + +`str`:: +String expression. If `null`, the function returns `null`. + +*Description* + Removes trailing whitespaces from strings. +*Supported types* + +include::types/rtrim.asciidoc[] + +*Example* + [source.merge.styled,esql] ---- include::{esql-specs}/string.csv-spec[tag=rtrim] @@ -14,7 +30,3 @@ include::{esql-specs}/string.csv-spec[tag=rtrim] |=== include::{esql-specs}/string.csv-spec[tag=rtrim-result] |=== - -Supported types: - -include::types/rtrim.asciidoc[] diff --git a/docs/reference/esql/functions/sin.asciidoc b/docs/reference/esql/functions/sin.asciidoc index d948bf2ec39a3..e6a8e0cf9331f 100644 --- a/docs/reference/esql/functions/sin.asciidoc +++ b/docs/reference/esql/functions/sin.asciidoc @@ -1,10 +1,27 @@ [discrete] [[esql-sin]] === `SIN` + +*Syntax* + [.text-center] image::esql/functions/signature/sin.svg[Embedded,opts=inline] -https://en.wikipedia.org/wiki/Sine_and_cosine[Sine] trigonometric function. Input expected in radians. +*Parameters* + +`n`:: +Numeric expression. If `null`, the function returns `null`. + +*Description* + +{wikipedia}/Sine_and_cosine[Sine] trigonometric function. Input expected in +radians. + +*Supported types* + +include::types/sin.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -14,7 +31,3 @@ include::{esql-specs}/floats.csv-spec[tag=sin] |=== include::{esql-specs}/floats.csv-spec[tag=sin-result] |=== - -Supported types: - -include::types/sin.asciidoc[] diff --git a/docs/reference/esql/functions/sinh.asciidoc b/docs/reference/esql/functions/sinh.asciidoc index 11d1ea29bffef..683ae6962c2fd 100644 --- a/docs/reference/esql/functions/sinh.asciidoc +++ b/docs/reference/esql/functions/sinh.asciidoc @@ -1,10 +1,26 @@ [discrete] [[esql-sinh]] === `SINH` + +*Syntax* + [.text-center] image::esql/functions/signature/sinh.svg[Embedded,opts=inline] -https://en.wikipedia.org/wiki/Hyperbolic_functions[Sine] hyperbolic function. +*Parameters* + +`n`:: +Numeric expression. If `null`, the function returns `null`. + +*Description* + +{wikipedia}/Hyperbolic_functions[Sine] hyperbolic function. + +*Supported types* + +include::types/sinh.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -14,7 +30,3 @@ include::{esql-specs}/floats.csv-spec[tag=sinh] |=== include::{esql-specs}/floats.csv-spec[tag=sinh-result] |=== - -Supported types: - -include::types/sinh.asciidoc[] diff --git a/docs/reference/esql/functions/split.asciidoc b/docs/reference/esql/functions/split.asciidoc index a6f8869bf89ca..0a4ce584d01da 100644 --- a/docs/reference/esql/functions/split.asciidoc +++ b/docs/reference/esql/functions/split.asciidoc @@ -1,18 +1,33 @@ [discrete] [[esql-split]] === `SPLIT` -Split a single valued string into multiple strings. For example: -[source,esql] +[.text-center] +image::esql/functions/signature/split.svg[Embedded,opts=inline] + +*Parameters* + +`str`:: +String expression. If `null`, the function returns `null`. + +`delim`:: +Delimiter. Only single byte delimiters are currently supported. + +*Description* + +Splits a single valued string into multiple strings. + +*Supported types* + +include::types/split.asciidoc[] + +*Example* + +[source.merge.styled,esql] ---- include::{esql-specs}/string.csv-spec[tag=split] ---- - -Which splits `"foo;bar;baz;qux;quux;corge"` on `;` and returns an array: - -[%header,format=dsv,separator=|] +[%header.monospaced.styled,format=dsv,separator=|] |=== include::{esql-specs}/string.csv-spec[tag=split-result] |=== - -WARNING: Only single byte delimiters are currently supported. diff --git a/docs/reference/esql/functions/sqrt.asciidoc b/docs/reference/esql/functions/sqrt.asciidoc index 02f7060089971..faf504a6b0af4 100644 --- a/docs/reference/esql/functions/sqrt.asciidoc +++ b/docs/reference/esql/functions/sqrt.asciidoc @@ -1,13 +1,30 @@ [discrete] [[esql-sqrt]] === `SQRT` + +*Syntax* + [.text-center] image::esql/functions/signature/sqrt.svg[Embedded,opts=inline] -Returns the square root of a number. The input can be any numeric value, the return value -is always a double. +*Parameters* + +`n`:: +Numeric expression. If `null`, the function returns `null`. + +*Description* + +Returns the square root of a number. The input can be any numeric value, the +return value is always a double. + +Square roots of negative numbers are NaN. Square roots of infinites are +infinite. -Square roots of negative numbers are NaN. Square roots of infinites are infinite. +*Supported types* + +include::types/sqrt.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -17,7 +34,3 @@ include::{esql-specs}/math.csv-spec[tag=sqrt] |=== include::{esql-specs}/math.csv-spec[tag=sqrt-result] |=== - -Supported types: - -include::types/sqrt.asciidoc[] diff --git a/docs/reference/esql/functions/starts_with.asciidoc b/docs/reference/esql/functions/starts_with.asciidoc index f98a76ef68206..4d45e89882400 100644 --- a/docs/reference/esql/functions/starts_with.asciidoc +++ b/docs/reference/esql/functions/starts_with.asciidoc @@ -1,11 +1,30 @@ [discrete] [[esql-starts_with]] === `STARTS_WITH` + +*Syntax* + [.text-center] image::esql/functions/signature/starts_with.svg[Embedded,opts=inline] +*Parameters* + +`str`:: +String expression. If `null`, the function returns `null`. + +`prefix`:: +String expression. If `null`, the function returns `null`. + +*Description* + Returns a boolean that indicates whether a keyword string starts with another -string: +string. + +*Supported types* + +include::types/starts_with.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -15,7 +34,3 @@ include::{esql-specs}/docs.csv-spec[tag=startsWith] |=== include::{esql-specs}/docs.csv-spec[tag=startsWith-result] |=== - -Supported types: - -include::types/starts_with.asciidoc[] diff --git a/docs/reference/esql/functions/substring.asciidoc b/docs/reference/esql/functions/substring.asciidoc index 8b8234de05bba..73df7a19aa6b7 100644 --- a/docs/reference/esql/functions/substring.asciidoc +++ b/docs/reference/esql/functions/substring.asciidoc @@ -1,8 +1,36 @@ [discrete] [[esql-substring]] === `SUBSTRING` + +*Syntax* + +[.text-center] +image::esql/functions/signature/substring.svg[Embedded,opts=inline] + +*Parameters* + +`str`:: +String expression. If `null`, the function returns `null`. + +`start`:: +Start position. + +`length`:: +Length of the substring from the start position. Optional; if omitted, all +positions after `start` are returned. + +*Description* + Returns a substring of a string, specified by a start position and an optional -length. This example returns the first three characters of every last name: +length. + +*Supported types* + +include::types/substring.asciidoc[] + +*Examples* + +This example returns the first three characters of every last name: [source.merge.styled,esql] ---- diff --git a/docs/reference/esql/functions/sum.asciidoc b/docs/reference/esql/functions/sum.asciidoc index abf790040114d..e88ebbeb3c771 100644 --- a/docs/reference/esql/functions/sum.asciidoc +++ b/docs/reference/esql/functions/sum.asciidoc @@ -1,7 +1,22 @@ [discrete] [[esql-agg-sum]] === `SUM` -The sum of a numeric field. + +*Syntax* + +[source,esql] +---- +SUM(column) +---- + +`column`:: +Numeric column. + +*Description* + +Returns the sum of a numeric column. + +*Example* [source.merge.styled,esql] ---- diff --git a/docs/reference/esql/functions/tan.asciidoc b/docs/reference/esql/functions/tan.asciidoc index 03e450ff23b0e..cc06421616fc1 100644 --- a/docs/reference/esql/functions/tan.asciidoc +++ b/docs/reference/esql/functions/tan.asciidoc @@ -1,10 +1,27 @@ [discrete] [[esql-tan]] === `TAN` + +*Syntax* + [.text-center] image::esql/functions/signature/tan.svg[Embedded,opts=inline] -https://en.wikipedia.org/wiki/Sine_and_cosine[Tangent] trigonometric function. Input expected in radians. +*Parameters* + +`n`:: +Numeric expression. If `null`, the function returns `null`. + +*Description* + +{wikipedia}/Sine_and_cosine[Tangent] trigonometric function. Input expected in +radians. + +*Supported types* + +include::types/tan.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -14,7 +31,3 @@ include::{esql-specs}/floats.csv-spec[tag=tan] |=== include::{esql-specs}/floats.csv-spec[tag=tan-result] |=== - -Supported types: - -include::types/tan.asciidoc[] diff --git a/docs/reference/esql/functions/tanh.asciidoc b/docs/reference/esql/functions/tanh.asciidoc index 218a0155d861c..a21354d23ba50 100644 --- a/docs/reference/esql/functions/tanh.asciidoc +++ b/docs/reference/esql/functions/tanh.asciidoc @@ -1,10 +1,26 @@ [discrete] [[esql-tanh]] === `TANH` + +*Syntax* + [.text-center] image::esql/functions/signature/tanh.svg[Embedded,opts=inline] -https://en.wikipedia.org/wiki/Hyperbolic_functions[Tangent] hyperbolic function. +*Parameters* + +`n`:: +Numeric expression. If `null`, the function returns `null`. + +*Description* + +{wikipedia}/Hyperbolic_functions[Tangent] hyperbolic function. + +*Supported types* + +include::types/tanh.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -14,7 +30,3 @@ include::{esql-specs}/floats.csv-spec[tag=tanh] |=== include::{esql-specs}/floats.csv-spec[tag=tanh-result] |=== - -Supported types: - -include::types/tanh.asciidoc[] diff --git a/docs/reference/esql/functions/tau.asciidoc b/docs/reference/esql/functions/tau.asciidoc index 61f352b0db8de..d9720eb34d795 100644 --- a/docs/reference/esql/functions/tau.asciidoc +++ b/docs/reference/esql/functions/tau.asciidoc @@ -1,10 +1,18 @@ [discrete] [[esql-tau]] === `TAU` + +*Syntax* + [.text-center] image::esql/functions/signature/tau.svg[Embedded,opts=inline] -The https://tauday.com/tau-manifesto[ratio] of a circle's circumference to its radius. +*Description* + +Returns the https://tauday.com/tau-manifesto[ratio] of a circle's circumference +to its radius. + +*Example* [source.merge.styled,esql] ---- diff --git a/docs/reference/esql/functions/to_boolean.asciidoc b/docs/reference/esql/functions/to_boolean.asciidoc index 03f21a503218c..54c41625f3eba 100644 --- a/docs/reference/esql/functions/to_boolean.asciidoc +++ b/docs/reference/esql/functions/to_boolean.asciidoc @@ -1,14 +1,39 @@ [discrete] [[esql-to_boolean]] === `TO_BOOLEAN` -Converts an input value to a boolean value. -The input can be a single- or multi-valued field or an expression. The input -type must be of a string or numeric type. +*Alias* + +`TO_BOOL` + +*Syntax* + +[source,esql] +---- +TO_BOOLEAN(v) +---- + +*Parameters* + +`v`:: +Input value. The input can be a single- or multi-valued column or an expression. + +*Description* + +Converts an input value to a boolean value. A string value of *"true"* will be case-insensitive converted to the Boolean *true*. For anything else, including the empty string, the function will -return *false*. For example: +return *false*. + +The numerical value of *0* will be converted to *false*, anything else will be +converted to *true*. + +*Supported types* + +The input type must be of a string or numeric type. + +*Example* [source.merge.styled,esql] ---- @@ -18,8 +43,3 @@ include::{esql-specs}/boolean.csv-spec[tag=to_boolean] |=== include::{esql-specs}/boolean.csv-spec[tag=to_boolean-result] |=== - -The numerical value of *0* will be converted to *false*, anything else will be -converted to *true*. - -Alias: TO_BOOL diff --git a/docs/reference/esql/functions/to_cartesianpoint.asciidoc b/docs/reference/esql/functions/to_cartesianpoint.asciidoc index a0e274bd1c5b2..223556d2c0e96 100644 --- a/docs/reference/esql/functions/to_cartesianpoint.asciidoc +++ b/docs/reference/esql/functions/to_cartesianpoint.asciidoc @@ -1,13 +1,31 @@ [discrete] [[esql-to_cartesianpoint]] === `TO_CARTESIANPOINT` -Converts an input value to a `point` value. -The input can be a single- or multi-valued field or an expression. -The input type must be a string or a cartesian `point`. +*Syntax* + +[source,esql] +---- +TO_CARTESIANPOINT(v) +---- + +*Parameters* + +`v`:: +Input value. The input can be a single- or multi-valued column or an expression. + +*Description* + +Converts an input value to a `point` value. A string will only be successfully converted if it respects the -https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry[WKT Point] format: +{wikipedia}/Well-known_text_representation_of_geometry[WKT Point] format. + +*Supported types* + +include::types/to_cartesianpoint.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -17,7 +35,3 @@ include::{esql-specs}/spatial.csv-spec[tag=to_cartesianpoint-str] |=== include::{esql-specs}/spatial.csv-spec[tag=to_cartesianpoint-str-result] |=== - -Supported types: - -include::types/to_cartesianpoint.asciidoc[] diff --git a/docs/reference/esql/functions/to_cartesianshape.asciidoc b/docs/reference/esql/functions/to_cartesianshape.asciidoc index 6a19bdd3bacda..16aa275b7332b 100644 --- a/docs/reference/esql/functions/to_cartesianshape.asciidoc +++ b/docs/reference/esql/functions/to_cartesianshape.asciidoc @@ -1,13 +1,32 @@ [discrete] [[esql-to_cartesianshape]] === `TO_CARTESIANSHAPE` -Converts an input value to a `cartesian_shape` value. -The input can be a single- or multi-valued field or an expression. +*Syntax* + +[source,esql] +---- +TO_CARTESIANSHAPE(v) +---- + +*Parameters* + +`v`:: +Input value. The input can be a single- or multi-valued column or an expression. The input type must be a string or a `cartesian_shape`. +*Description* + +Converts an input value to a `cartesian_shape` value. + A string will only be successfully converted if it respects the -https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry[WKT] format: +{wikipedia}/Well-known_text_representation_of_geometry[WKT] format. + +*Supported types* + +include::types/to_cartesianshape.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -17,7 +36,3 @@ include::{esql-specs}/spatial_shapes.csv-spec[tag=to_cartesianshape-str] |=== include::{esql-specs}/spatial_shapes.csv-spec[tag=to_cartesianshape-str-result] |=== - -Supported types: - -include::types/to_cartesianshape.asciidoc[] diff --git a/docs/reference/esql/functions/to_datetime.asciidoc b/docs/reference/esql/functions/to_datetime.asciidoc index 750c8025cb6c2..9baf7d818d93c 100644 --- a/docs/reference/esql/functions/to_datetime.asciidoc +++ b/docs/reference/esql/functions/to_datetime.asciidoc @@ -1,13 +1,36 @@ [discrete] [[esql-to_datetime]] === `TO_DATETIME` -Converts an input value to a date value. -The input can be a single- or multi-valued field or an expression. The input -type must be of a string or numeric type. +*Alias* + +`TO_DT` + +*Syntax* + +[source,esql] +---- +TO_DATETIME(v) +---- + +*Parameters* + +`v`:: +Input value. The input can be a single- or multi-valued column or an expression. + +*Description* + +Converts an input value to a date value. A string will only be successfully converted if it's respecting the format -`yyyy-MM-dd'T'HH:mm:ss.SSS'Z'` (to convert dates in other formats, use <>). For example: +`yyyy-MM-dd'T'HH:mm:ss.SSS'Z'`. To convert dates in other formats, use +<>. + +*Supported types* + +The input type must be of a string or numeric type. + +*Examples* [source.merge.styled,esql] ---- @@ -30,10 +53,8 @@ A following header will contain the failure reason and the offending value: `"java.lang.IllegalArgumentException: failed to parse date field [1964-06-02 00:00:00] with format [yyyy-MM-dd'T'HH:mm:ss.SSS'Z']"` - If the input parameter is of a numeric type, its value will be interpreted as -milliseconds since the https://en.wikipedia.org/wiki/Unix_time[Unix epoch]. -For example: +milliseconds since the {wikipedia}/Unix_time[Unix epoch]. For example: [source.merge.styled,esql] ---- @@ -43,5 +64,3 @@ include::{esql-specs}/date.csv-spec[tag=to_datetime-int] |=== include::{esql-specs}/date.csv-spec[tag=to_datetime-int-result] |=== - -Alias: TO_DT diff --git a/docs/reference/esql/functions/to_degrees.asciidoc b/docs/reference/esql/functions/to_degrees.asciidoc index 71b480253fe35..7b0846c9a4c3f 100644 --- a/docs/reference/esql/functions/to_degrees.asciidoc +++ b/docs/reference/esql/functions/to_degrees.asciidoc @@ -1,13 +1,29 @@ [discrete] [[esql-to_degrees]] === `TO_DEGREES` -Converts a number in https://en.wikipedia.org/wiki/Radian[radians] -to https://en.wikipedia.org/wiki/Degree_(angle)[degrees]. -The input can be a single- or multi-valued field or an expression. The input -type must be of a numeric type and result is always `double`. +*Syntax* -Example: +[source,esql] +---- +TO_DEGREES(v) +---- + +*Parameters* + +`v`:: +Input value. The input can be a single- or multi-valued column or an expression. + +*Description* + +Converts a number in {wikipedia}/Radian[radians] to +{wikipedia}/Degree_(angle)[degrees]. + +*Supported types* + +The input type must be of a numeric type and result is always `double`. + +*Example* [source.merge.styled,esql] ---- diff --git a/docs/reference/esql/functions/to_double.asciidoc b/docs/reference/esql/functions/to_double.asciidoc index 27ad84e4c7762..5d372d6c77c39 100644 --- a/docs/reference/esql/functions/to_double.asciidoc +++ b/docs/reference/esql/functions/to_double.asciidoc @@ -1,12 +1,37 @@ [discrete] [[esql-to_double]] === `TO_DOUBLE` + +*Alias* + +`TO_DBL` + +*Syntax* + +[source,esql] +---- +TO_DOUBLE(v) +---- + +*Parameters* + +`v`:: +Input value. The input can be a single- or multi-valued column or an expression. + +*Description* + Converts an input value to a double value. -The input can be a single- or multi-valued field or an expression. The input -type must be of a boolean, date, string or numeric type. +If the input parameter is of a date type, its value will be interpreted as +milliseconds since the {wikipedia}/Unix_time[Unix epoch], converted to double. -Example: +Boolean *true* will be converted to double *1.0*, *false* to *0.0*. + +*Supported types* + +The input type must be of a boolean, date, string or numeric type. + +*Example* [source.merge.styled,esql] ---- @@ -17,22 +42,13 @@ include::{esql-specs}/floats.csv-spec[tag=to_double-str] include::{esql-specs}/floats.csv-spec[tag=to_double-str-result] |=== -Note that in this example, the last conversion of the string isn't -possible. When this happens, the result is a *null* value. In this case a -_Warning_ header is added to the response. The header will provide information -on the source of the failure: +Note that in this example, the last conversion of the string isn't possible. +When this happens, the result is a *null* value. In this case a _Warning_ header +is added to the response. The header will provide information on the source of +the failure: `"Line 1:115: evaluation of [TO_DOUBLE(str2)] failed, treating result as null. Only first 20 failures recorded."` A following header will contain the failure reason and the offending value: `"java.lang.NumberFormatException: For input string: \"foo\""` - - -If the input parameter is of a date type, its value will be interpreted as -milliseconds since the https://en.wikipedia.org/wiki/Unix_time[Unix epoch], -converted to double. - -Boolean *true* will be converted to double *1.0*, *false* to *0.0*. - -Alias: TO_DBL diff --git a/docs/reference/esql/functions/to_geopoint.asciidoc b/docs/reference/esql/functions/to_geopoint.asciidoc index fc29ea7869ce7..d4d7d397d8f7b 100644 --- a/docs/reference/esql/functions/to_geopoint.asciidoc +++ b/docs/reference/esql/functions/to_geopoint.asciidoc @@ -1,13 +1,32 @@ [discrete] [[esql-to_geopoint]] === `TO_GEOPOINT` -Converts an input value to a `geo_point` value. -The input can be a single- or multi-valued field or an expression. +*Syntax* + +[source,esql] +---- +TO_GEOPOINT(v) +---- + +*Parameters* + +`v`:: +Input value. The input can be a single- or multi-valued column or an expression. The input type must be a string or a `geo_point`. +*Description* + +Converts an input value to a `geo_point` value. + +*Supported types* + +include::types/to_geopoint.asciidoc[] + A string will only be successfully converted if it respects the -https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry[WKT Point] format: +{wikipedia}/Well-known_text_representation_of_geometry[WKT Point] format. + +*Example* [source.merge.styled,esql] ---- @@ -17,7 +36,3 @@ include::{esql-specs}/spatial.csv-spec[tag=to_geopoint-str] |=== include::{esql-specs}/spatial.csv-spec[tag=to_geopoint-str-result] |=== - -Supported types: - -include::types/to_geopoint.asciidoc[] diff --git a/docs/reference/esql/functions/to_geoshape.asciidoc b/docs/reference/esql/functions/to_geoshape.asciidoc index 8d489cce77fa5..7f87d1d46579c 100644 --- a/docs/reference/esql/functions/to_geoshape.asciidoc +++ b/docs/reference/esql/functions/to_geoshape.asciidoc @@ -1,13 +1,32 @@ [discrete] [[esql-to_geoshape]] === `TO_GEOSHAPE` -Converts an input value to a `geo_point` value. -The input can be a single- or multi-valued field or an expression. -The input type must be a string or a `geo_point`. +*Syntax* + +[source,esql] +---- +TO_GEOPOINT(v) +---- + +*Parameters* + +`v`:: +Input value. The input can be a single- or multi-valued column or an expression. +The input type must be a string or a `geo_shape`. + +*Description* + +Converts an input value to a `geo_shape` value. A string will only be successfully converted if it respects the -https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry[WKT] format: +{wikipedia}/Well-known_text_representation_of_geometry[WKT] format. + +*Supported types* + +include::types/to_geoshape.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -17,7 +36,3 @@ include::{esql-specs}/spatial_shapes.csv-spec[tag=to_geoshape-str] |=== include::{esql-specs}/spatial_shapes.csv-spec[tag=to_geoshape-str-result] |=== - -Supported types: - -include::types/to_geoshape.asciidoc[] diff --git a/docs/reference/esql/functions/to_integer.asciidoc b/docs/reference/esql/functions/to_integer.asciidoc index e62256930c5aa..f07bdcd231e40 100644 --- a/docs/reference/esql/functions/to_integer.asciidoc +++ b/docs/reference/esql/functions/to_integer.asciidoc @@ -1,12 +1,37 @@ [discrete] [[esql-to_integer]] === `TO_INTEGER` + +*Alias* + +`TO_INT` + +*Syntax* + +[source,esql] +---- +TO_INTEGER(v) +---- + +*Parameters* + +`v`:: +Input value. The input can be a single- or multi-valued column or an expression. + +*Description* + Converts an input value to an integer value. -The input can be a single- or multi-valued field or an expression. The input -type must be of a boolean, date, string or numeric type. +If the input parameter is of a date type, its value will be interpreted as +milliseconds since the {wikipedia}/Unix_time[Unix epoch], converted to integer. -Example: +Boolean *true* will be converted to integer *1*, *false* to *0*. + +*Supported types* + +The input type must be of a boolean, date, string or numeric type. + +*Example* [source.merge.styled,esql] ---- @@ -27,12 +52,3 @@ provide information on the source of the failure: A following header will contain the failure reason and the offending value: `"org.elasticsearch.xpack.ql.InvalidArgumentException: [501379200000] out of [integer] range"` - - -If the input parameter is of a date type, its value will be interpreted as -milliseconds since the https://en.wikipedia.org/wiki/Unix_time[Unix epoch], -converted to integer. - -Boolean *true* will be converted to integer *1*, *false* to *0*. - -Alias: TO_INT diff --git a/docs/reference/esql/functions/to_ip.asciidoc b/docs/reference/esql/functions/to_ip.asciidoc index dea147eba1a41..28e98ea69c305 100644 --- a/docs/reference/esql/functions/to_ip.asciidoc +++ b/docs/reference/esql/functions/to_ip.asciidoc @@ -1,11 +1,24 @@ [discrete] [[esql-to_ip]] === `TO_IP` -Converts an input string to an IP value. -The input can be a single- or multi-valued field or an expression. +*Syntax* + +[source,esql] +---- +TO_IP(v) +---- + +*Parameters* + +`v`:: +Input value. The input can be a single- or multi-valued column or an expression. + +*Description* + +Converts an input string to an IP value. -Example: +*Example* [source.merge.styled,esql] ---- @@ -16,10 +29,10 @@ include::{esql-specs}/ip.csv-spec[tag=to_ip] include::{esql-specs}/ip.csv-spec[tag=to_ip-result] |=== -Note that in the example above the last conversion of the string isn't -possible. When this happens, the result is a *null* value. In this case a -_Warning_ header is added to the response. The header will provide information -on the source of the failure: +Note that in this example, the last conversion of the string isn't possible. +When this happens, the result is a *null* value. In this case a _Warning_ header +is added to the response. The header will provide information on the source of +the failure: `"Line 1:68: evaluation of [TO_IP(str2)] failed, treating result as null. Only first 20 failures recorded."` diff --git a/docs/reference/esql/functions/to_long.asciidoc b/docs/reference/esql/functions/to_long.asciidoc index 9501c28a31657..04b2e3980a07d 100644 --- a/docs/reference/esql/functions/to_long.asciidoc +++ b/docs/reference/esql/functions/to_long.asciidoc @@ -1,12 +1,33 @@ [discrete] [[esql-to_long]] === `TO_LONG` + +*Syntax* + +[source,esql] +---- +TO_LONG(v) +---- + +*Parameters* + +`v`:: +Input value. The input can be a single- or multi-valued column or an expression. + +*Description* + Converts an input value to a long value. -The input can be a single- or multi-valued field or an expression. The input -type must be of a boolean, date, string or numeric type. +If the input parameter is of a date type, its value will be interpreted as +milliseconds since the {wikipedia}/Unix_time[Unix epoch], converted to long. + +Boolean *true* will be converted to long *1*, *false* to *0*. + +*Supported types* -Example: +The input type must be of a boolean, date, string or numeric type. + +*Example* [source.merge.styled,esql] ---- @@ -27,10 +48,3 @@ on the source of the failure: A following header will contain the failure reason and the offending value: `"java.lang.NumberFormatException: For input string: \"foo\""` - - -If the input parameter is of a date type, its value will be interpreted as -milliseconds since the https://en.wikipedia.org/wiki/Unix_time[Unix epoch], -converted to long. - -Boolean *true* will be converted to long *1*, *false* to *0*. diff --git a/docs/reference/esql/functions/to_lower.asciidoc b/docs/reference/esql/functions/to_lower.asciidoc index 3d55e39e7c1ca..5b98d82c9a94f 100644 --- a/docs/reference/esql/functions/to_lower.asciidoc +++ b/docs/reference/esql/functions/to_lower.asciidoc @@ -1,10 +1,26 @@ [discrete] [[esql-to_lower]] === `TO_LOWER` + +*Syntax* + [.text-center] image::esql/functions/signature/to_lower.svg[Embedded,opts=inline] -Returns a new string representing the input string converted to lower case +*Parameters* + +`str`:: +String expression. If `null`, the function returns `null`. + +*Description* + +Returns a new string representing the input string converted to lower case. + +*Supported types* + +include::types/to_lower.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -14,7 +30,3 @@ include::{esql-specs}/string.csv-spec[tag=to_lower] |=== include::{esql-specs}/string.csv-spec[tag=to_lower-result] |=== - -Supported types: - -include::types/to_lower.asciidoc[] diff --git a/docs/reference/esql/functions/to_radians.asciidoc b/docs/reference/esql/functions/to_radians.asciidoc index 1f86f1fb983cc..f3b1fbd1f3794 100644 --- a/docs/reference/esql/functions/to_radians.asciidoc +++ b/docs/reference/esql/functions/to_radians.asciidoc @@ -1,13 +1,29 @@ [discrete] [[esql-to_radians]] === `TO_RADIANS` -Converts a number in https://en.wikipedia.org/wiki/Degree_(angle)[degrees] to -https://en.wikipedia.org/wiki/Radian[radians]. -The input can be a single- or multi-valued field or an expression. The input -type must be of a numeric type and result is always `double`. +*Syntax* -Example: +[source,esql] +---- +TO_RADIANS(v) +---- + +*Parameters* + +`v`:: +Input value. The input can be a single- or multi-valued column or an expression. + +*Description* + +Converts a number in {wikipedia}/Degree_(angle)[degrees] to +{wikipedia}/Radian[radians]. + +*Supported types* + +The input type must be of a numeric type and result is always `double`. + +*Example* [source.merge.styled,esql] ---- diff --git a/docs/reference/esql/functions/to_string.asciidoc b/docs/reference/esql/functions/to_string.asciidoc index d03b6511b8de5..e771915977d97 100644 --- a/docs/reference/esql/functions/to_string.asciidoc +++ b/docs/reference/esql/functions/to_string.asciidoc @@ -1,10 +1,28 @@ [discrete] [[esql-to_string]] === `TO_STRING` + +*Alias* + +`TO_STR` + [.text-center] image::esql/functions/signature/to_string.svg[Embedded,opts=inline] -Converts a field into a string. For example: +*Parameters* + +`v`:: +Input value. The input can be a single- or multi-valued column or an expression. + +*Description* + +Converts an input value into a string. + +*Supported types* + +include::types/to_string.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -25,9 +43,3 @@ include::{esql-specs}/string.csv-spec[tag=to_string_multivalue] |=== include::{esql-specs}/string.csv-spec[tag=to_string_multivalue-result] |=== - -Alias: TO_STR - -Supported types: - -include::types/to_string.asciidoc[] diff --git a/docs/reference/esql/functions/to_unsigned_long.asciidoc b/docs/reference/esql/functions/to_unsigned_long.asciidoc index af3ff05bf055c..a4a6cfd54ed6f 100644 --- a/docs/reference/esql/functions/to_unsigned_long.asciidoc +++ b/docs/reference/esql/functions/to_unsigned_long.asciidoc @@ -1,12 +1,38 @@ [discrete] [[esql-to_unsigned_long]] === `TO_UNSIGNED_LONG` + +*Aliases* + +`TO_ULONG`, `TO_UL` + +*Syntax* + +[source,esql] +---- +TO_UNSIGNED_LONG(v) +---- + +*Parameters* + +`v`:: +Input value. The input can be a single- or multi-valued column or an expression. + +*Description* + Converts an input value to an unsigned long value. -The input can be a single- or multi-valued field or an expression. The input -type must be of a boolean, date, string or numeric type. +*Supported types* -Example: +The input type must be of a boolean, date, string or numeric type. + +If the input parameter is of a date type, its value will be interpreted as +milliseconds since the {wikipedia}/Unix_time[Unix epoch], converted to unsigned +long. + +Boolean *true* will be converted to unsigned long *1*, *false* to *0*. + +*Example* [source.merge.styled,esql] ---- @@ -27,12 +53,3 @@ on the source of the failure: A following header will contain the failure reason and the offending value: `"java.lang.NumberFormatException: Character f is neither a decimal digit number, decimal point, nor \"e\" notation exponential mark."` - - -If the input parameter is of a date type, its value will be interpreted as -milliseconds since the https://en.wikipedia.org/wiki/Unix_time[Unix epoch], -converted to unsigned long. - -Boolean *true* will be converted to unsigned long *1*, *false* to *0*. - -Alias: TO_ULONG, TO_UL diff --git a/docs/reference/esql/functions/to_upper.asciidoc b/docs/reference/esql/functions/to_upper.asciidoc index b451cc53d35e8..cea63bcbb4bb0 100644 --- a/docs/reference/esql/functions/to_upper.asciidoc +++ b/docs/reference/esql/functions/to_upper.asciidoc @@ -1,10 +1,26 @@ [discrete] [[esql-to_upper]] === `TO_UPPER` + +*Syntax* + [.text-center] image::esql/functions/signature/to_upper.svg[Embedded,opts=inline] -Returns a new string representing the input string converted to upper case +*Parameters* + +`str`:: +String expression. If `null`, the function returns `null`. + +*Description* + +Returns a new string representing the input string converted to upper case. + +*Supported types* + +include::types/to_upper.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -14,7 +30,3 @@ include::{esql-specs}/string.csv-spec[tag=to_upper] |=== include::{esql-specs}/string.csv-spec[tag=to_upper-result] |=== - -Supported types: - -include::types/to_upper.asciidoc[] diff --git a/docs/reference/esql/functions/to_version.asciidoc b/docs/reference/esql/functions/to_version.asciidoc index 33419233c4788..6a1583889c87f 100644 --- a/docs/reference/esql/functions/to_version.asciidoc +++ b/docs/reference/esql/functions/to_version.asciidoc @@ -1,10 +1,30 @@ [discrete] [[esql-to_version]] === `TO_VERSION` + +*Alias* + +`TO_VER` + +*Syntax* + [.text-center] image::esql/functions/signature/to_version.svg[Embedded,opts=inline] -Converts an input string to a version value. For example: +*Parameters* + +`v`:: +Input value. The input can be a single- or multi-valued column or an expression. + +*Description* + +Converts an input string to a version value. + +*Supported types* + +include::types/to_version.asciidoc[] + +*Example* [source.merge.styled,esql] ---- @@ -14,11 +34,3 @@ include::{esql-specs}/version.csv-spec[tag=to_version] |=== include::{esql-specs}/version.csv-spec[tag=to_version-result] |=== - -The input can be a single- or multi-valued field or an expression. - -Alias: TO_VER - -Supported types: - -include::types/to_version.asciidoc[] diff --git a/docs/reference/esql/functions/trim.asciidoc b/docs/reference/esql/functions/trim.asciidoc index 6ace6118dd757..0b246b7526cd2 100644 --- a/docs/reference/esql/functions/trim.asciidoc +++ b/docs/reference/esql/functions/trim.asciidoc @@ -1,11 +1,27 @@ [discrete] [[esql-trim]] === `TRIM` + +*Syntax* + [.text-center] image::esql/functions/signature/trim.svg[Embedded,opts=inline] +*Parameters* + +`str`:: +String expression. If `null`, the function returns `null`. + +*Description* + Removes leading and trailing whitespaces from strings. +*Supported types* + +include::types/trim.asciidoc[] + +*Example* + [source.merge.styled,esql] ---- include::{esql-specs}/string.csv-spec[tag=trim] @@ -14,7 +30,3 @@ include::{esql-specs}/string.csv-spec[tag=trim] |=== include::{esql-specs}/string.csv-spec[tag=trim-result] |=== - -Supported types: - -include::types/trim.asciidoc[] diff --git a/docs/reference/esql/processing-commands/where.asciidoc b/docs/reference/esql/processing-commands/where.asciidoc index 973b163b08b10..3076f92c40fc0 100644 --- a/docs/reference/esql/processing-commands/where.asciidoc +++ b/docs/reference/esql/processing-commands/where.asciidoc @@ -33,6 +33,14 @@ Which, if `still_hired` is a boolean field, can be simplified to: include::{esql-specs}/docs.csv-spec[tag=whereBoolean] ---- +Use date math to retrieve data from a specific time range. For example, to +retrieve the last hour of logs: + +[source,esql] +---- +include::{esql-specs}/date.csv-spec[tag=docsNowWhere] +---- + `WHERE` supports various <>. For example the <> function: diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date.csv-spec index 8dd9704fd2d4b..770e500024c34 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date.csv-spec @@ -1048,3 +1048,29 @@ hires:long | year:date 1 |1999-01-01T00:00:00.000Z // end::docsDateTruncHistogram-result[] ; + +docsNow +// tag::docsNow[] +ROW current_date = NOW() +// end::docsNow[] +| EVAL y = SUBSTRING(DATE_FORMAT("yyyy", current_date), 0, 2) +| KEEP y +; + +// tag::docsNow-result[] +y:keyword +20 +// end::docsNow-result[] +; + +docsNowWhere +// tag::docsNowWhere[] +FROM sample_data +| WHERE @timestamp > NOW() - 1 hour +// end::docsNowWhere[] +; + +// tag::docsNowWhere-result[] +@timestamp:date | client_ip:ip | event_duration:long | message:keyword +// end::docsNowWhere-result[] +; diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/eval.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/eval.csv-spec index 7a7d2486d97e1..441f6d8a264fe 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/eval.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/eval.csv-spec @@ -262,6 +262,24 @@ FROM sample_data @timestamp:date | client_ip:ip | event_duration:long | message:keyword | duration_ms:double ; +docsLength +// tag::length[] +FROM employees +| KEEP first_name, last_name +| EVAL fn_length = LENGTH(first_name) +// end::length[] +| SORT first_name +| LIMIT 3 +; + +// tag::length-result[] +first_name:keyword | last_name:keyword | fn_length:integer +Alejandro |McAlpine |9 +Amabile |Gomatam |7 +Anneke |Preusig |6 +// end::length-result[] +; + docsGettingStartedEvalNoColumnName // tag::gs-eval-no-column-name[] FROM sample_data From 3fb2893e8e1808cf1daf8d439592c6595ba5e96f Mon Sep 17 00:00:00 2001 From: Nhat Nguyen Date: Thu, 25 Jan 2024 07:37:35 -0800 Subject: [PATCH 32/37] Avoid execute ESQL planning on refresh thread (#104591) A recent report shows that we can perform ESQL planning on the refresh thread pool after waiting for refreshes from search-idle shards. While the planning process is generally lightweight, it may become expensive at times. Therefore, we should fork off the refresh thread pool immediately upon resuming ESQL execution. Another place where we should fork off is after field_caps. I will look into that later. --- docs/changelog/104591.yaml | 5 ++ .../xpack/esql/plugin/ComputeService.java | 82 +++++++++++-------- 2 files changed, 51 insertions(+), 36 deletions(-) create mode 100644 docs/changelog/104591.yaml diff --git a/docs/changelog/104591.yaml b/docs/changelog/104591.yaml new file mode 100644 index 0000000000000..0bd054385753f --- /dev/null +++ b/docs/changelog/104591.yaml @@ -0,0 +1,5 @@ +pr: 104591 +summary: Avoid execute ESQL planning on refresh thread +area: ES|QL +type: bug +issues: [] diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java index 172fc0a3dc5cc..307b17814e142 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java @@ -9,6 +9,7 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionListenerResponseHandler; +import org.elasticsearch.action.ActionRunnable; import org.elasticsearch.action.OriginalIndices; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchShardsGroup; @@ -22,7 +23,6 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.util.BigArrays; -import org.elasticsearch.common.util.concurrent.CountDown; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.compute.data.BlockFactory; import org.elasticsearch.compute.data.Page; @@ -435,51 +435,60 @@ private void acquireSearchContexts( Map aliasFilters, ActionListener> listener ) { + final List targetShards = new ArrayList<>(); try { - List targetShards = new ArrayList<>(); for (ShardId shardId : shardIds) { var indexShard = searchService.getIndicesService().indexServiceSafe(shardId.getIndex()).getShard(shardId.id()); targetShards.add(indexShard); } - if (targetShards.isEmpty()) { - listener.onResponse(List.of()); - return; + } catch (Exception e) { + listener.onFailure(e); + return; + } + final var doAcquire = ActionRunnable.supply(listener, () -> { + final List searchContexts = new ArrayList<>(targetShards.size()); + boolean success = false; + try { + for (IndexShard shard : targetShards) { + var aliasFilter = aliasFilters.getOrDefault(shard.shardId().getIndex(), AliasFilter.EMPTY); + var shardRequest = new ShardSearchRequest( + shard.shardId(), + configuration.absoluteStartedTimeInMillis(), + aliasFilter, + clusterAlias + ); + SearchContext context = searchService.createSearchContext(shardRequest, SearchService.NO_TIMEOUT); + searchContexts.add(context); + } + for (SearchContext searchContext : searchContexts) { + searchContext.preProcess(); + } + success = true; + return searchContexts; + } finally { + if (success == false) { + IOUtils.close(searchContexts); + } + } + }); + final AtomicBoolean waitedForRefreshes = new AtomicBoolean(); + try (RefCountingRunnable refs = new RefCountingRunnable(() -> { + if (waitedForRefreshes.get()) { + esqlExecutor.execute(doAcquire); + } else { + doAcquire.run(); } - CountDown countDown = new CountDown(targetShards.size()); + })) { for (IndexShard targetShard : targetShards) { - targetShard.ensureShardSearchActive(ignored -> { - if (countDown.countDown()) { - ActionListener.completeWith(listener, () -> { - final List searchContexts = new ArrayList<>(targetShards.size()); - boolean success = false; - try { - for (IndexShard shard : targetShards) { - var aliasFilter = aliasFilters.getOrDefault(shard.shardId().getIndex(), AliasFilter.EMPTY); - var shardRequest = new ShardSearchRequest( - shard.shardId(), - configuration.absoluteStartedTimeInMillis(), - aliasFilter, - clusterAlias - ); - SearchContext context = searchService.createSearchContext(shardRequest, SearchService.NO_TIMEOUT); - searchContexts.add(context); - } - for (SearchContext searchContext : searchContexts) { - searchContext.preProcess(); - } - success = true; - return searchContexts; - } finally { - if (success == false) { - IOUtils.close(searchContexts); - } - } - }); + final Releasable ref = refs.acquire(); + targetShard.ensureShardSearchActive(await -> { + try (ref) { + if (await) { + waitedForRefreshes.set(true); + } } }); } - } catch (Exception e) { - listener.onFailure(e); } } @@ -585,6 +594,7 @@ public void messageReceived(DataNodeRequest request, TransportChannel channel, T configuration, request.aliasFilters(), ActionListener.wrap(searchContexts -> { + assert ThreadPool.assertCurrentThreadPool(ESQL_THREAD_POOL_NAME); var computeContext = new ComputeContext(sessionId, clusterAlias, searchContexts, configuration, null, exchangeSink); runCompute(parentTask, computeContext, request.plan(), ActionListener.wrap(driverProfiles -> { // don't return until all pages are fetched From 048fa9385bc5c72411ec1bb3c6dea0cc0f24ce2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20R=C3=BChsen?= Date: Thu, 25 Jan 2024 16:44:22 +0100 Subject: [PATCH 33/37] [Profiling] Refine co2 calculation data (#104628) * Add CO2 data for AWS ap-southeast-3 and me-central-1 * Update CO2 data for GCP including new regions * Update CO2 data for Azure including new/changed regions * Move provider data into CloudProviders.java * Add NOTICE and LICENSE for the provider data * Document CloudProviders' public functions * Add cloudcarbonfootprint-(NOTICE|LICENSE).txt as ignoreFile --------- Co-authored-by: Elastic Machine --- x-pack/plugin/profiling/build.gradle | 4 + .../licenses/cloudcarbonfootprint-LICENSE.txt | 201 ++++++++++++++ .../licenses/cloudcarbonfootprint-NOTICE.txt | 6 + .../xpack/profiling/CO2Calculator.java | 146 +---------- .../xpack/profiling/CloudProviders.java | 247 ++++++++++++++++++ .../xpack/profiling/CO2CalculatorTests.java | 2 +- 6 files changed, 461 insertions(+), 145 deletions(-) create mode 100644 x-pack/plugin/profiling/licenses/cloudcarbonfootprint-LICENSE.txt create mode 100644 x-pack/plugin/profiling/licenses/cloudcarbonfootprint-NOTICE.txt create mode 100644 x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/CloudProviders.java diff --git a/x-pack/plugin/profiling/build.gradle b/x-pack/plugin/profiling/build.gradle index 8275bfe633c91..3790fb6e762aa 100644 --- a/x-pack/plugin/profiling/build.gradle +++ b/x-pack/plugin/profiling/build.gradle @@ -24,3 +24,7 @@ dependencies { testImplementation project(path: xpackModule('ilm')) testImplementation project(':modules:data-streams') } +tasks.named("dependencyLicenses").configure { + ignoreFile 'cloudcarbonfootprint-LICENSE.txt' + ignoreFile 'cloudcarbonfootprint-NOTICE.txt' +} diff --git a/x-pack/plugin/profiling/licenses/cloudcarbonfootprint-LICENSE.txt b/x-pack/plugin/profiling/licenses/cloudcarbonfootprint-LICENSE.txt new file mode 100644 index 0000000000000..b46d5a742382d --- /dev/null +++ b/x-pack/plugin/profiling/licenses/cloudcarbonfootprint-LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2021 Thoughtworks Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/x-pack/plugin/profiling/licenses/cloudcarbonfootprint-NOTICE.txt b/x-pack/plugin/profiling/licenses/cloudcarbonfootprint-NOTICE.txt new file mode 100644 index 0000000000000..44eaf62f3b2c9 --- /dev/null +++ b/x-pack/plugin/profiling/licenses/cloudcarbonfootprint-NOTICE.txt @@ -0,0 +1,6 @@ +For CO2 calculations, we include and use data from +https://github.com/PaoloFrigo/cloud-carbon-footprint . + +License: Apache 2.0 + +Copyright: Cloud Carbon Footprint, (C) 2021 Thoughtworks, Inc. diff --git a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/CO2Calculator.java b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/CO2Calculator.java index 4013afd2002f2..454cd35b396b9 100644 --- a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/CO2Calculator.java +++ b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/CO2Calculator.java @@ -9,8 +9,6 @@ import java.util.Map; -import static java.util.Map.entry; - final class CO2Calculator { private static final double DEFAULT_SAMPLING_FREQUENCY = 20.0d; private static final double DEFAULT_CO2_TONS_PER_KWH = 0.000379069d; // unit: metric tons / kWh @@ -66,150 +64,10 @@ private double getKiloWattsPerCore(HostMetadata host) { } private double getCO2TonsPerKWH(HostMetadata host) { - Provider provider = PROVIDERS.get(host.instanceType.provider); - return provider == null ? customCO2PerKWH : provider.co2TonsPerKWH.getOrDefault(host.instanceType.region, customCO2PerKWH); + return CloudProviders.getCO2TonsPerKWHOrDefault(host.instanceType.provider, host.instanceType.region, customCO2PerKWH); } private double getDatacenterPUE(HostMetadata host) { - Provider provider = PROVIDERS.get(host.instanceType.provider); - return provider == null ? customDatacenterPUE : provider.pue; - } - - private record Provider(double pue, Map co2TonsPerKWH) {} - - // values are taken from https://www.cloudcarbonfootprint.org/docs/methodology/ - private static final Map PROVIDERS; - static { - // noinspection (explicit type arguments speedup compilation and analysis time) - PROVIDERS = Map.of( - "aws", - new Provider( - 1.135d, - Map.ofEntries( - entry("us-east-1", 0.000379069d), - entry("us-east-2", 0.000410608d), - entry("us-west-1", 0.000322167d), - entry("us-west-2", 0.000322167d), - entry("us-gov-east-1", 0.000379069d), - entry("us-gov-west-1", 0.000322167d), - entry("af-south-1", 0.0009006d), - entry("ap-east-1", 0.00071d), - entry("ap-south-1", 0.0007082d), - entry("ap-northeast-3", 0.0004658d), - entry("ap-northeast-2", 0.0004156d), - entry("ap-southeast-1", 0.000408d), - entry("ap-southeast-2", 0.00076d), - entry("ap-northeast-1", 0.0004658d), - entry("ca-central-1", 0.00012d), - entry("cn-north-1", 0.0005374d), - entry("cn-northwest-1", 0.0005374d), - entry("eu-central-1", 0.000311d), - entry("eu-west-1", 0.0002786d), - entry("eu-west-2", 0.000225d), - entry("eu-south-1", 0.0002134d), - entry("eu-west-3", 0.0000511d), - entry("eu-north-1", 0.0000088d), - entry("me-south-1", 0.0005059d), - entry("sa-east-1", 0.0000617d) - ) - ), - // noinspection (explicit type arguments speedup compilation and analysis time) - "gcp", - new Provider( - 1.1d, - Map.ofEntries( - entry("us-central1", 0.00003178d), - entry("us-east1", 0.0003504d), - entry("us-east4", 0.00015162d), - entry("us-west1", 0.0000078d), - entry("us-west2", 0.00011638d), - entry("us-west3", 0.00038376d), - entry("us-west4", 0.00036855d), - entry("asia-east1", 0.0004428d), - entry("asia-east2", 0.000453d), - entry("asia-northeast1", 0.00048752d), - entry("asia-northeast2", 0.00048752d), - entry("asia-northeast3", 0.00031533d), - entry("asia-south1", 0.00063448d), - entry("asia-south2", 0.000657d), - entry("asia-southeast1", 0.00047328d), - entry("asia-southeast2", 0.000647d), - entry("australia-southeast1", 0.00064703d), - entry("australia-southeast2", 0.000691d), - entry("europe-central2", 0.000622d), - entry("europe-north1", 0.00000798d), - entry("europe-west1", 0.00004452d), - entry("europe-west2", 0.00009471d), - entry("europe-west3", 0.000108), - entry("europe-west4", 0.000164d), - entry("europe-west6", 0.000087d), - entry("northamerica-northeast1", 0.000027d), - entry("southamerica-east1", 0.00001236d) - ) - ), - "azure", - new Provider( - 1.185d, - Map.ofEntries( - entry("centralus", 0.000426254d), - entry("eastus", 0.000379069d), - entry("eastus2", 0.000379069d), - entry("eastus3", 0.000379069d), - entry("northcentralus", 0.000410608d), - entry("southcentralus", 0.000373231d), - entry("westcentralusS", 0.000322167d), - entry("westus", 0.000322167d), - entry("westus2", 0.000322167d), - entry("westus3", 0.000322167d), - entry("eastasia", 0.00071d), - entry("southeastasia", 0.000408d), - entry("southafricanorth", 0.0009006d), - entry("southafricawest", 0.0009006d), - entry("southafrica", 0.0009006d), - entry("australia", 0.00079d), - entry("australiacentral", 0.00079d), - entry("australiacentral2", 0.00079d), - entry("australiaeast", 0.00079d), - entry("australiasoutheast", 0.00096d), - entry("japan", 0.0004658d), - entry("japanwest", 0.0004658d), - entry("japaneast", 0.0004658d), - entry("korea", 0.0004156d), - entry("koreaeast", 0.0004156d), - entry("koreasouth", 0.0004156d), - entry("india", 0.0007082d), - entry("indiawest", 0.0007082d), - entry("indiacentral", 0.0007082d), - entry("indiasouth", 0.0007082d), - entry("northeurope", 0.0002786d), - entry("westeurope", 0.0003284d), - entry("france", 0.00005128d), - entry("francecentral", 0.00005128d), - entry("francesouth", 0.00005128d), - entry("swedencentral", 0.00000567d), - entry("switzerland", 0.00000567d), - entry("switzerlandnorth", 0.00000567d), - entry("switzerlandwest", 0.00000567d), - entry("uk", 0.000225d), - entry("uksouth", 0.000225d), - entry("ukwest", 0.000228d), - entry("germany", 0.00033866d), - entry("germanynorth", 0.00033866d), - entry("germanywestcentral", 0.00033866d), - entry("norway", 0.00000762d), - entry("norwayeast", 0.00000762d), - entry("norwaywest", 0.00000762d), - entry("unitedarabemirates", 0.0004041d), - entry("unitedarabemiratesnorth", 0.0004041d), - entry("unitedarabemiratescentral", 0.0004041d), - entry("canada", 0.00012d), - entry("canadacentral", 0.00012d), - entry("canadaeast", 0.00012d), - entry("brazil", 0.0000617d), - entry("brazilsouth", 0.0000617d), - entry("brazilsoutheast", 0.0000617d) - ) - ) - ); + return CloudProviders.getPUEOrDefault(host.instanceType.provider, customDatacenterPUE); } } diff --git a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/CloudProviders.java b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/CloudProviders.java new file mode 100644 index 0000000000000..0245df13f8fad --- /dev/null +++ b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/CloudProviders.java @@ -0,0 +1,247 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.profiling; + +import java.util.Map; + +import static java.util.Map.entry; + +final class CloudProviders { + private CloudProviders() { + // no instances intended + } + + public record Provider(double pue, Map co2TonsPerKWH) {} + + private static Provider getProvider(String providerName) { + return PROVIDERS.get(providerName); + } + + /** + * Returns the PUE for the given provider, or the default value if the provider is unknown. + * PUE stands for Power Usage Effectiveness, and is a measure of how much power is used by + * the datacenter infrastructure (cooling, lighting, etc.) vs. the IT equipment (servers, etc.). + * A PUE of 1.0 means that all power is used by the IT equipment, and a PUE of 2.0 means that + * half of the power is used by the IT equipment and half is used by the infrastructure. + * See also https://en.wikipedia.org/wiki/Power_usage_effectiveness . + * + * @param providerName The name of the provider. + * Currently supported providers are "aws", "gcp", and "azure". + * If the provider is unknown, the default value is returned. + * @param defaultPUEValue The default value to return if the provider is unknown. + * @return The PUE for the given provider, or the default value if the provider is unknown. + */ + public static double getPUEOrDefault(String providerName, double defaultPUEValue) { + Provider provider = getProvider(providerName); + if (provider == null) { + return defaultPUEValue; + } + return provider.pue; + } + + /** + * Returns the CO2 emission factor for the given provider and region, or the default value if + * the provider or region is unknown. The CO2 emission factor is the amount of CO2 emitted per + * kWh of electricity consumed and measured in metric tons. + * + * @param providerName The name of the provider. + * Currently supported providers are "aws", "gcp", and "azure". + * If the provider is unknown, the default value is returned. + * @param region The name of the region. + * If the region is unknown, the default value is returned. + * @param defaultCO2Value The default value to return if the provider or region is unknown. + * @return The CO2 emission factor for the given provider and region, or the default value if + * the provider or region is unknown. + */ + public static double getCO2TonsPerKWHOrDefault(String providerName, String region, double defaultCO2Value) { + Provider provider = getProvider(providerName); + if (provider == null) { + return defaultCO2Value; + } + return provider.co2TonsPerKWH.getOrDefault(region, defaultCO2Value); + } + + // The following data taken from https://www.cloudcarbonfootprint.org/docs/methodology/ + // and updated from https://github.com/PaoloFrigo/cloud-carbon-footprint . + // License: Apache 2.0 + // Copyright: Cloud Carbon Footprint, (C) 2021 Thoughtworks, Inc. + private static final Map PROVIDERS; + static { + // noinspection (explicit type arguments speedup compilation and analysis time) + PROVIDERS = Map.of( + "aws", + new Provider( + 1.135d, + Map.ofEntries( + entry("us-east-1", 0.000379069d), + entry("us-east-2", 0.000410608d), + entry("us-west-1", 0.000322167d), + entry("us-west-2", 0.000322167d), + entry("us-gov-east-1", 0.000379069d), + entry("us-gov-west-1", 0.000322167d), + entry("af-south-1", 0.0009006d), + entry("ap-east-1", 0.00071d), + entry("ap-south-1", 0.0007082d), + entry("ap-northeast-3", 0.0004658d), + entry("ap-northeast-2", 0.0004156d), + entry("ap-southeast-1", 0.000408d), + entry("ap-southeast-2", 0.00076d), + entry("ap-southeast-3", 0.0007177d), + entry("ap-northeast-1", 0.0004658d), + entry("ca-central-1", 0.00012d), + entry("cn-north-1", 0.0005374d), + entry("cn-northwest-1", 0.0005374d), + entry("eu-central-1", 0.000311d), + entry("eu-west-1", 0.0002786d), + entry("eu-west-2", 0.000225d), + entry("eu-south-1", 0.0002134d), + entry("eu-west-3", 0.0000511d), + entry("eu-north-1", 0.0000088d), + entry("me-south-1", 0.0005059d), + entry("me-central-1", 0.0004041), + entry("sa-east-1", 0.0000617d) + ) + ), + // noinspection (explicit type arguments speedup compilation and analysis time) + "gcp", + new Provider( + 1.1d, + // These emission factors take into account Google Carbon Free Energy percentage in each region. + // Source: https://cloud.google.com/sustainability/region-carbon + Map.ofEntries( + entry("us-central1", 0.0002152373529d), + entry("us-central2", 0.0002152373529d), + entry("us-east1", 0.0003255d), + entry("us-east4", 0.00011124d), + entry("us-east5", 0.00011124d), + entry("us-west1", 0.0000072d), + entry("us-west2", 0.0000893d), + entry("us-west3", 0.00030912d), + entry("us-west4", 0.00028835d), + entry("us-south1", 0.0001776d), + entry("asia-east1", 0.00037848d), + entry("asia-east2", 0.0002592d), + entry("asia-northeast1", 0.00038976d), + entry("asia-northeast2", 0.00026496d), + entry("asia-northeast3", 0.00029325d), + entry("asia-south1", 0.000603d), + entry("asia-south2", 0.00061732d), + entry("asia-southeast1", 0.00035712d), + entry("asia-southeast2", 0.0005046d), + entry("australia-southeast1", 0.00047242d), + entry("australia-southeast2", 0.00035949d), + entry("europe-central2", 0.0004608d), + entry("europe-north1", 0.00001143d), + entry("europe-southwest1", 0.000121d), + entry("europe-west1", 0.0000198d), + entry("europe-west2", 0.00007396d), + entry("europe-west3", 0.0001076), + entry("europe-west4", 0.00013301d), + entry("europe-west6", 0.0000129d), + entry("europe-west8", 0.000298d), + entry("europe-west9", 0.000059d), + entry("northamerica-northeast1", 0d), // Montreal is 100% CFE + entry("northamerica-northeast2", 0.00000232d), + entry("southamerica-east1", 0.00002838d), + entry("southamerica-west1", 0.0000589d) + ) + ), + "azure", + new Provider( + 1.185d, + Map.ofEntries( + entry("centralus", 0.000426254d), + entry("centraluseuap", 0.000426254d), + entry("centralusestage", 0.000426254d), + entry("eastus", 0.000379069d), + entry("useast", 0.000379069d), + entry("eastusstage", 0.000379069d), + entry("eastus2", 0.000379069d), + entry("useast2", 0.000379069d), + entry("eastus2euap", 0.000379069d), + entry("eastus2stage", 0.000379069d), + entry("eastus3", 0.000379069d), + entry("usnorth", 0.000410608d), + entry("northcentralus", 0.000410608d), + entry("northcentralusstage", 0.000410608d), + entry("southcentralus", 0.000373231d), + entry("southcentralusstage", 0.000373231d), + entry("unitedstates", 0.000373231d), + entry("unitedstateseuap", 0.000373231d), + entry("westcentralus", 0.000322167d), + entry("westcentralusstage", 0.000322167d), + entry("westus", 0.000322167d), + entry("westusstage", 0.000322167d), + entry("westus2", 0.000322167d), + entry("westus2stage", 0.000322167d), + entry("westus3", 0.000322167d), + entry("asia", 0.0005647d), + entry("asiapacific", 0.0005647d), + entry("eastasia", 0.00071d), + entry("eastasiastage", 0.00071d), + entry("southeastasia", 0.000408d), + entry("asiasoutheast", 0.000408d), + entry("southafricanorth", 0.0009006d), + entry("southafricawest", 0.0009006d), + entry("southafrica", 0.0009006d), + entry("australia", 0.00079d), + entry("australiacentral", 0.00079d), + entry("australiacentral2", 0.00079d), + entry("australiaeast", 0.00079d), + entry("australiasoutheast", 0.00096d), + entry("apeast", 0.00071d), + entry("apsoutheast", 0.000408d), + entry("japan", 0.0004658d), + entry("japanwest", 0.0004658d), + entry("japaneast", 0.0004658d), + entry("korea", 0.0004156d), + entry("koreaeast", 0.0004156d), + entry("koreasouth", 0.0004156d), + entry("india", 0.0007082d), + entry("indiacentral", 0.0007082d), + entry("centralindia", 0.0007082d), + entry("jioindiacentral", 0.0007082d), + entry("indiawest", 0.0007082d), + entry("westindia", 0.0007082d), + entry("jioindiawest", 0.0007082d), + entry("indiasouth", 0.0007082d), + entry("southindia", 0.0007082d), + entry("northeurope", 0.0002786d), + entry("europenorth", 0.0002786d), + entry("westeurope", 0.0003284d), + entry("europewest", 0.0003284d), + entry("france", 0.00005128d), + entry("francecentral", 0.00005128d), + entry("francesouth", 0.00005128d), + entry("swedencentral", 0.00000567d), + entry("switzerland", 0.00001152d), + entry("switzerlandnorth", 0.00001152d), + entry("switzerlandwest", 0.00001152d), + entry("uk", 0.000225d), + entry("uksouth", 0.000225d), + entry("ukwest", 0.000228d), + entry("germany", 0.00033866d), + entry("germanynorth", 0.00033866d), + entry("germanywestcentral", 0.00033866d), + entry("norway", 0.00000762d), + entry("norwayeast", 0.00000762d), + entry("norwaywest", 0.00000762d), + entry("uae", 0.0004041d), + entry("uaenorth", 0.0004041d), + entry("uaecentral", 0.0004041d), + entry("canada", 0.00012d), + entry("canadacentral", 0.00012d), + entry("canadaeast", 0.00012d), + entry("brazil", 0.0000617d), + entry("brazilsouth", 0.0000617d), + entry("brazilsoutheast", 0.0000617d) + ) + ) + ); + } +} diff --git a/x-pack/plugin/profiling/src/test/java/org/elasticsearch/xpack/profiling/CO2CalculatorTests.java b/x-pack/plugin/profiling/src/test/java/org/elasticsearch/xpack/profiling/CO2CalculatorTests.java index eb0a2f056044b..96c56daef7d95 100644 --- a/x-pack/plugin/profiling/src/test/java/org/elasticsearch/xpack/profiling/CO2CalculatorTests.java +++ b/x-pack/plugin/profiling/src/test/java/org/elasticsearch/xpack/profiling/CO2CalculatorTests.java @@ -73,7 +73,7 @@ public void testCreateFromRegularSource() { CO2Calculator co2Calculator = new CO2Calculator(hostsTable, samplingDurationInSeconds, null, null, null, null); checkCO2Calculation(co2Calculator.getAnnualCO2Tons(HOST_ID_A, samples), annualCoreHours, 1.135d, 0.0002786d, 7.0d); - checkCO2Calculation(co2Calculator.getAnnualCO2Tons(HOST_ID_B, samples), annualCoreHours, 1.1d, 0.00004452d, 7.0d); + checkCO2Calculation(co2Calculator.getAnnualCO2Tons(HOST_ID_B, samples), annualCoreHours, 1.1d, 0.0000198d, 7.0d); checkCO2Calculation(co2Calculator.getAnnualCO2Tons(HOST_ID_C, samples), annualCoreHours, 1.185d, 0.000410608d, 2.8d); checkCO2Calculation(co2Calculator.getAnnualCO2Tons(HOST_ID_D, samples), annualCoreHours, 1.7d, 0.000379069d, 2.8d); } From fc2bdc2fe31ee8a90ed254828016da5cb71bda28 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Thu, 25 Jan 2024 16:45:01 +0100 Subject: [PATCH 34/37] Build sub aggregation buckets more lazily (#104762) Build these more lazily avoiding putting them in an array and don't keep an accidental reference to the aggregator itself. --- .../adjacency/AdjacencyMatrixAggregator.java | 7 ++- .../bucket/BucketsAggregator.java | 48 +++++++++---------- .../bucket/composite/CompositeAggregator.java | 4 +- .../VariableWidthHistogramAggregator.java | 4 +- .../bucket/prefix/IpPrefixAggregator.java | 5 +- 5 files changed, 33 insertions(+), 35 deletions(-) diff --git a/modules/aggregations/src/main/java/org/elasticsearch/aggregations/bucket/adjacency/AdjacencyMatrixAggregator.java b/modules/aggregations/src/main/java/org/elasticsearch/aggregations/bucket/adjacency/AdjacencyMatrixAggregator.java index 44a79fd6dc104..07a363ed727c7 100644 --- a/modules/aggregations/src/main/java/org/elasticsearch/aggregations/bucket/adjacency/AdjacencyMatrixAggregator.java +++ b/modules/aggregations/src/main/java/org/elasticsearch/aggregations/bucket/adjacency/AdjacencyMatrixAggregator.java @@ -20,7 +20,6 @@ import org.elasticsearch.search.aggregations.AggregatorFactories; import org.elasticsearch.search.aggregations.CardinalityUpperBound; import org.elasticsearch.search.aggregations.InternalAggregation; -import org.elasticsearch.search.aggregations.InternalAggregations; import org.elasticsearch.search.aggregations.LeafBucketCollector; import org.elasticsearch.search.aggregations.LeafBucketCollectorBase; import org.elasticsearch.search.aggregations.bucket.BucketsAggregator; @@ -195,7 +194,7 @@ public InternalAggregation[] buildAggregations(long[] owningBucketOrds) throws I } assert builtBucketIndex == totalBucketsToBuild; builtBucketIndex = 0; - InternalAggregations[] bucketSubAggs = buildSubAggsForBuckets(bucketOrdsToBuild); + var bucketSubAggs = buildSubAggsForBuckets(bucketOrdsToBuild); InternalAggregation[] results = new InternalAggregation[owningBucketOrds.length]; for (int owningBucketOrdIdx = 0; owningBucketOrdIdx < owningBucketOrds.length; owningBucketOrdIdx++) { List buckets = new ArrayList<>(filters.length); @@ -209,7 +208,7 @@ public InternalAggregation[] buildAggregations(long[] owningBucketOrds) throws I InternalAdjacencyMatrix.InternalBucket bucket = new InternalAdjacencyMatrix.InternalBucket( keys[i], docCount, - bucketSubAggs[builtBucketIndex++] + bucketSubAggs.apply(builtBucketIndex++) ); buckets.add(bucket); } @@ -225,7 +224,7 @@ public InternalAggregation[] buildAggregations(long[] owningBucketOrds) throws I InternalAdjacencyMatrix.InternalBucket bucket = new InternalAdjacencyMatrix.InternalBucket( intersectKey, docCount, - bucketSubAggs[builtBucketIndex++] + bucketSubAggs.apply(builtBucketIndex++) ); buckets.add(bucket); } diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/BucketsAggregator.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/BucketsAggregator.java index ec8117cf03135..fc2e7f04f2c59 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/BucketsAggregator.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/BucketsAggregator.java @@ -34,6 +34,7 @@ import java.util.Map; import java.util.function.BiConsumer; import java.util.function.Function; +import java.util.function.IntFunction; import java.util.function.LongUnaryOperator; import java.util.function.ToLongFunction; @@ -172,28 +173,27 @@ protected void prepareSubAggs(long[] ordsToCollect) throws IOException {} * @return the sub-aggregation results in the same order as the provided * array of ordinals */ - protected final InternalAggregations[] buildSubAggsForBuckets(long[] bucketOrdsToCollect) throws IOException { + protected final IntFunction buildSubAggsForBuckets(long[] bucketOrdsToCollect) throws IOException { prepareSubAggs(bucketOrdsToCollect); InternalAggregation[][] aggregations = new InternalAggregation[subAggregators.length][]; for (int i = 0; i < subAggregators.length; i++) { aggregations[i] = subAggregators[i].buildAggregations(bucketOrdsToCollect); } - InternalAggregations[] result = new InternalAggregations[bucketOrdsToCollect.length]; - for (int ord = 0; ord < bucketOrdsToCollect.length; ord++) { - final int thisOrd = ord; - result[ord] = InternalAggregations.from(new AbstractList<>() { - @Override - public InternalAggregation get(int index) { - return aggregations[index][thisOrd]; - } + return subAggsForBucketFunction(aggregations); + } - @Override - public int size() { - return aggregations.length; - } - }); - } - return result; + private static IntFunction subAggsForBucketFunction(InternalAggregation[][] aggregations) { + return ord -> InternalAggregations.from(new AbstractList<>() { + @Override + public InternalAggregation get(int index) { + return aggregations[index][ord]; + } + + @Override + public int size() { + return aggregations.length; + } + }); } /** @@ -221,11 +221,11 @@ protected final void buildSubAggsForAllBuckets( bucketOrdsToCollect[s++] = bucketToOrd.applyAsLong(bucket); } } - InternalAggregations[] results = buildSubAggsForBuckets(bucketOrdsToCollect); + var results = buildSubAggsForBuckets(bucketOrdsToCollect); s = 0; for (B[] bucket : buckets) { for (int b = 0; b < bucket.length; b++) { - setAggs.accept(bucket[b], results[s++]); + setAggs.accept(bucket[b], results.apply(s++)); } } } @@ -254,7 +254,7 @@ protected final InternalAggregation[] buildAggregationsForFixedBucketCount( } } bucketOrdIdx = 0; - InternalAggregations[] subAggregationResults = buildSubAggsForBuckets(bucketOrdsToCollect); + var subAggregationResults = buildSubAggsForBuckets(bucketOrdsToCollect); InternalAggregation[] results = new InternalAggregation[owningBucketOrds.length]; for (int owningOrdIdx = 0; owningOrdIdx < owningBucketOrds.length; owningOrdIdx++) { List buckets = new ArrayList<>(bucketsPerOwningBucketOrd); @@ -263,7 +263,7 @@ protected final InternalAggregation[] buildAggregationsForFixedBucketCount( bucketBuilder.build( offsetInOwningOrd, bucketDocCount(bucketOrdsToCollect[bucketOrdIdx]), - subAggregationResults[bucketOrdIdx++] + subAggregationResults.apply(bucketOrdIdx++) ) ); } @@ -289,10 +289,10 @@ protected final InternalAggregation[] buildAggregationsForSingleBucket(long[] ow * `consumeBucketsAndMaybeBreak(owningBucketOrds.length)` * here but we don't because single bucket aggs never have. */ - InternalAggregations[] subAggregationResults = buildSubAggsForBuckets(owningBucketOrds); + var subAggregationResults = buildSubAggsForBuckets(owningBucketOrds); InternalAggregation[] results = new InternalAggregation[owningBucketOrds.length]; for (int ordIdx = 0; ordIdx < owningBucketOrds.length; ordIdx++) { - results[ordIdx] = resultBuilder.build(owningBucketOrds[ordIdx], subAggregationResults[ordIdx]); + results[ordIdx] = resultBuilder.build(owningBucketOrds[ordIdx], subAggregationResults.apply(ordIdx)); } return results; } @@ -336,7 +336,7 @@ protected final InternalAggregation[] buildAggregationsForVariableBuckets( bucketOrdsToCollect[b++] = ordsEnum.ord(); } } - InternalAggregations[] subAggregationResults = buildSubAggsForBuckets(bucketOrdsToCollect); + var subAggregationResults = buildSubAggsForBuckets(bucketOrdsToCollect); InternalAggregation[] results = new InternalAggregation[owningBucketOrds.length]; b = 0; @@ -352,7 +352,7 @@ protected final InternalAggregation[] buildAggregationsForVariableBuckets( bucketOrdsToCollect[b] ); } - buckets.add(bucketBuilder.build(ordsEnum.value(), bucketDocCount(ordsEnum.ord()), subAggregationResults[b++])); + buckets.add(bucketBuilder.build(ordsEnum.value(), bucketDocCount(ordsEnum.ord()), subAggregationResults.apply(b++))); } results[ordIdx] = resultBuilder.build(owningBucketOrds[ordIdx], buckets); } diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/composite/CompositeAggregator.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/composite/CompositeAggregator.java index 0d088e9406175..e0189c3dd6651 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/composite/CompositeAggregator.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/composite/CompositeAggregator.java @@ -197,11 +197,11 @@ public InternalAggregation[] buildAggregations(long[] owningBucketOrds) throws I for (int i = 0; i < queue.size(); i++) { bucketOrdsToCollect[i] = i; } - InternalAggregations[] subAggsForBuckets = buildSubAggsForBuckets(bucketOrdsToCollect); + var subAggsForBuckets = buildSubAggsForBuckets(bucketOrdsToCollect); while (queue.size() > 0) { int slot = queue.pop(); CompositeKey key = queue.toCompositeKey(slot); - InternalAggregations aggs = subAggsForBuckets[slot]; + InternalAggregations aggs = subAggsForBuckets.apply(slot); long docCount = queue.getDocCount(slot); buckets[queue.size()] = new InternalComposite.InternalBucket( sourceNames, diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/VariableWidthHistogramAggregator.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/VariableWidthHistogramAggregator.java index 945ecd7424de3..55063c0af4010 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/VariableWidthHistogramAggregator.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/VariableWidthHistogramAggregator.java @@ -555,11 +555,11 @@ public InternalAggregation[] buildAggregations(long[] owningBucketOrds) throws I bucketOrdsToCollect[i] = i; } - InternalAggregations[] subAggregationResults = buildSubAggsForBuckets(bucketOrdsToCollect); + var subAggregationResults = buildSubAggsForBuckets(bucketOrdsToCollect); List buckets = new ArrayList<>(numClusters); for (int bucketOrd = 0; bucketOrd < numClusters; bucketOrd++) { - buckets.add(collector.buildBucket(bucketOrd, subAggregationResults[bucketOrd])); + buckets.add(collector.buildBucket(bucketOrd, subAggregationResults.apply(bucketOrd))); } Function, InternalAggregation> resultBuilder = bucketsToFormat -> { diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/prefix/IpPrefixAggregator.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/prefix/IpPrefixAggregator.java index eb8b0f95047b9..ec95052f5c3f5 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/prefix/IpPrefixAggregator.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/prefix/IpPrefixAggregator.java @@ -19,7 +19,6 @@ import org.elasticsearch.search.aggregations.BucketOrder; import org.elasticsearch.search.aggregations.CardinalityUpperBound; import org.elasticsearch.search.aggregations.InternalAggregation; -import org.elasticsearch.search.aggregations.InternalAggregations; import org.elasticsearch.search.aggregations.LeafBucketCollector; import org.elasticsearch.search.aggregations.LeafBucketCollectorBase; import org.elasticsearch.search.aggregations.NonCollectingAggregator; @@ -170,7 +169,7 @@ public InternalAggregation[] buildAggregations(long[] owningBucketOrds) throws I } } - InternalAggregations[] subAggregationResults = buildSubAggsForBuckets(bucketOrdsToCollect); + var subAggregationResults = buildSubAggsForBuckets(bucketOrdsToCollect); InternalAggregation[] results = new InternalAggregation[owningBucketOrds.length]; b = 0; for (int ordIdx = 0; ordIdx < owningBucketOrds.length; ordIdx++) { @@ -193,7 +192,7 @@ public InternalAggregation[] buildAggregations(long[] owningBucketOrds) throws I ipPrefix.prefixLength, ipPrefix.appendPrefixLength, docCount, - subAggregationResults[b++] + subAggregationResults.apply(b++) ) ); From 03c9f89bc17c447ce79a0ba239368432996cfd74 Mon Sep 17 00:00:00 2001 From: David Turner Date: Thu, 25 Jan 2024 17:00:24 +0000 Subject: [PATCH 35/37] Make RestResponse releasable (#104752) On reflection is was probably a mistake to give each `ChunkedRestResponseBody` a nontrivial lifecycle in #99871. The lifecycle really belongs to the whole containing `RestResponse`. This commit moves it there. --- .../Netty4HttpPipeliningHandlerTests.java | 3 - .../Netty4HttpServerTransportTests.java | 2 +- .../http/DefaultRestChannel.java | 4 +- .../rest/ChunkedRestResponseBody.java | 29 ++------ .../rest/LoggingChunkedRestResponseBody.java | 5 -- .../elasticsearch/rest/RestController.java | 11 ++- .../org/elasticsearch/rest/RestResponse.java | 34 ++++++--- .../action/RestChunkedToXContentListener.java | 3 +- .../cluster/RestNodesHotThreadsAction.java | 2 +- .../rest/action/cat/RestTable.java | 12 ++-- .../action/info/RestClusterInfoAction.java | 6 +- .../http/DefaultRestChannelTests.java | 14 +--- .../rest/ChunkedRestResponseBodyTests.java | 69 +++++++------------ .../elasticsearch/rest/RestResponseTests.java | 3 +- .../esql/action/EsqlResponseListener.java | 10 ++- 15 files changed, 78 insertions(+), 129 deletions(-) diff --git a/modules/transport-netty4/src/test/java/org/elasticsearch/http/netty4/Netty4HttpPipeliningHandlerTests.java b/modules/transport-netty4/src/test/java/org/elasticsearch/http/netty4/Netty4HttpPipeliningHandlerTests.java index dd71fb62c1106..05f9f1bbb19f0 100644 --- a/modules/transport-netty4/src/test/java/org/elasticsearch/http/netty4/Netty4HttpPipeliningHandlerTests.java +++ b/modules/transport-netty4/src/test/java/org/elasticsearch/http/netty4/Netty4HttpPipeliningHandlerTests.java @@ -522,9 +522,6 @@ public ReleasableBytesReference encodeChunk(int sizeHint, Recycler rec public String getResponseContentTypeString() { return "application/octet-stream"; } - - @Override - public void close() {} }; } diff --git a/modules/transport-netty4/src/test/java/org/elasticsearch/http/netty4/Netty4HttpServerTransportTests.java b/modules/transport-netty4/src/test/java/org/elasticsearch/http/netty4/Netty4HttpServerTransportTests.java index c08d571eaf6bb..1215d54e9ace1 100644 --- a/modules/transport-netty4/src/test/java/org/elasticsearch/http/netty4/Netty4HttpServerTransportTests.java +++ b/modules/transport-netty4/src/test/java/org/elasticsearch/http/netty4/Netty4HttpServerTransportTests.java @@ -614,7 +614,7 @@ public void dispatchRequest(final RestRequest request, final RestChannel channel channel.sendResponse( RestResponse.chunked(OK, ChunkedRestResponseBody.fromXContent(ignored -> Iterators.single((builder, params) -> { throw new AssertionError("should not be called for HEAD REQUEST"); - }), ToXContent.EMPTY_PARAMS, channel, null)) + }), ToXContent.EMPTY_PARAMS, channel), null) ); } catch (IOException e) { throw new AssertionError(e); diff --git a/server/src/main/java/org/elasticsearch/http/DefaultRestChannel.java b/server/src/main/java/org/elasticsearch/http/DefaultRestChannel.java index f4dbf8115da33..9719716c57ce4 100644 --- a/server/src/main/java/org/elasticsearch/http/DefaultRestChannel.java +++ b/server/src/main/java/org/elasticsearch/http/DefaultRestChannel.java @@ -95,6 +95,7 @@ public void sendResponse(RestResponse restResponse) { toClose.add(() -> CloseableChannel.closeChannel(httpChannel)); } toClose.add(() -> tracer.stopTrace(request)); + toClose.add(restResponse); boolean success = false; String opaque = null; @@ -113,7 +114,6 @@ public void sendResponse(RestResponse restResponse) { final HttpResponse httpResponse; if (isHeadRequest == false && restResponse.isChunked()) { ChunkedRestResponseBody chunkedContent = restResponse.chunkedContent(); - toClose.add(chunkedContent); if (httpLogger != null && httpLogger.isBodyTracerEnabled()) { final var loggerStream = httpLogger.openResponseBodyLoggingStream(request.getRequestId()); toClose.add(() -> { @@ -131,8 +131,6 @@ public void sendResponse(RestResponse restResponse) { final BytesReference content = restResponse.content(); if (content instanceof Releasable releasable) { toClose.add(releasable); - } else if (restResponse.isChunked()) { - toClose.add(restResponse.chunkedContent()); } toClose.add(this::releaseOutputBuffer); diff --git a/server/src/main/java/org/elasticsearch/rest/ChunkedRestResponseBody.java b/server/src/main/java/org/elasticsearch/rest/ChunkedRestResponseBody.java index ae267573b4cab..8f96e30c76c45 100644 --- a/server/src/main/java/org/elasticsearch/rest/ChunkedRestResponseBody.java +++ b/server/src/main/java/org/elasticsearch/rest/ChunkedRestResponseBody.java @@ -15,8 +15,6 @@ import org.elasticsearch.common.xcontent.ChunkedToXContent; import org.elasticsearch.core.CheckedConsumer; import org.elasticsearch.core.IOUtils; -import org.elasticsearch.core.Nullable; -import org.elasticsearch.core.Releasable; import org.elasticsearch.core.Releasables; import org.elasticsearch.core.RestApiVersion; import org.elasticsearch.core.Streams; @@ -36,7 +34,7 @@ * The body of a rest response that uses chunked HTTP encoding. Implementations are used to avoid materializing full responses on heap and * instead serialize only as much of the response as can be flushed to the network right away. */ -public interface ChunkedRestResponseBody extends Releasable { +public interface ChunkedRestResponseBody { Logger logger = LogManager.getLogger(ChunkedRestResponseBody.class); @@ -67,15 +65,10 @@ public interface ChunkedRestResponseBody extends Releasable { * @param chunkedToXContent chunked x-content instance to serialize * @param params parameters to use for serialization * @param channel channel the response will be written to - * @param releasable resource to release when the response is fully sent, or {@code null} if nothing to release * @return chunked rest response body */ - static ChunkedRestResponseBody fromXContent( - ChunkedToXContent chunkedToXContent, - ToXContent.Params params, - RestChannel channel, - @Nullable Releasable releasable - ) throws IOException { + static ChunkedRestResponseBody fromXContent(ChunkedToXContent chunkedToXContent, ToXContent.Params params, RestChannel channel) + throws IOException { return new ChunkedRestResponseBody() { @@ -146,11 +139,6 @@ public ReleasableBytesReference encodeChunk(int sizeHint, Recycler rec public String getResponseContentTypeString() { return builder.getResponseContentTypeString(); } - - @Override - public void close() { - Releasables.closeExpectNoException(releasable); - } }; } @@ -158,11 +146,7 @@ public void close() { * Create a chunked response body to be written to a specific {@link RestChannel} from a stream of text chunks, each represented as a * consumer of a {@link Writer}. The last chunk that the iterator yields must write at least one byte. */ - static ChunkedRestResponseBody fromTextChunks( - String contentType, - Iterator> chunkIterator, - @Nullable Releasable releasable - ) { + static ChunkedRestResponseBody fromTextChunks(String contentType, Iterator> chunkIterator) { return new ChunkedRestResponseBody() { private RecyclerBytesStreamOutput currentOutput; private final Writer writer = new OutputStreamWriter(new OutputStream() { @@ -235,11 +219,6 @@ public ReleasableBytesReference encodeChunk(int sizeHint, Recycler rec public String getResponseContentTypeString() { return contentType; } - - @Override - public void close() { - Releasables.closeExpectNoException(releasable); - } }; } } diff --git a/server/src/main/java/org/elasticsearch/rest/LoggingChunkedRestResponseBody.java b/server/src/main/java/org/elasticsearch/rest/LoggingChunkedRestResponseBody.java index 00b56d0e05051..0508828c70da1 100644 --- a/server/src/main/java/org/elasticsearch/rest/LoggingChunkedRestResponseBody.java +++ b/server/src/main/java/org/elasticsearch/rest/LoggingChunkedRestResponseBody.java @@ -46,9 +46,4 @@ public ReleasableBytesReference encodeChunk(int sizeHint, Recycler rec public String getResponseContentTypeString() { return inner.getResponseContentTypeString(); } - - @Override - public void close() { - inner.close(); - } } diff --git a/server/src/main/java/org/elasticsearch/rest/RestController.java b/server/src/main/java/org/elasticsearch/rest/RestController.java index 56a70e3bb2ab4..913ce03b1efc1 100644 --- a/server/src/main/java/org/elasticsearch/rest/RestController.java +++ b/server/src/main/java/org/elasticsearch/rest/RestController.java @@ -29,6 +29,8 @@ import org.elasticsearch.common.util.concurrent.RunOnce; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.core.Nullable; +import org.elasticsearch.core.Releasable; +import org.elasticsearch.core.Releasables; import org.elasticsearch.core.RestApiVersion; import org.elasticsearch.core.Streams; import org.elasticsearch.core.TimeValue; @@ -824,10 +826,8 @@ public void sendResponse(RestResponse response) { if (response.isChunked() == false) { methodHandlers.addResponseStats(response.content().length()); } else { - response = RestResponse.chunked( - response.status(), - new EncodedLengthTrackingChunkedRestResponseBody(response.chunkedContent(), methodHandlers) - ); + final var wrapped = new EncodedLengthTrackingChunkedRestResponseBody(response.chunkedContent(), methodHandlers); + response = RestResponse.chunked(response.status(), wrapped, Releasables.wrap(wrapped, response)); } delegate.sendResponse(response); success = true; @@ -851,7 +851,7 @@ private void close() { } } - private static class EncodedLengthTrackingChunkedRestResponseBody implements ChunkedRestResponseBody { + private static class EncodedLengthTrackingChunkedRestResponseBody implements ChunkedRestResponseBody, Releasable { private final ChunkedRestResponseBody delegate; private final RunOnce onCompletion; @@ -884,7 +884,6 @@ public String getResponseContentTypeString() { @Override public void close() { - delegate.close(); // the client might close the connection before we send the last chunk, in which case we won't have recorded the response in the // stats yet, so we do it now: onCompletion.run(); diff --git a/server/src/main/java/org/elasticsearch/rest/RestResponse.java b/server/src/main/java/org/elasticsearch/rest/RestResponse.java index 49a6a34357a45..a4a44a5a65561 100644 --- a/server/src/main/java/org/elasticsearch/rest/RestResponse.java +++ b/server/src/main/java/org/elasticsearch/rest/RestResponse.java @@ -15,9 +15,10 @@ import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.bytes.ReleasableBytesReference; import org.elasticsearch.common.util.Maps; import org.elasticsearch.core.Nullable; +import org.elasticsearch.core.Releasable; +import org.elasticsearch.core.Releasables; import org.elasticsearch.xcontent.ToXContent; import org.elasticsearch.xcontent.XContentBuilder; @@ -33,7 +34,7 @@ import static org.elasticsearch.ElasticsearchException.REST_EXCEPTION_SKIP_STACK_TRACE; import static org.elasticsearch.rest.RestController.ELASTIC_PRODUCT_HTTP_HEADER; -public final class RestResponse { +public final class RestResponse implements Releasable { public static final String TEXT_CONTENT_TYPE = "text/plain; charset=UTF-8"; @@ -51,6 +52,9 @@ public final class RestResponse { private final String responseMediaType; private Map> customHeaders; + @Nullable + private final Releasable releasable; + /** * Creates a new response based on {@link XContentBuilder}. */ @@ -73,18 +77,18 @@ public RestResponse(RestStatus status, String responseMediaType, String content) } public RestResponse(RestStatus status, String responseMediaType, BytesReference content) { - this(status, responseMediaType, content, null); + this(status, responseMediaType, content, null, null); + } + + private RestResponse(RestStatus status, String responseMediaType, BytesReference content, @Nullable Releasable releasable) { + this(status, responseMediaType, content, null, releasable); } - public static RestResponse chunked(RestStatus restStatus, ChunkedRestResponseBody content) { + public static RestResponse chunked(RestStatus restStatus, ChunkedRestResponseBody content, @Nullable Releasable releasable) { if (content.isDone()) { - return new RestResponse( - restStatus, - content.getResponseContentTypeString(), - new ReleasableBytesReference(BytesArray.EMPTY, content) - ); + return new RestResponse(restStatus, content.getResponseContentTypeString(), BytesArray.EMPTY, releasable); } else { - return new RestResponse(restStatus, content.getResponseContentTypeString(), null, content); + return new RestResponse(restStatus, content.getResponseContentTypeString(), null, content, releasable); } } @@ -95,12 +99,14 @@ private RestResponse( RestStatus status, String responseMediaType, @Nullable BytesReference content, - @Nullable ChunkedRestResponseBody chunkedResponseBody + @Nullable ChunkedRestResponseBody chunkedResponseBody, + @Nullable Releasable releasable ) { this.status = status; this.content = content; this.responseMediaType = responseMediaType; this.chunkedResponseBody = chunkedResponseBody; + this.releasable = releasable; assert (content == null) != (chunkedResponseBody == null); } @@ -142,6 +148,7 @@ public RestResponse(RestChannel channel, RestStatus status, Exception e) throws copyHeaders(((ElasticsearchException) e)); } this.chunkedResponseBody = null; + this.releasable = null; } public String contentType() { @@ -224,4 +231,9 @@ public Map> filterHeaders(Map> headers } return headers; } + + @Override + public void close() { + Releasables.closeExpectNoException(releasable); + } } diff --git a/server/src/main/java/org/elasticsearch/rest/action/RestChunkedToXContentListener.java b/server/src/main/java/org/elasticsearch/rest/action/RestChunkedToXContentListener.java index 2edb042ea23e8..3798f2b6b6fb1 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/RestChunkedToXContentListener.java +++ b/server/src/main/java/org/elasticsearch/rest/action/RestChunkedToXContentListener.java @@ -40,7 +40,8 @@ protected void processResponse(Response response) throws IOException { channel.sendResponse( RestResponse.chunked( getRestStatus(response), - ChunkedRestResponseBody.fromXContent(response, params, channel, releasableFromResponse(response)) + ChunkedRestResponseBody.fromXContent(response, params, channel), + releasableFromResponse(response) ) ); } diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestNodesHotThreadsAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestNodesHotThreadsAction.java index 2942e59aa1bfd..bc0750f16e0e7 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestNodesHotThreadsAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestNodesHotThreadsAction.java @@ -117,7 +117,7 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC @Override public RestResponse buildResponse(NodesHotThreadsResponse response) { response.mustIncRef(); - return RestResponse.chunked(RestStatus.OK, fromTextChunks(TEXT_CONTENT_TYPE, response.getTextChunks(), response::decRef)); + return RestResponse.chunked(RestStatus.OK, fromTextChunks(TEXT_CONTENT_TYPE, response.getTextChunks()), response::decRef); } }); } diff --git a/server/src/main/java/org/elasticsearch/rest/action/cat/RestTable.java b/server/src/main/java/org/elasticsearch/rest/action/cat/RestTable.java index 8ce001f7a1a77..6845fec4db6fe 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/cat/RestTable.java +++ b/server/src/main/java/org/elasticsearch/rest/action/cat/RestTable.java @@ -77,9 +77,9 @@ public static RestResponse buildXContentBuilder(Table table, RestChannel channel Iterators.single((builder, params) -> builder.endArray()) ), ToXContent.EMPTY_PARAMS, - channel, - null - ) + channel + ), + null ); } @@ -127,9 +127,9 @@ public static RestResponse buildTextPlainResponse(Table table, RestChannel chann } writer.append("\n"); }) - ), - null - ) + ) + ), + null ); } diff --git a/server/src/main/java/org/elasticsearch/rest/action/info/RestClusterInfoAction.java b/server/src/main/java/org/elasticsearch/rest/action/info/RestClusterInfoAction.java index 4300293a1336e..8be023bb4a182 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/info/RestClusterInfoAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/info/RestClusterInfoAction.java @@ -130,9 +130,9 @@ public RestResponse buildResponse(NodesStatsResponse response) throws Exception ChunkedToXContentHelper.endObject() ), EMPTY_PARAMS, - channel, - null - ) + channel + ), + null ); } }); diff --git a/server/src/test/java/org/elasticsearch/http/DefaultRestChannelTests.java b/server/src/test/java/org/elasticsearch/http/DefaultRestChannelTests.java index a22f17702b157..1629dbd001dc2 100644 --- a/server/src/test/java/org/elasticsearch/http/DefaultRestChannelTests.java +++ b/server/src/test/java/org/elasticsearch/http/DefaultRestChannelTests.java @@ -543,12 +543,7 @@ public ReleasableBytesReference encodeChunk(int sizeHint, Recycler rec public String getResponseContentTypeString() { return RestResponse.TEXT_CONTENT_TYPE; } - - @Override - public void close() { - assertTrue(isClosed.compareAndSet(false, true)); - } - })); + }, () -> assertTrue(isClosed.compareAndSet(false, true)))); @SuppressWarnings("unchecked") Class> listenerClass = (Class>) (Class) ActionListener.class; ArgumentCaptor> listenerCaptor = ArgumentCaptor.forClass(listenerClass); @@ -750,12 +745,7 @@ public ReleasableBytesReference encodeChunk(int sizeHint, Recycler rec public String getResponseContentTypeString() { return RestResponse.TEXT_CONTENT_TYPE; } - - @Override - public void close() { - assertTrue(isClosed.compareAndSet(false, true)); - } - })) + }, () -> assertTrue(isClosed.compareAndSet(false, true)))) ) ); diff --git a/server/src/test/java/org/elasticsearch/rest/ChunkedRestResponseBodyTests.java b/server/src/test/java/org/elasticsearch/rest/ChunkedRestResponseBodyTests.java index 485e2a3a3fdd7..cce2a8db25c8e 100644 --- a/server/src/test/java/org/elasticsearch/rest/ChunkedRestResponseBodyTests.java +++ b/server/src/test/java/org/elasticsearch/rest/ChunkedRestResponseBodyTests.java @@ -29,7 +29,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; public class ChunkedRestResponseBodyTests extends ESTestCase { @@ -51,59 +50,39 @@ public void testEncodesChunkedXContentCorrectly() throws IOException { } final var bytesDirect = BytesReference.bytes(builderDirect); - final var isClosed = new AtomicBoolean(); - try ( - var chunkedResponse = ChunkedRestResponseBody.fromXContent( - chunkedToXContent, - ToXContent.EMPTY_PARAMS, - new FakeRestChannel( - new FakeRestRequest.Builder(xContentRegistry()).withContent(BytesArray.EMPTY, randomXContent.type()).build(), - randomBoolean(), - 1 - ), - () -> assertTrue(isClosed.compareAndSet(false, true)) + var chunkedResponse = ChunkedRestResponseBody.fromXContent( + chunkedToXContent, + ToXContent.EMPTY_PARAMS, + new FakeRestChannel( + new FakeRestRequest.Builder(xContentRegistry()).withContent(BytesArray.EMPTY, randomXContent.type()).build(), + randomBoolean(), + 1 ) - ) { - - final List refsGenerated = new ArrayList<>(); - while (chunkedResponse.isDone() == false) { - refsGenerated.add(chunkedResponse.encodeChunk(randomIntBetween(2, 10), BytesRefRecycler.NON_RECYCLING_INSTANCE)); - } + ); - assertEquals(bytesDirect, CompositeBytesReference.of(refsGenerated.toArray(new BytesReference[0]))); - assertFalse(isClosed.get()); + final List refsGenerated = new ArrayList<>(); + while (chunkedResponse.isDone() == false) { + refsGenerated.add(chunkedResponse.encodeChunk(randomIntBetween(2, 10), BytesRefRecycler.NON_RECYCLING_INSTANCE)); } - assertTrue(isClosed.get()); + + assertEquals(bytesDirect, CompositeBytesReference.of(refsGenerated.toArray(new BytesReference[0]))); } public void testFromTextChunks() throws IOException { final var chunks = randomList(1000, () -> randomUnicodeOfLengthBetween(1, 100)); - final var isClosed = new AtomicBoolean(); - try ( - var body = ChunkedRestResponseBody.fromTextChunks( - "text/plain", - Iterators.map(chunks.iterator(), s -> w -> w.write(s)), - () -> assertTrue(isClosed.compareAndSet(false, true)) - ) - ) { - final List refsGenerated = new ArrayList<>(); - while (body.isDone() == false) { - refsGenerated.add(body.encodeChunk(randomIntBetween(2, 10), BytesRefRecycler.NON_RECYCLING_INSTANCE)); - } - final BytesReference chunkedBytes = CompositeBytesReference.of(refsGenerated.toArray(new BytesReference[0])); + var body = ChunkedRestResponseBody.fromTextChunks("text/plain", Iterators.map(chunks.iterator(), s -> w -> w.write(s))); + final List refsGenerated = new ArrayList<>(); + while (body.isDone() == false) { + refsGenerated.add(body.encodeChunk(randomIntBetween(2, 10), BytesRefRecycler.NON_RECYCLING_INSTANCE)); + } + final BytesReference chunkedBytes = CompositeBytesReference.of(refsGenerated.toArray(new BytesReference[0])); - try ( - var outputStream = new ByteArrayOutputStream(); - var writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8) - ) { - for (final var chunk : chunks) { - writer.write(chunk); - } - writer.flush(); - assertEquals(new BytesArray(outputStream.toByteArray()), chunkedBytes); + try (var outputStream = new ByteArrayOutputStream(); var writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)) { + for (final var chunk : chunks) { + writer.write(chunk); } - assertFalse(isClosed.get()); + writer.flush(); + assertEquals(new BytesArray(outputStream.toByteArray()), chunkedBytes); } - assertTrue(isClosed.get()); } } diff --git a/server/src/test/java/org/elasticsearch/rest/RestResponseTests.java b/server/src/test/java/org/elasticsearch/rest/RestResponseTests.java index 4125c9bb66b4f..41a54ac580a55 100644 --- a/server/src/test/java/org/elasticsearch/rest/RestResponseTests.java +++ b/server/src/test/java/org/elasticsearch/rest/RestResponseTests.java @@ -97,7 +97,8 @@ public void testWithHeaders() throws Exception { public void testEmptyChunkedBody() { RestResponse response = RestResponse.chunked( RestStatus.OK, - ChunkedRestResponseBody.fromTextChunks(RestResponse.TEXT_CONTENT_TYPE, Collections.emptyIterator(), null) + ChunkedRestResponseBody.fromTextChunks(RestResponse.TEXT_CONTENT_TYPE, Collections.emptyIterator()), + null ); assertFalse(response.isChunked()); assertNotNull(response.content()); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlResponseListener.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlResponseListener.java index 7b525642009a7..0022866cf1742 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlResponseListener.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlResponseListener.java @@ -132,16 +132,14 @@ private RestResponse buildResponse(EsqlQueryResponse esqlResponse) throws IOExce if (mediaType instanceof TextFormat format) { restResponse = RestResponse.chunked( RestStatus.OK, - ChunkedRestResponseBody.fromTextChunks( - format.contentType(restRequest), - format.format(restRequest, esqlResponse), - releasable - ) + ChunkedRestResponseBody.fromTextChunks(format.contentType(restRequest), format.format(restRequest, esqlResponse)), + releasable ); } else { restResponse = RestResponse.chunked( RestStatus.OK, - ChunkedRestResponseBody.fromXContent(esqlResponse, channel.request(), channel, releasable) + ChunkedRestResponseBody.fromXContent(esqlResponse, channel.request(), channel), + releasable ); } long tookNanos = stopWatch.stop().getNanos(); From e0514f33e7af855d63b539a6a004390c8af4ba61 Mon Sep 17 00:00:00 2001 From: fang-xing-esql <155562079+fang-xing-esql@users.noreply.github.com> Date: Thu, 25 Jan 2024 12:20:42 -0500 Subject: [PATCH 36/37] [ES|QL] Allow DateTime as the third and fourth inputs to auto_bucket (#104547) * Allow both string and datetime as the third and fourth inputs to auto_bucket Committer: Fang Xing * Allow both string and datetime as the third and fourth inputs to auto_bucket * Allow both string and datetime as the third and fourth inputs to auto_bucket * Allow both string and datetime as the third and fourth inputs to auto_bucket * Allow both string and datetime as the third and fourth inputs to auto_bucket * Allow both string and datetime as the third and fourth inputs to auto_bucket --- .../src/main/resources/date.csv-spec | 19 ++++++++--- .../src/main/resources/show.csv-spec | 4 +-- .../function/scalar/math/AutoBucket.java | 32 +++++++++++++++---- .../function/scalar/math/AutoBucketTests.java | 11 +++++-- 4 files changed, 51 insertions(+), 15 deletions(-) diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date.csv-spec index 770e500024c34..c32c4e3e2fd2c 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date.csv-spec @@ -315,6 +315,17 @@ from employees | where birth_date > now() | sort emp_no asc | keep emp_no, birth emp_no:integer | birth_date:date ; +autoBucketYearInAgg +FROM employees +| WHERE hire_date >= "1999-01-01T00:00:00Z" +| EVAL bucket = AUTO_BUCKET(hire_date, 5, "1999-01-01T00:00:00Z", NOW()) +| STATS COUNT(*) by bucket +| sort bucket; + +COUNT(*):long | bucket:date +1 | 1999-01-01T00:00:00.000Z +; + autoBucketMonthInAgg // tag::auto_bucket_in_agg[] @@ -910,7 +921,7 @@ docsAutoBucketLast24hr //tag::docsAutoBucketLast24hr[] FROM sample_data | WHERE @timestamp >= NOW() - 1 day and @timestamp < NOW() -| EVAL bucket = AUTO_BUCKET(@timestamp, 25, DATE_FORMAT(NOW() - 1 day), DATE_FORMAT(NOW())) +| EVAL bucket = AUTO_BUCKET(@timestamp, 25, NOW() - 1 day, NOW()) | STATS COUNT(*) BY bucket //end::docsAutoBucketLast24hr[] ; @@ -922,7 +933,7 @@ docsGettingStartedAutoBucket // tag::gs-auto_bucket[] FROM sample_data | KEEP @timestamp -| EVAL bucket = AUTO_BUCKET (@timestamp, 24, "2023-10-23T00:00:00Z", "2023-10-23T23:59:59Z") +| EVAL bucket = AUTO_BUCKET(@timestamp, 24, "2023-10-23T00:00:00Z", NOW()) // end::gs-auto_bucket[] | LIMIT 0 ; @@ -934,7 +945,7 @@ docsGettingStartedAutoBucketStatsBy // tag::gs-auto_bucket-stats-by[] FROM sample_data | KEEP @timestamp, event_duration -| EVAL bucket = AUTO_BUCKET (@timestamp, 24, "2023-10-23T00:00:00Z", "2023-10-23T23:59:59Z") +| EVAL bucket = AUTO_BUCKET(@timestamp, 24, "2023-10-23T00:00:00Z", "2023-10-23T23:59:59Z") | STATS COUNT(*) BY bucket // end::gs-auto_bucket-stats-by[] | SORT bucket @@ -949,7 +960,7 @@ docsGettingStartedAutoBucketStatsByMedian // tag::gs-auto_bucket-stats-by-median[] FROM sample_data | KEEP @timestamp, event_duration -| EVAL bucket = AUTO_BUCKET (@timestamp, 24, "2023-10-23T00:00:00Z", "2023-10-23T23:59:59Z") +| EVAL bucket = AUTO_BUCKET(@timestamp, 24, "2023-10-23T00:00:00Z", "2023-10-23T23:59:59Z") | STATS median_duration = MEDIAN(event_duration) BY bucket // end::gs-auto_bucket-stats-by-median[] | SORT bucket diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/show.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/show.csv-spec index b8d6193887c34..76c83984a13ea 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/show.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/show.csv-spec @@ -15,7 +15,7 @@ acos |"double acos(n:double|integer|long|unsigned_long)" asin |"double asin(n:double|integer|long|unsigned_long)"|n |"double|integer|long|unsigned_long" | "" |double | "Inverse sine trigonometric function." | false | false | false atan |"double atan(n:double|integer|long|unsigned_long)" |n |"double|integer|long|unsigned_long" | "" |double | "Inverse tangent trigonometric function." | false | false | false atan2 |"double atan2(y:double|integer|long|unsigned_long, x:double|integer|long|unsigned_long)" |[y, x] |["double|integer|long|unsigned_long", "double|integer|long|unsigned_long"] |["", ""] |double | "The angle between the positive x-axis and the ray from the origin to the point (x , y) in the Cartesian plane." | [false, false] | false | false -auto_bucket |"double|date auto_bucket(field:integer|long|double|date, buckets:integer, from:integer|long|double|date, to:integer|long|double|date)" |[field, buckets, from, to] |["integer|long|double|date", "integer", "integer|long|double|date", "integer|long|double|date"] |["", "", "", ""] | "double|date" | "Creates human-friendly buckets and returns a datetime value for each row that corresponds to the resulting bucket the row falls into." | [false, false, false, false] | false | false +auto_bucket |"double|date auto_bucket(field:integer|long|double|date, buckets:integer, from:integer|long|double|date|string, to:integer|long|double|date|string)" |[field, buckets, from, to] |["integer|long|double|date", "integer", "integer|long|double|date|string", "integer|long|double|date|string"] |["", "", "", ""] | "double|date" | "Creates human-friendly buckets and returns a datetime value for each row that corresponds to the resulting bucket the row falls into." | [false, false, false, false] | false | false avg |"double avg(field:double|integer|long|unsigned_long)" |field |"double|integer|long|unsigned_long" | "" |double | "The average of a numeric field." | false | false | true case |"boolean|cartesian_point|date|double|geo_point|integer|ip|keyword|long|text|unsigned_long|version case(condition:boolean, rest...:boolean|cartesian_point|date|double|geo_point|integer|ip|keyword|long|text|unsigned_long|version)" |[condition, rest] |["boolean", "boolean|cartesian_point|date|double|geo_point|integer|ip|keyword|long|text|unsigned_long|version"] |["", ""] |"boolean|cartesian_point|date|double|geo_point|integer|ip|keyword|long|text|unsigned_long|version" | "Accepts pairs of conditions and values. The function returns the value that belongs to the first condition that evaluates to true." | [false, false] | true | false ceil |"double|integer|long|unsigned_long ceil(n:double|integer|long|unsigned_long)" |n |"double|integer|long|unsigned_long" | "" | "double|integer|long|unsigned_long" | "Round a number up to the nearest integer." | false | false | false @@ -111,7 +111,7 @@ synopsis:keyword "double asin(n:double|integer|long|unsigned_long)" "double atan(n:double|integer|long|unsigned_long)" "double atan2(y:double|integer|long|unsigned_long, x:double|integer|long|unsigned_long)" -"double|date auto_bucket(field:integer|long|double|date, buckets:integer, from:integer|long|double|date, to:integer|long|double|date)" +"double|date auto_bucket(field:integer|long|double|date, buckets:integer, from:integer|long|double|date|string, to:integer|long|double|date|string)" "double avg(field:double|integer|long|unsigned_long)" "boolean|cartesian_point|date|double|geo_point|integer|ip|keyword|long|text|unsigned_long|version case(condition:boolean, rest...:boolean|cartesian_point|date|double|geo_point|integer|ip|keyword|long|text|unsigned_long|version)" "double|integer|long|unsigned_long ceil(n:double|integer|long|unsigned_long)" diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AutoBucket.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AutoBucket.java index 33e0addf44d2f..6a8b3f41a9c65 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AutoBucket.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AutoBucket.java @@ -7,8 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; -import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.Rounding; +import org.elasticsearch.common.lucene.BytesRefs; import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator; import org.elasticsearch.core.TimeValue; import org.elasticsearch.index.mapper.DateFieldMapper; @@ -20,6 +20,7 @@ import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Div; import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Mul; import org.elasticsearch.xpack.ql.expression.Expression; +import org.elasticsearch.xpack.ql.expression.Foldables; import org.elasticsearch.xpack.ql.expression.Literal; import org.elasticsearch.xpack.ql.expression.TypeResolutions; import org.elasticsearch.xpack.ql.expression.function.scalar.ScalarFunction; @@ -40,7 +41,6 @@ import static org.elasticsearch.xpack.ql.expression.TypeResolutions.isFoldable; import static org.elasticsearch.xpack.ql.expression.TypeResolutions.isInteger; import static org.elasticsearch.xpack.ql.expression.TypeResolutions.isNumeric; -import static org.elasticsearch.xpack.ql.expression.TypeResolutions.isString; import static org.elasticsearch.xpack.ql.expression.TypeResolutions.isType; /** @@ -90,8 +90,8 @@ public AutoBucket( Source source, @Param(name = "field", type = { "integer", "long", "double", "date" }) Expression field, @Param(name = "buckets", type = { "integer" }) Expression buckets, - @Param(name = "from", type = { "integer", "long", "double", "date" }) Expression from, - @Param(name = "to", type = { "integer", "long", "double", "date" }) Expression to + @Param(name = "from", type = { "integer", "long", "double", "date", "string" }) Expression from, + @Param(name = "to", type = { "integer", "long", "double", "date", "string" }) Expression to ) { super(source, List.of(field, buckets, from, to)); this.field = field; @@ -115,8 +115,8 @@ public ExpressionEvaluator.Factory toEvaluator(Function isString(e, sourceText(), o)); + return resolveType((e, o) -> isStringOrDate(e, sourceText(), o)); } if (field.dataType().isNumeric()) { return resolveType((e, o) -> isNumeric(e, sourceText(), o)); @@ -216,6 +216,24 @@ private TypeResolution resolveType(BiFunction DataTypes.isString(exp) || DataTypes.isDateTime(exp), + operationName, + paramOrd, + "datetime", + "string" + ); + } + + private long foldToLong(Expression e) { + Object value = Foldables.valueOf(e); + return DataTypes.isDateTime(e.dataType()) + ? ((Number) value).longValue() + : DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parseMillis(BytesRefs.toString(value)); + } + @Override public DataType dataType() { if (field.dataType().isNumeric()) { diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AutoBucketTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AutoBucketTests.java index 043bf083b580a..013753c801c39 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AutoBucketTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AutoBucketTests.java @@ -84,8 +84,8 @@ private Expression build(Source source, Expression arg) { Literal from; Literal to; if (arg.dataType() == DataTypes.DATETIME) { - from = new Literal(Source.EMPTY, new BytesRef("2023-02-01T00:00:00.00Z"), DataTypes.KEYWORD); - to = new Literal(Source.EMPTY, new BytesRef("2023-03-01T00:00:00.00Z"), DataTypes.KEYWORD); + from = stringOrDateTime("2023-02-01T00:00:00.00Z"); + to = stringOrDateTime("2023-03-01T09:00:00.00Z"); } else { from = new Literal(Source.EMPTY, 0, DataTypes.DOUBLE); to = new Literal(Source.EMPTY, 1000, DataTypes.DOUBLE); @@ -93,6 +93,13 @@ private Expression build(Source source, Expression arg) { return new AutoBucket(source, arg, new Literal(Source.EMPTY, 50, DataTypes.INTEGER), from, to); } + private Literal stringOrDateTime(String date) { + if (randomBoolean()) { + return new Literal(Source.EMPTY, new BytesRef(date), randomBoolean() ? DataTypes.KEYWORD : DataTypes.TEXT); + } + return new Literal(Source.EMPTY, DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parseMillis(date), DataTypes.DATETIME); + } + @Override protected DataType expectedType(List argTypes) { if (argTypes.get(0).isNumeric()) { From 2a5cd78c68aeef129c51cf2e284fb206e22c9819 Mon Sep 17 00:00:00 2001 From: Mayya Sharipova Date: Thu, 25 Jan 2024 14:35:54 -0500 Subject: [PATCH 37/37] Mute data_stream test (#104775) data_stream/190_require_data_stream/Testing require_data_stream in bulk requests Awaiting fix from #104774 --- .../test/data_stream/190_require_data_stream.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/data-streams/src/yamlRestTest/resources/rest-api-spec/test/data_stream/190_require_data_stream.yml b/modules/data-streams/src/yamlRestTest/resources/rest-api-spec/test/data_stream/190_require_data_stream.yml index c77e114616c78..7aed1cbe0a636 100644 --- a/modules/data-streams/src/yamlRestTest/resources/rest-api-spec/test/data_stream/190_require_data_stream.yml +++ b/modules/data-streams/src/yamlRestTest/resources/rest-api-spec/test/data_stream/190_require_data_stream.yml @@ -60,8 +60,10 @@ --- "Testing require_data_stream in bulk requests": - skip: - version: " - 8.12.99" - reason: "require_data_stream was introduced in 8.13.0" + version: "all" + reason: "AwaitsFix https://github.com/elastic/elasticsearch/issues/104774" + #version: " - 8.12.99" + #reason: "require_data_stream was introduced in 8.13.0" features: allowed_warnings - do: