From c16f8efafee7b9a13bfc5fa36b246c2959f8d59a Mon Sep 17 00:00:00 2001 From: John Verwolf Date: Thu, 7 Dec 2023 11:53:30 -0800 Subject: [PATCH 01/22] S3 first byte latency metric (#102435) This PR adds a metrics for s3 backed blob store first byte latencies. --- docs/changelog/102435.yaml | 5 +++ .../s3/S3BlobStoreRepositoryMetricsTests.java | 10 ++++++ .../repositories/s3/S3BlobStore.java | 31 +++++++++++++++++++ .../repositories/RepositoriesModule.java | 10 +++++- 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 docs/changelog/102435.yaml diff --git a/docs/changelog/102435.yaml b/docs/changelog/102435.yaml new file mode 100644 index 0000000000000..e8905b08f1adc --- /dev/null +++ b/docs/changelog/102435.yaml @@ -0,0 +1,5 @@ +pr: 102435 +summary: S3 first byte latency metric +area: Search +type: enhancement +issues: [] diff --git a/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryMetricsTests.java b/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryMetricsTests.java index 2c759abc1e437..a7c1d25195028 100644 --- a/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryMetricsTests.java +++ b/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryMetricsTests.java @@ -37,6 +37,7 @@ import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; +import static org.elasticsearch.repositories.RepositoriesModule.HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM; import static org.elasticsearch.repositories.RepositoriesModule.METRIC_EXCEPTIONS_COUNT; import static org.elasticsearch.repositories.RepositoriesModule.METRIC_EXCEPTIONS_HISTOGRAM; import static org.elasticsearch.repositories.RepositoriesModule.METRIC_OPERATIONS_COUNT; @@ -110,6 +111,7 @@ public void testMetricsWithErrors() throws IOException { assertThat(getLongCounterValue(plugin, METRIC_THROTTLES_COUNT, Operation.PUT_OBJECT), equalTo(2L * batch)); assertThat(getLongHistogramValue(plugin, METRIC_EXCEPTIONS_HISTOGRAM, Operation.PUT_OBJECT), equalTo(batch)); assertThat(getLongHistogramValue(plugin, METRIC_THROTTLES_HISTOGRAM, Operation.PUT_OBJECT), equalTo(2L * batch)); + assertThat(getNumberOfMeasurements(plugin, HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM, Operation.PUT_OBJECT), equalTo(batch)); } // Get not found @@ -129,6 +131,7 @@ public void testMetricsWithErrors() throws IOException { assertThat(getLongCounterValue(plugin, METRIC_THROTTLES_COUNT, Operation.GET_OBJECT), equalTo(batch)); assertThat(getLongHistogramValue(plugin, METRIC_EXCEPTIONS_HISTOGRAM, Operation.GET_OBJECT), equalTo(batch)); assertThat(getLongHistogramValue(plugin, METRIC_THROTTLES_HISTOGRAM, Operation.GET_OBJECT), equalTo(batch)); + assertThat(getNumberOfMeasurements(plugin, HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM, Operation.GET_OBJECT), equalTo(batch)); } // List retry exhausted @@ -148,6 +151,7 @@ public void testMetricsWithErrors() throws IOException { assertThat(getLongCounterValue(plugin, METRIC_THROTTLES_COUNT, Operation.LIST_OBJECTS), equalTo(5L * batch)); assertThat(getLongHistogramValue(plugin, METRIC_EXCEPTIONS_HISTOGRAM, Operation.LIST_OBJECTS), equalTo(batch)); assertThat(getLongHistogramValue(plugin, METRIC_THROTTLES_HISTOGRAM, Operation.LIST_OBJECTS), equalTo(5L * batch)); + assertThat(getNumberOfMeasurements(plugin, HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM, Operation.LIST_OBJECTS), equalTo(batch)); } // Delete to clean up @@ -159,6 +163,7 @@ public void testMetricsWithErrors() throws IOException { assertThat(getLongCounterValue(plugin, METRIC_THROTTLES_COUNT, Operation.DELETE_OBJECTS), equalTo(0L)); assertThat(getLongHistogramValue(plugin, METRIC_EXCEPTIONS_HISTOGRAM, Operation.DELETE_OBJECTS), equalTo(0L)); assertThat(getLongHistogramValue(plugin, METRIC_THROTTLES_HISTOGRAM, Operation.DELETE_OBJECTS), equalTo(0L)); + assertThat(getNumberOfMeasurements(plugin, HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM, Operation.DELETE_OBJECTS), equalTo(1L)); } private void addErrorStatus(RestStatus... statuses) { @@ -174,6 +179,11 @@ private long getLongCounterValue(TestTelemetryPlugin plugin, String instrumentNa .orElse(0L); } + private long getNumberOfMeasurements(TestTelemetryPlugin plugin, String instrumentName, Operation operation) { + final List measurements = plugin.getLongHistogramMeasurement(instrumentName); + return measurements.stream().filter(m -> m.attributes().get("operation") == operation.getKey()).count(); + } + private long getLongHistogramValue(TestTelemetryPlugin plugin, String instrumentName, Operation operation) { final List measurements = Measurement.combine(plugin.getLongHistogramMeasurement(instrumentName)); return measurements.stream() diff --git a/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobStore.java b/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobStore.java index 37d076362f396..99fe3d5cc31ad 100644 --- a/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobStore.java +++ b/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobStore.java @@ -48,11 +48,13 @@ import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.LongAdder; import java.util.stream.Collectors; import static org.elasticsearch.core.Strings.format; +import static org.elasticsearch.repositories.RepositoriesModule.HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM; import static org.elasticsearch.repositories.RepositoriesModule.METRIC_EXCEPTIONS_COUNT; import static org.elasticsearch.repositories.RepositoriesModule.METRIC_EXCEPTIONS_HISTOGRAM; import static org.elasticsearch.repositories.RepositoriesModule.METRIC_OPERATIONS_COUNT; @@ -97,6 +99,7 @@ class S3BlobStore implements BlobStore { private final LongCounter unsuccessfulOperationCounter; private final LongHistogram exceptionHistogram; private final LongHistogram throttleHistogram; + private final LongHistogram httpRequestTimeInMicroHistogram; private final StatsCollectors statsCollectors = new StatsCollectors(); @@ -134,6 +137,7 @@ class S3BlobStore implements BlobStore { this.unsuccessfulOperationCounter = this.meterRegistry.getLongCounter(METRIC_UNSUCCESSFUL_OPERATIONS_COUNT); this.exceptionHistogram = this.meterRegistry.getLongHistogram(METRIC_EXCEPTIONS_HISTOGRAM); this.throttleHistogram = this.meterRegistry.getLongHistogram(METRIC_THROTTLES_HISTOGRAM); + this.httpRequestTimeInMicroHistogram = this.meterRegistry.getLongHistogram(HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM); s3RequestRetryStats = new S3RequestRetryStats(getMaxRetries()); threadPool.scheduleWithFixedDelay(() -> { var priorRetryStats = s3RequestRetryStats; @@ -224,6 +228,7 @@ public final void collectMetrics(Request request, Response response) { throttleCounter.incrementBy(throttleCount, attributes); throttleHistogram.record(throttleCount, attributes); } + httpRequestTimeInMicroHistogram.record(getHttpRequestTimeInMicros(request), attributes); } private boolean assertConsistencyBetweenHttpRequestAndOperation(Request request, Operation operation) { @@ -262,6 +267,32 @@ private static long getCountForMetric(TimingInfo info, AWSRequestMetrics.Field f } } + /** + * Used for APM style metrics to measure statics about performance. This is not for billing. + */ + private static long getHttpRequestTimeInMicros(Request request) { + List requestTimesIncludingRetries; + requestTimesIncludingRetries = request.getAWSRequestMetrics() + .getTimingInfo() + .getAllSubMeasurements(AWSRequestMetrics.Field.HttpRequestTime.name()); + + // Here we calculate the timing in Microseconds for the sum of the individual subMeasurements with the goal of deriving the TTFB + // (time to first byte). We calculate the time in micros for later use with an APM style counter (exposed as a long), rather than + // using the default double exposed by getTimeTakenMillisIfKnown(). + long totalTimeInMicros = 0; + for (TimingInfo timingInfo : requestTimesIncludingRetries) { + var endTimeInNanos = timingInfo.getEndTimeNanoIfKnown(); + if (endTimeInNanos != null) { + totalTimeInMicros += TimeUnit.NANOSECONDS.toMicros(endTimeInNanos - timingInfo.getStartTimeNano()); + } + } + if (totalTimeInMicros == 0) { + logger.warn("Expected HttpRequestTime to be tracked for request [{}] but found no count.", request); + return 0L; + } + return totalTimeInMicros; + } + @Override public String toString() { return bucket; diff --git a/server/src/main/java/org/elasticsearch/repositories/RepositoriesModule.java b/server/src/main/java/org/elasticsearch/repositories/RepositoriesModule.java index b066b4c5a329e..a60ab48597de3 100644 --- a/server/src/main/java/org/elasticsearch/repositories/RepositoriesModule.java +++ b/server/src/main/java/org/elasticsearch/repositories/RepositoriesModule.java @@ -42,7 +42,7 @@ public final class RepositoriesModule { public static final String METRIC_UNSUCCESSFUL_OPERATIONS_COUNT = "es.repositories.operations.unsuccessful.count"; public static final String METRIC_EXCEPTIONS_HISTOGRAM = "es.repositories.exceptions.histogram"; public static final String METRIC_THROTTLES_HISTOGRAM = "es.repositories.throttles.histogram"; - + public static final String HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM = "es.repositories.requests.http_request_time.histogram"; private final RepositoriesService repositoriesService; public RepositoriesModule( @@ -55,6 +55,7 @@ public RepositoriesModule( RecoverySettings recoverySettings, TelemetryProvider telemetryProvider ) { + // TODO: refactor APM metrics into their own class, passed in as a dependency (e.g. see BlobCacheMetrics as an example). telemetryProvider.getMeterRegistry().registerLongCounter(METRIC_REQUESTS_COUNT, "repository request counter", "unit"); telemetryProvider.getMeterRegistry().registerLongCounter(METRIC_EXCEPTIONS_COUNT, "repository request exception counter", "unit"); telemetryProvider.getMeterRegistry().registerLongCounter(METRIC_THROTTLES_COUNT, "repository operation counter", "unit"); @@ -66,6 +67,13 @@ public RepositoriesModule( .registerLongHistogram(METRIC_EXCEPTIONS_HISTOGRAM, "repository request exception histogram", "unit"); telemetryProvider.getMeterRegistry() .registerLongHistogram(METRIC_THROTTLES_HISTOGRAM, "repository request throttle histogram", "unit"); + telemetryProvider.getMeterRegistry() + .registerLongHistogram( + HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM, + "HttpRequestTime in microseconds expressed as as a histogram", + "micros" + ); + Map factories = new HashMap<>(); factories.put( FsRepository.TYPE, From 715b1bfa64b4394cc3fee1aafdf8e9a7723c1e11 Mon Sep 17 00:00:00 2001 From: David Turner Date: Thu, 7 Dec 2023 20:16:20 +0000 Subject: [PATCH 02/22] Reduce forking in SLMGetExpiredSnapshotsAction (#102978) We only need to dispatch steps back onto the `MANAGEMENT` pool if they forked off it, and mostly that's not going to happen. With this commit we push the forking decisions down into the implementation in order to skip them when unnecessary. Relates #101445 --- .../slm/SLMGetExpiredSnapshotsAction.java | 34 +++++++------------ .../SLMGetExpiredSnapshotsActionTests.java | 2 +- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/x-pack/plugin/slm/src/main/java/org/elasticsearch/xpack/slm/SLMGetExpiredSnapshotsAction.java b/x-pack/plugin/slm/src/main/java/org/elasticsearch/xpack/slm/SLMGetExpiredSnapshotsAction.java index bd2d040d76299..550410d1d59aa 100644 --- a/x-pack/plugin/slm/src/main/java/org/elasticsearch/xpack/slm/SLMGetExpiredSnapshotsAction.java +++ b/x-pack/plugin/slm/src/main/java/org/elasticsearch/xpack/slm/SLMGetExpiredSnapshotsAction.java @@ -18,13 +18,13 @@ import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.RefCountingRunnable; import org.elasticsearch.action.support.SubscribableListener; +import org.elasticsearch.action.support.ThreadedActionListener; import org.elasticsearch.action.support.TransportAction; import org.elasticsearch.common.Strings; 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.ConcurrentCollections; -import org.elasticsearch.common.util.concurrent.EsExecutors; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.core.Tuple; import org.elasticsearch.repositories.GetSnapshotInfoContext; @@ -126,32 +126,21 @@ protected void doExecute(Task task, Request request, ActionListener li perRepositoryListener -> SubscribableListener // Get repository data - .newForked( - l -> repository.getRepositoryData( - EsExecutors.DIRECT_EXECUTOR_SERVICE, // TODO use retentionExecutor, see #101445? - l - ) - ) + .newForked(l -> repository.getRepositoryData(retentionExecutor, l)) // Collect snapshot details by policy, and get any missing details by reading SnapshotInfo .andThen( - retentionExecutor, - threadContext, - (l, repositoryData) -> getSnapshotDetailsByPolicy(repository, repositoryData, l) + (l, repositoryData) -> getSnapshotDetailsByPolicy(retentionExecutor, repository, repositoryData, l) ) // Compute snapshots to delete for each (relevant) policy - .andThen( - retentionExecutor, - threadContext, - (l, snapshotDetailsByPolicy) -> ActionListener.completeWith(l, () -> { - resultsBuilder.addResult( - repositoryName, - getSnapshotsToDelete(repositoryName, request.policies(), snapshotDetailsByPolicy) - ); - return null; - }) - ) + .andThen((l, snapshotDetailsByPolicy) -> ActionListener.completeWith(l, () -> { + resultsBuilder.addResult( + repositoryName, + getSnapshotsToDelete(repositoryName, request.policies(), snapshotDetailsByPolicy) + ); + return null; + })) // And notify this repository's listener on completion .addListener(perRepositoryListener.delegateResponse((l, e) -> { @@ -184,6 +173,7 @@ Stream flatMap(BiFunction listener @@ -218,7 +208,7 @@ static void getSnapshotDetailsByPolicy( snapshotInfo.snapshotId(), RepositoryData.SnapshotDetails.fromSnapshotInfo(snapshotInfo) ), - listener.map(ignored -> snapshotDetailsByPolicy) + new ThreadedActionListener<>(executor, listener.map(ignored -> snapshotDetailsByPolicy)) ) ); } diff --git a/x-pack/plugin/slm/src/test/java/org/elasticsearch/xpack/slm/SLMGetExpiredSnapshotsActionTests.java b/x-pack/plugin/slm/src/test/java/org/elasticsearch/xpack/slm/SLMGetExpiredSnapshotsActionTests.java index c876bb83f919d..eda0e4f8ae39c 100644 --- a/x-pack/plugin/slm/src/test/java/org/elasticsearch/xpack/slm/SLMGetExpiredSnapshotsActionTests.java +++ b/x-pack/plugin/slm/src/test/java/org/elasticsearch/xpack/slm/SLMGetExpiredSnapshotsActionTests.java @@ -180,7 +180,7 @@ record SeenSnapshotInfo(SnapshotId snapshotId, String policyId) {} .newForked(l -> repository.getRepositoryData(EsExecutors.DIRECT_EXECUTOR_SERVICE, l)) .andThen( - (l, rd) -> SLMGetExpiredSnapshotsAction.getSnapshotDetailsByPolicy(repository, rd, l) + (l, rd) -> SLMGetExpiredSnapshotsAction.getSnapshotDetailsByPolicy(EsExecutors.DIRECT_EXECUTOR_SERVICE, repository, rd, l) ) .andThen((l, snapshotDetailsByPolicy) -> { From b0ae25504aff8e33e4ed7171c22dc335d4016b2c Mon Sep 17 00:00:00 2001 From: James Baiera Date: Thu, 7 Dec 2023 15:56:46 -0500 Subject: [PATCH 03/22] Fix template simulate setting application ordering (#103024) * Fix index template application order during index template simulation * precommit * Update docs/changelog/103024.yaml --------- Co-authored-by: Elastic Machine --- docs/changelog/103024.yaml | 6 ++ .../TransportSimulateIndexTemplateAction.java | 2 +- ...sportSimulateIndexTemplateActionTests.java | 94 +++++++++++++++++++ 3 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 docs/changelog/103024.yaml create mode 100644 server/src/test/java/org/elasticsearch/action/admin/indices/template/post/TransportSimulateIndexTemplateActionTests.java diff --git a/docs/changelog/103024.yaml b/docs/changelog/103024.yaml new file mode 100644 index 0000000000000..e860ad056f980 --- /dev/null +++ b/docs/changelog/103024.yaml @@ -0,0 +1,6 @@ +pr: 103024 +summary: Fix template simulate setting application ordering +area: Indices APIs +type: bug +issues: + - 103008 diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/template/post/TransportSimulateIndexTemplateAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/template/post/TransportSimulateIndexTemplateAction.java index af40637db6703..bee6ab7f78be0 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/template/post/TransportSimulateIndexTemplateAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/template/post/TransportSimulateIndexTemplateAction.java @@ -307,7 +307,7 @@ public static Template resolveTemplate( } ); - Settings settings = Settings.builder().put(templateSettings).put(additionalSettings.build()).build(); + Settings settings = Settings.builder().put(additionalSettings.build()).put(templateSettings).build(); DataStreamLifecycle lifecycle = resolveLifecycle(simulatedState.metadata(), matchingTemplate); if (template.getDataStreamTemplate() != null && lifecycle == null && isDslOnlyMode) { lifecycle = DataStreamLifecycle.DEFAULT; diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/template/post/TransportSimulateIndexTemplateActionTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/template/post/TransportSimulateIndexTemplateActionTests.java new file mode 100644 index 0000000000000..c8fb09b1e7177 --- /dev/null +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/template/post/TransportSimulateIndexTemplateActionTests.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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.action.admin.indices.template.post; + +import org.elasticsearch.cluster.ClusterName; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.metadata.IndexMetadata; +import org.elasticsearch.cluster.metadata.Metadata; +import org.elasticsearch.cluster.metadata.Template; +import org.elasticsearch.common.compress.CompressedXContent; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.index.IndexSettingProvider; +import org.elasticsearch.indices.IndicesService; +import org.elasticsearch.indices.SystemIndices; +import org.elasticsearch.test.ESTestCase; + +import java.time.Instant; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.hamcrest.CoreMatchers.is; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class TransportSimulateIndexTemplateActionTests extends ESTestCase { + + public void testSettingsProviderIsOverridden() throws Exception { + String matchingTemplate = "test_template"; + String indexName = "test_index_name"; + CompressedXContent expectedMockMapping = new CompressedXContent(Map.of("key", "value")); + + boolean isDslOnlyMode = false; + ClusterState simulatedState = ClusterState.builder(new ClusterName("test_cluster")) + .metadata( + Metadata.builder() + .indexTemplates( + Map.of( + matchingTemplate, + ComposableIndexTemplate.builder() + .indexPatterns(List.of("test_index*")) + .template(new Template(Settings.builder().put("test-setting", 1).build(), null, null)) + .build() + ) + ) + ) + .build(); + + IndicesService indicesService = mock(IndicesService.class); + when(indicesService.withTempIndexService(any(IndexMetadata.class), any())).thenReturn(List.of()) // First call is mocked to return + // aliases + .thenReturn(expectedMockMapping); // Second call is mocked to return the merged mappings + + // This is not actually called in this test + SystemIndices systemIndices = mock(SystemIndices.class); + + // Create a setting provider that sets the test-setting to 0 + Set indexSettingsProviders = Set.of(new IndexSettingProvider() { + @Override + public Settings getAdditionalIndexSettings( + String indexName, + String dataStreamName, + boolean timeSeries, + Metadata metadata, + Instant resolvedAt, + Settings allSettings, + List combinedTemplateMappings + ) { + return Settings.builder().put("test-setting", 0).build(); + } + }); + + Template resolvedTemplate = TransportSimulateIndexTemplateAction.resolveTemplate( + matchingTemplate, + indexName, + simulatedState, + isDslOnlyMode, + xContentRegistry(), + indicesService, + systemIndices, + indexSettingsProviders + ); + + assertThat(resolvedTemplate.settings().getAsInt("test-setting", -1), is(1)); + } +} From e20821f13ecd6b53d25c910cbc007f33e7955ffb Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Thu, 7 Dec 2023 22:05:45 +0100 Subject: [PATCH 04/22] Remove some more ActionType subclasses (#103055) Cleaned up a few more of these. --- .../analysis/common/ReloadAnalyzerTests.java | 8 +- .../common/ReloadSynonymAnalyzerIT.java | 4 +- .../ingest/geoip/GeoIpDownloaderTests.java | 4 +- .../http/ClusterHealthRestCancellationIT.java | 6 +- .../http/RestActionCancellationIT.java | 4 +- .../action/IndicesRequestIT.java | 35 +- .../admin/cluster/node/tasks/TasksIT.java | 20 +- .../search/fieldcaps/FieldCapabilitiesIT.java | 11 +- .../elasticsearch/action/ActionModule.java | 33 +- .../action/DocWriteResponse.java | 2 +- .../cluster/health/ClusterHealthAction.java | 21 - .../health/ClusterHealthRequestBuilder.java | 2 +- .../health/TransportClusterHealthAction.java | 7 +- .../tasks/PendingClusterTasksAction.java | 21 - .../PendingClusterTasksRequestBuilder.java | 2 +- .../TransportPendingClusterTasksAction.java | 7 +- .../indices/alias/IndicesAliasesAction.java | 23 - .../alias/IndicesAliasesRequestBuilder.java | 2 +- .../alias/TransportIndicesAliasesAction.java | 5 +- .../indices/analyze/ReloadAnalyzerAction.java | 21 - .../TransportReloadAnalyzersAction.java | 7 +- .../admin/indices/close/CloseIndexAction.java | 21 - .../close/CloseIndexRequestBuilder.java | 2 +- .../close/TransportCloseIndexAction.java | 5 +- ...TransportVerifyShardBeforeCloseAction.java | 2 +- .../action/delete/DeleteAction.java | 21 - .../action/delete/DeleteRequestBuilder.java | 2 +- .../action/delete/TransportDeleteAction.java | 6 +- .../fieldcaps/FieldCapabilitiesAction.java | 22 - .../FieldCapabilitiesRequestBuilder.java | 2 +- .../TransportFieldCapabilitiesAction.java | 7 +- .../elasticsearch/action/get/GetAction.java | 22 - .../action/get/GetRequestBuilder.java | 4 +- .../action/get/MultiGetAction.java | 21 - .../action/get/MultiGetRequestBuilder.java | 2 +- .../action/get/TransportGetAction.java | 4 +- .../action/get/TransportMultiGetAction.java | 5 +- .../get/TransportShardMultiGetAction.java | 2 +- .../action/index/IndexAction.java | 25 - .../action/index/IndexRequestBuilder.java | 4 +- .../action/index/TransportIndexAction.java | 9 +- .../action/update/TransportUpdateAction.java | 13 +- .../action/update/UpdateAction.java | 21 - .../action/update/UpdateRequestBuilder.java | 4 +- .../internal/support/AbstractClient.java | 58 +- .../indices/RestReloadAnalyzersAction.java | 8 +- .../elasticsearch/script/package-info.java | 3 +- .../SynonymsManagementAPIService.java | 4 +- .../bulk/TransportBulkActionIngestTests.java | 4 +- .../get/TransportMultiGetActionTests.java | 2 +- .../AbstractClientHeadersTestCase.java | 21 +- .../health/ClusterStateHealthTests.java | 3 +- .../test/disruption/NetworkDisruptionIT.java | 55 +- .../core/ml/annotations/AnnotationIndex.java | 4 +- .../persistence/AnomalyDetectorsIndex.java | 4 +- .../authz/privilege/IndexPrivilege.java | 10 +- .../KibanaOwnedReservedRoleDescriptors.java | 17 +- .../authz/store/ReservedRolesStore.java | 10 +- .../core/security/user/InternalUsers.java | 4 +- .../xpack/core/ClientHelperTests.java | 4 +- .../notifications/AbstractAuditorTests.java | 14 +- ...pAliasesAndDeleteSourceIndexStepTests.java | 4 +- .../authz/privilege/IndexPrivilegeTests.java | 12 +- .../authz/privilege/PrivilegeTests.java | 6 +- .../authz/store/ReservedRolesStoreTests.java | 508 +++++++++++------- .../security/user/InternalUsersTests.java | 17 +- .../xpack/enrich/EnrichPolicyRunnerTests.java | 4 +- .../rules/RuleQueryBuilderTests.java | 4 +- .../AbstractEqlBlockingIntegTestCase.java | 4 +- .../ml/integration/DeleteExpiredDataIT.java | 4 +- .../integration/ModelSnapshotRetentionIT.java | 4 +- .../ml/integration/ModelSnapshotSearchIT.java | 4 +- .../xpack/ml/integration/JobsAndModelsIT.java | 4 +- .../xpack/ml/MlInitializationService.java | 4 +- .../TransportDeleteCalendarEventAction.java | 8 +- .../TransportFinalizeJobExecutionAction.java | 4 +- .../TransportPreviewDatafeedAction.java | 4 +- .../ml/action/TransportPutCalendarAction.java | 4 +- .../ml/action/TransportPutFilterAction.java | 4 +- .../action/TransportUpdateFilterAction.java | 8 +- .../scroll/ScrollDataExtractorFactory.java | 4 +- .../persistence/DatafeedConfigProvider.java | 106 ++-- .../ml/dataframe/DataFrameAnalyticsTask.java | 4 +- .../xpack/ml/dataframe/DestinationIndex.java | 4 +- .../ExtractedFieldsDetectorFactory.java | 4 +- .../DataFrameAnalyticsConfigProvider.java | 10 +- .../DataFrameAnalyticsDeleter.java | 4 +- .../xpack/ml/dataframe/steps/FinalStep.java | 4 +- .../persistence/TrainedModelProvider.java | 10 +- .../ml/job/persistence/JobConfigProvider.java | 60 ++- .../persistence/JobDataCountsPersister.java | 4 +- ...nsportFinalizeJobExecutionActionTests.java | 6 +- .../extractor/DataExtractorFactoryTests.java | 4 +- .../DataFrameAnalyticsTaskTests.java | 10 +- .../ml/dataframe/DestinationIndexTests.java | 8 +- .../TrainedModelProviderTests.java | 4 +- .../persistence/JobResultsPersisterTests.java | 6 +- .../AutodetectProcessManagerTests.java | 15 +- .../blob/BlobStoreCacheServiceTests.java | 10 +- ...lusterSecurityFcActionAuthorizationIT.java | 10 +- .../SecurityFeatureStateIntegTests.java | 4 +- .../security/authc/ApiKeyIntegTests.java | 4 +- .../authc/apikey/ApiKeySingleNodeTests.java | 10 +- .../security/authz/IndexAliasesTests.java | 32 +- .../security/authz/ReadActionsTests.java | 10 +- .../security/authz/WriteActionsTests.java | 6 +- .../user/AnonymousUserIntegTests.java | 4 +- .../action/filter/SecurityActionFilter.java | 4 +- .../xpack/security/authc/TokenService.java | 4 +- .../IndexServiceAccountTokenStore.java | 8 +- .../security/authz/AuthorizationService.java | 23 +- .../xpack/security/authz/RBACEngine.java | 20 +- .../security/profile/ProfileService.java | 40 +- .../transport/ServerTransportFilter.java | 4 +- .../filter/SecurityActionFilterTests.java | 4 +- ...ansportOpenIdConnectLogoutActionTests.java | 4 +- ...sportSamlInvalidateSessionActionTests.java | 4 +- .../saml/TransportSamlLogoutActionTests.java | 4 +- .../TransportCreateTokenActionTests.java | 4 +- .../HasPrivilegesRequestBuilderTests.java | 6 +- .../authc/AuthenticationServiceTests.java | 4 +- .../security/authc/TokenServiceTests.java | 4 +- .../service/ElasticServiceAccountsTests.java | 68 +-- .../authz/AuthorizationServiceTests.java | 106 ++-- .../authz/IndicesAndAliasesResolverTests.java | 54 +- .../xpack/security/authz/RBACEngineTests.java | 20 +- ...IndicesAliasesRequestInterceptorTests.java | 6 +- .../authz/permission/PermissionTests.java | 8 +- .../authz/store/CompositeRolesStoreTests.java | 64 ++- .../security/profile/ProfileServiceTests.java | 20 +- .../xpack/security/test/SecurityMocks.java | 4 +- .../transport/ServerTransportFilterTests.java | 4 +- .../history/SnapshotHistoryStoreTests.java | 7 +- .../sql/qa/security/SqlSecurityTestCase.java | 12 +- .../AbstractSqlBlockingIntegTestCase.java | 4 +- .../IndexBasedTransformConfigManager.java | 60 +-- .../transform/persistence/TransformIndex.java | 4 +- .../transforms/pivot/SchemaUtil.java | 6 +- .../persistence/TransformIndexTests.java | 4 +- 139 files changed, 1137 insertions(+), 1115 deletions(-) delete mode 100644 server/src/main/java/org/elasticsearch/action/admin/cluster/health/ClusterHealthAction.java delete mode 100644 server/src/main/java/org/elasticsearch/action/admin/cluster/tasks/PendingClusterTasksAction.java delete mode 100644 server/src/main/java/org/elasticsearch/action/admin/indices/alias/IndicesAliasesAction.java delete mode 100644 server/src/main/java/org/elasticsearch/action/admin/indices/analyze/ReloadAnalyzerAction.java delete mode 100644 server/src/main/java/org/elasticsearch/action/admin/indices/close/CloseIndexAction.java delete mode 100644 server/src/main/java/org/elasticsearch/action/delete/DeleteAction.java delete mode 100644 server/src/main/java/org/elasticsearch/action/fieldcaps/FieldCapabilitiesAction.java delete mode 100644 server/src/main/java/org/elasticsearch/action/get/GetAction.java delete mode 100644 server/src/main/java/org/elasticsearch/action/get/MultiGetAction.java delete mode 100644 server/src/main/java/org/elasticsearch/action/index/IndexAction.java delete mode 100644 server/src/main/java/org/elasticsearch/action/update/UpdateAction.java diff --git a/modules/analysis-common/src/internalClusterTest/java/org/elasticsearch/analysis/common/ReloadAnalyzerTests.java b/modules/analysis-common/src/internalClusterTest/java/org/elasticsearch/analysis/common/ReloadAnalyzerTests.java index 2ef1a7639e597..1014406745e1c 100644 --- a/modules/analysis-common/src/internalClusterTest/java/org/elasticsearch/analysis/common/ReloadAnalyzerTests.java +++ b/modules/analysis-common/src/internalClusterTest/java/org/elasticsearch/analysis/common/ReloadAnalyzerTests.java @@ -11,9 +11,9 @@ import org.elasticsearch.action.admin.indices.analyze.AnalyzeAction; import org.elasticsearch.action.admin.indices.analyze.AnalyzeAction.AnalyzeToken; import org.elasticsearch.action.admin.indices.analyze.AnalyzeAction.Response; -import org.elasticsearch.action.admin.indices.analyze.ReloadAnalyzerAction; import org.elasticsearch.action.admin.indices.analyze.ReloadAnalyzersRequest; import org.elasticsearch.action.admin.indices.analyze.ReloadAnalyzersResponse; +import org.elasticsearch.action.admin.indices.analyze.TransportReloadAnalyzersAction; import org.elasticsearch.index.mapper.MapperException; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.plugins.Plugin; @@ -121,7 +121,7 @@ private void updateSynonyms(Path synonymsFile, boolean preview) throws IOExcepti out.println("foo, baz, buzz"); } ReloadAnalyzersResponse reloadResponse = client().execute( - ReloadAnalyzerAction.INSTANCE, + TransportReloadAnalyzersAction.TYPE, new ReloadAnalyzersRequest(null, preview, INDEX_NAME) ).actionGet(); assertNoFailures(reloadResponse); @@ -183,7 +183,7 @@ public void testSynonymsInMultiplexerUpdateable() throws FileNotFoundException, out.println("foo, baz, buzz"); } ReloadAnalyzersResponse reloadResponse = client().execute( - ReloadAnalyzerAction.INSTANCE, + TransportReloadAnalyzersAction.TYPE, new ReloadAnalyzersRequest(null, false, INDEX_NAME) ).actionGet(); assertNoFailures(reloadResponse); @@ -303,7 +303,7 @@ public void testKeywordMarkerUpdateable() throws IOException { } ReloadAnalyzersResponse reloadResponse = client().execute( - ReloadAnalyzerAction.INSTANCE, + TransportReloadAnalyzersAction.TYPE, new ReloadAnalyzersRequest(null, false, INDEX_NAME) ).actionGet(); assertNoFailures(reloadResponse); diff --git a/modules/analysis-common/src/internalClusterTest/java/org/elasticsearch/analysis/common/ReloadSynonymAnalyzerIT.java b/modules/analysis-common/src/internalClusterTest/java/org/elasticsearch/analysis/common/ReloadSynonymAnalyzerIT.java index d55dbd0f1d783..e8164bfbb8f36 100644 --- a/modules/analysis-common/src/internalClusterTest/java/org/elasticsearch/analysis/common/ReloadSynonymAnalyzerIT.java +++ b/modules/analysis-common/src/internalClusterTest/java/org/elasticsearch/analysis/common/ReloadSynonymAnalyzerIT.java @@ -10,9 +10,9 @@ import org.elasticsearch.action.admin.indices.analyze.AnalyzeAction.AnalyzeToken; import org.elasticsearch.action.admin.indices.analyze.AnalyzeAction.Response; -import org.elasticsearch.action.admin.indices.analyze.ReloadAnalyzerAction; import org.elasticsearch.action.admin.indices.analyze.ReloadAnalyzersRequest; import org.elasticsearch.action.admin.indices.analyze.ReloadAnalyzersResponse; +import org.elasticsearch.action.admin.indices.analyze.TransportReloadAnalyzersAction; import org.elasticsearch.env.Environment; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.plugins.Plugin; @@ -91,7 +91,7 @@ private void testSynonymsUpdate(boolean preview) throws FileNotFoundException, I out.println("foo, baz, " + testTerm); } ReloadAnalyzersResponse reloadResponse = client().execute( - ReloadAnalyzerAction.INSTANCE, + TransportReloadAnalyzersAction.TYPE, new ReloadAnalyzersRequest(null, preview, "test") ).actionGet(); assertNoFailures(reloadResponse); diff --git a/modules/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpDownloaderTests.java b/modules/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpDownloaderTests.java index 5fedb357fff8e..7fdce03252687 100644 --- a/modules/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpDownloaderTests.java +++ b/modules/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpDownloaderTests.java @@ -21,9 +21,9 @@ import org.elasticsearch.action.admin.indices.refresh.RefreshAction; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.block.ClusterBlockException; import org.elasticsearch.cluster.block.ClusterBlocks; @@ -221,7 +221,7 @@ public void testIndexChunks() throws IOException { AtomicInteger chunkIndex = new AtomicInteger(); - client.addHandler(IndexAction.INSTANCE, (IndexRequest request, ActionListener listener) -> { + client.addHandler(TransportIndexAction.TYPE, (IndexRequest request, ActionListener listener) -> { int chunk = chunkIndex.getAndIncrement(); assertEquals(OpType.CREATE, request.opType()); assertThat(request.id(), Matchers.startsWith("test_" + (chunk + 15) + "_")); diff --git a/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/ClusterHealthRestCancellationIT.java b/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/ClusterHealthRestCancellationIT.java index 755bbce93c95b..f165f00c5cc2f 100644 --- a/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/ClusterHealthRestCancellationIT.java +++ b/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/ClusterHealthRestCancellationIT.java @@ -9,7 +9,7 @@ package org.elasticsearch.http; import org.apache.http.client.methods.HttpGet; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.client.Cancellable; import org.elasticsearch.client.Request; @@ -73,14 +73,14 @@ public void onFailure(Exception e) { safeAwait(barrier); - awaitTaskWithPrefixOnMaster(ClusterHealthAction.NAME); + awaitTaskWithPrefixOnMaster(TransportClusterHealthAction.NAME); logger.info("--> cancelling cluster health request"); cancellable.cancel(); expectThrows(CancellationException.class, future::actionGet); logger.info("--> checking cluster health task cancelled"); - assertAllCancellableTasksAreCancelled(ClusterHealthAction.NAME); + assertAllCancellableTasksAreCancelled(TransportClusterHealthAction.NAME); safeAwait(barrier); } diff --git a/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/RestActionCancellationIT.java b/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/RestActionCancellationIT.java index d46868094907d..acfd870576b21 100644 --- a/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/RestActionCancellationIT.java +++ b/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/RestActionCancellationIT.java @@ -10,7 +10,7 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.admin.cluster.state.ClusterStateAction; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesAction; import org.elasticsearch.action.admin.indices.recovery.RecoveryAction; @@ -50,7 +50,7 @@ public void testCatRecoveryRestCancellation() { } public void testClusterHealthRestCancellation() { - runRestActionCancellationTest(new Request(HttpGet.METHOD_NAME, "/_cluster/health"), ClusterHealthAction.NAME); + runRestActionCancellationTest(new Request(HttpGet.METHOD_NAME, "/_cluster/health"), TransportClusterHealthAction.NAME); } public void testClusterStateRestCancellation() { diff --git a/server/src/internalClusterTest/java/org/elasticsearch/action/IndicesRequestIT.java b/server/src/internalClusterTest/java/org/elasticsearch/action/IndicesRequestIT.java index e01241da4db91..36f317474f5a9 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/action/IndicesRequestIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/action/IndicesRequestIT.java @@ -12,8 +12,8 @@ import org.elasticsearch.action.admin.indices.analyze.AnalyzeAction; import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheAction; import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheRequest; -import org.elasticsearch.action.admin.indices.close.CloseIndexAction; import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; +import org.elasticsearch.action.admin.indices.close.TransportCloseIndexAction; import org.elasticsearch.action.admin.indices.delete.DeleteIndexAction; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.admin.indices.flush.FlushRequest; @@ -47,12 +47,12 @@ import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.explain.ExplainRequest; import org.elasticsearch.action.explain.TransportExplainAction; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest; -import org.elasticsearch.action.get.GetAction; +import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; import org.elasticsearch.action.get.GetRequest; -import org.elasticsearch.action.get.MultiGetAction; import org.elasticsearch.action.get.MultiGetRequest; +import org.elasticsearch.action.get.TransportGetAction; +import org.elasticsearch.action.get.TransportMultiGetAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchTransportService; @@ -62,7 +62,7 @@ import org.elasticsearch.action.termvectors.MultiTermVectorsRequest; import org.elasticsearch.action.termvectors.TermVectorsAction; import org.elasticsearch.action.termvectors.TermVectorsRequest; -import org.elasticsearch.action.update.UpdateAction; +import org.elasticsearch.action.update.TransportUpdateAction; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.internal.Requests; @@ -181,7 +181,7 @@ public void testGetFieldMappings() { } public void testFieldCapabilities() { - String fieldCapabilitiesShardAction = FieldCapabilitiesAction.NAME + "[n]"; + String fieldCapabilitiesShardAction = TransportFieldCapabilitiesAction.NAME + "[n]"; interceptTransportActions(fieldCapabilitiesShardAction); FieldCapabilitiesRequest fieldCapabilitiesRequest = new FieldCapabilitiesRequest(); @@ -229,7 +229,10 @@ public void testDelete() { public void testUpdate() { // update action goes to the primary, index op gets executed locally, then replicated - String[] updateShardActions = new String[] { UpdateAction.NAME + "[s]", BulkAction.NAME + "[s][p]", BulkAction.NAME + "[s][r]" }; + String[] updateShardActions = new String[] { + TransportUpdateAction.NAME + "[s]", + BulkAction.NAME + "[s][p]", + BulkAction.NAME + "[s][r]" }; interceptTransportActions(updateShardActions); String indexOrAlias = randomIndexOrAlias(); @@ -244,7 +247,10 @@ public void testUpdate() { public void testUpdateUpsert() { // update action goes to the primary, index op gets executed locally, then replicated - String[] updateShardActions = new String[] { UpdateAction.NAME + "[s]", BulkAction.NAME + "[s][p]", BulkAction.NAME + "[s][r]" }; + String[] updateShardActions = new String[] { + TransportUpdateAction.NAME + "[s]", + BulkAction.NAME + "[s][p]", + BulkAction.NAME + "[s][r]" }; interceptTransportActions(updateShardActions); String indexOrAlias = randomIndexOrAlias(); @@ -259,7 +265,10 @@ public void testUpdateUpsert() { public void testUpdateDelete() { // update action goes to the primary, delete op gets executed locally, then replicated - String[] updateShardActions = new String[] { UpdateAction.NAME + "[s]", BulkAction.NAME + "[s][p]", BulkAction.NAME + "[s][r]" }; + String[] updateShardActions = new String[] { + TransportUpdateAction.NAME + "[s]", + BulkAction.NAME + "[s][p]", + BulkAction.NAME + "[s][r]" }; interceptTransportActions(updateShardActions); String indexOrAlias = randomIndexOrAlias(); @@ -306,7 +315,7 @@ public void testBulk() { } public void testGet() { - String getShardAction = GetAction.NAME + "[s]"; + String getShardAction = TransportGetAction.TYPE.name() + "[s]"; interceptTransportActions(getShardAction); GetRequest getRequest = new GetRequest(randomIndexOrAlias(), "id"); @@ -357,7 +366,7 @@ public void testMultiTermVector() { } public void testMultiGet() { - String multiGetShardAction = MultiGetAction.NAME + "[shard][s]"; + String multiGetShardAction = TransportMultiGetAction.NAME + "[shard][s]"; interceptTransportActions(multiGetShardAction); List indicesOrAliases = new ArrayList<>(); @@ -483,13 +492,13 @@ public void testOpenIndex() { } public void testCloseIndex() { - interceptTransportActions(CloseIndexAction.NAME); + interceptTransportActions(TransportCloseIndexAction.NAME); CloseIndexRequest closeIndexRequest = new CloseIndexRequest(randomUniqueIndicesOrAliases()); internalCluster().coordOnlyNodeClient().admin().indices().close(closeIndexRequest).actionGet(); clearInterceptedActions(); - assertSameIndices(closeIndexRequest, CloseIndexAction.NAME); + assertSameIndices(closeIndexRequest, TransportCloseIndexAction.NAME); } public void testDeleteIndex() { diff --git a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/node/tasks/TasksIT.java b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/node/tasks/TasksIT.java index 502c60b4a3402..1a230154b27bf 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/node/tasks/TasksIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/node/tasks/TasksIT.java @@ -15,7 +15,7 @@ import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.action.TaskOperationFailure; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.admin.cluster.node.tasks.cancel.CancelTasksResponse; import org.elasticsearch.action.admin.cluster.node.tasks.get.GetTaskRequest; import org.elasticsearch.action.admin.cluster.node.tasks.get.GetTaskResponse; @@ -25,7 +25,7 @@ import org.elasticsearch.action.admin.indices.refresh.RefreshAction; import org.elasticsearch.action.admin.indices.validate.query.ValidateQueryAction; import org.elasticsearch.action.bulk.BulkAction; -import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.SearchTransportService; import org.elasticsearch.action.search.TransportSearchAction; import org.elasticsearch.action.support.WriteRequest; @@ -136,24 +136,24 @@ public void testTaskCounts() { } public void testMasterNodeOperationTasks() throws Exception { - registerTaskManagerListeners(ClusterHealthAction.NAME); + registerTaskManagerListeners(TransportClusterHealthAction.NAME); // First run the health on the master node - should produce only one task on the master node internalCluster().masterClient().admin().cluster().prepareHealth().get(); - assertEquals(1, numberOfEvents(ClusterHealthAction.NAME, Tuple::v1)); // counting only registration events + assertEquals(1, numberOfEvents(TransportClusterHealthAction.NAME, Tuple::v1)); // counting only registration events // counting only unregistration events // When checking unregistration events there might be some delay since receiving the response from the cluster doesn't // guarantee that the task has been unregistered. - assertBusy(() -> assertEquals(1, numberOfEvents(ClusterHealthAction.NAME, event -> event.v1() == false))); + assertBusy(() -> assertEquals(1, numberOfEvents(TransportClusterHealthAction.NAME, event -> event.v1() == false))); - resetTaskManagerListeners(ClusterHealthAction.NAME); + resetTaskManagerListeners(TransportClusterHealthAction.NAME); // Now run the health on a non-master node - should produce one task on master and one task on another node internalCluster().nonMasterClient().admin().cluster().prepareHealth().get(); - assertEquals(2, numberOfEvents(ClusterHealthAction.NAME, Tuple::v1)); // counting only registration events + assertEquals(2, numberOfEvents(TransportClusterHealthAction.NAME, Tuple::v1)); // counting only registration events // counting only unregistration events - assertBusy(() -> assertEquals(2, numberOfEvents(ClusterHealthAction.NAME, event -> event.v1() == false))); - List tasks = findEvents(ClusterHealthAction.NAME, Tuple::v1); + assertBusy(() -> assertEquals(2, numberOfEvents(TransportClusterHealthAction.NAME, event -> event.v1() == false))); + List tasks = findEvents(TransportClusterHealthAction.NAME, Tuple::v1); // Verify that one of these tasks is a parent of another task if (tasks.get(0).parentTaskId().isSet()) { @@ -433,7 +433,7 @@ public void testCanFetchIndexStatus() throws Exception { ((MockTaskManager) transportService.getTaskManager()).addListener(new MockTaskManagerListener() { @Override public void onTaskRegistered(Task task) { - if (task.getAction().startsWith(IndexAction.NAME)) { + if (task.getAction().startsWith(TransportIndexAction.NAME)) { taskRegistered.countDown(); logger.debug("Blocking [{}] starting", task); try { diff --git a/server/src/internalClusterTest/java/org/elasticsearch/search/fieldcaps/FieldCapabilitiesIT.java b/server/src/internalClusterTest/java/org/elasticsearch/search/fieldcaps/FieldCapabilitiesIT.java index 02867e0cf6920..6139d6875d5ae 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/search/fieldcaps/FieldCapabilitiesIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/search/fieldcaps/FieldCapabilitiesIT.java @@ -14,7 +14,6 @@ import org.apache.lucene.util.BytesRef; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.fieldcaps.FieldCapabilities; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesFailure; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse; @@ -478,7 +477,7 @@ public void testTargetNodeFails() throws Exception { if (randomBoolean()) { request.indexFilter(QueryBuilders.rangeQuery("timestamp").gte("2020-01-01")); } - final FieldCapabilitiesResponse response = client().execute(FieldCapabilitiesAction.INSTANCE, request).actionGet(); + final FieldCapabilitiesResponse response = client().execute(TransportFieldCapabilitiesAction.TYPE, request).actionGet(); assertTrue(failedRequest.get()); assertThat(response.getIndices(), arrayContainingInAnyOrder("log-index-1", "log-index-2")); assertThat(response.getField("field1"), aMapWithSize(2)); @@ -512,7 +511,7 @@ public void testNoActiveCopy() throws Exception { if (randomBoolean()) { request.indexFilter(QueryBuilders.rangeQuery("timestamp").gte("2020-01-01")); } - final FieldCapabilitiesResponse response = client().execute(FieldCapabilitiesAction.INSTANCE, request).actionGet(); + final FieldCapabilitiesResponse response = client().execute(TransportFieldCapabilitiesAction.TYPE, request).actionGet(); assertThat(response.getIndices(), arrayContainingInAnyOrder("log-index-1", "log-index-2")); assertThat(response.getField("field1"), aMapWithSize(2)); assertThat(response.getField("field1"), hasKey("long")); @@ -574,7 +573,7 @@ public void testRelocation() throws Exception { if (randomBoolean()) { request.indexFilter(QueryBuilders.rangeQuery("timestamp").gte("2020-01-01")); } - final FieldCapabilitiesResponse response = client().execute(FieldCapabilitiesAction.INSTANCE, request).actionGet(); + final FieldCapabilitiesResponse response = client().execute(TransportFieldCapabilitiesAction.TYPE, request).actionGet(); assertThat(response.getIndices(), arrayContainingInAnyOrder("log-index-1", "log-index-2")); assertThat(response.getField("field1"), aMapWithSize(2)); assertThat(response.getField("field1"), hasKey("long")); @@ -630,7 +629,7 @@ public void testManyIndicesWithSameMapping() { } }; // Single mapping - verifyResponse.accept(client().execute(FieldCapabilitiesAction.INSTANCE, request).actionGet()); + verifyResponse.accept(client().execute(TransportFieldCapabilitiesAction.TYPE, request).actionGet()); // add an extra field for some indices String[] indicesWithExtraField = randomSubsetOf(between(1, indices.length), indices).stream().sorted().toArray(String[]::new); @@ -639,7 +638,7 @@ public void testManyIndicesWithSameMapping() { for (String index : indicesWithExtraField) { prepareIndex(index).setSource("extra_field", randomIntBetween(1, 1000)).get(); } - FieldCapabilitiesResponse resp = client().execute(FieldCapabilitiesAction.INSTANCE, request).actionGet(); + FieldCapabilitiesResponse resp = client().execute(TransportFieldCapabilitiesAction.TYPE, request).actionGet(); verifyResponse.accept(resp); assertThat(resp.getField("extra_field"), hasKey("integer")); assertThat(resp.getField("extra_field").get("integer").indices(), nullValue()); diff --git a/server/src/main/java/org/elasticsearch/action/ActionModule.java b/server/src/main/java/org/elasticsearch/action/ActionModule.java index 8e008dc57c81b..01e51d47722f6 100644 --- a/server/src/main/java/org/elasticsearch/action/ActionModule.java +++ b/server/src/main/java/org/elasticsearch/action/ActionModule.java @@ -29,7 +29,6 @@ import org.elasticsearch.action.admin.cluster.desirednodes.TransportGetDesiredNodesAction; import org.elasticsearch.action.admin.cluster.desirednodes.TransportUpdateDesiredNodesAction; import org.elasticsearch.action.admin.cluster.desirednodes.UpdateDesiredNodesAction; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.admin.cluster.migration.GetFeatureUpgradeStatusAction; import org.elasticsearch.action.admin.cluster.migration.PostFeatureUpgradeAction; @@ -102,20 +101,16 @@ import org.elasticsearch.action.admin.cluster.storedscripts.TransportGetScriptLanguageAction; import org.elasticsearch.action.admin.cluster.storedscripts.TransportGetStoredScriptAction; import org.elasticsearch.action.admin.cluster.storedscripts.TransportPutStoredScriptAction; -import org.elasticsearch.action.admin.cluster.tasks.PendingClusterTasksAction; import org.elasticsearch.action.admin.cluster.tasks.TransportPendingClusterTasksAction; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.TransportIndicesAliasesAction; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesAction; import org.elasticsearch.action.admin.indices.alias.get.TransportGetAliasesAction; import org.elasticsearch.action.admin.indices.analyze.AnalyzeAction; -import org.elasticsearch.action.admin.indices.analyze.ReloadAnalyzerAction; import org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction; import org.elasticsearch.action.admin.indices.analyze.TransportReloadAnalyzersAction; import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheAction; import org.elasticsearch.action.admin.indices.cache.clear.TransportClearIndicesCacheAction; -import org.elasticsearch.action.admin.indices.close.CloseIndexAction; import org.elasticsearch.action.admin.indices.close.TransportCloseIndexAction; import org.elasticsearch.action.admin.indices.close.TransportVerifyShardBeforeCloseAction; import org.elasticsearch.action.admin.indices.create.AutoCreateAction; @@ -206,17 +201,12 @@ import org.elasticsearch.action.bulk.TransportBulkAction; import org.elasticsearch.action.bulk.TransportShardBulkAction; import org.elasticsearch.action.bulk.TransportSimulateBulkAction; -import org.elasticsearch.action.delete.DeleteAction; import org.elasticsearch.action.delete.TransportDeleteAction; import org.elasticsearch.action.explain.TransportExplainAction; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; -import org.elasticsearch.action.get.GetAction; -import org.elasticsearch.action.get.MultiGetAction; import org.elasticsearch.action.get.TransportGetAction; import org.elasticsearch.action.get.TransportMultiGetAction; import org.elasticsearch.action.get.TransportShardMultiGetAction; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.ingest.DeletePipelineAction; import org.elasticsearch.action.ingest.DeletePipelineTransportAction; @@ -262,7 +252,6 @@ import org.elasticsearch.action.termvectors.TransportShardMultiTermsVectorAction; import org.elasticsearch.action.termvectors.TransportTermVectorsAction; import org.elasticsearch.action.update.TransportUpdateAction; -import org.elasticsearch.action.update.UpdateAction; import org.elasticsearch.client.internal.node.NodeClient; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.node.DiscoveryNodes; @@ -682,13 +671,13 @@ public void reg actions.register(DeleteDesiredBalanceAction.INSTANCE, TransportDeleteDesiredBalanceAction.class); actions.register(ClusterStatsAction.INSTANCE, TransportClusterStatsAction.class); actions.register(ClusterStateAction.INSTANCE, TransportClusterStateAction.class); - actions.register(ClusterHealthAction.INSTANCE, TransportClusterHealthAction.class); + actions.register(TransportClusterHealthAction.TYPE, TransportClusterHealthAction.class); actions.register(ClusterUpdateSettingsAction.INSTANCE, TransportClusterUpdateSettingsAction.class); actions.register(ClusterGetSettingsAction.INSTANCE, TransportClusterGetSettingsAction.class); actions.register(ClusterRerouteAction.INSTANCE, TransportClusterRerouteAction.class); actions.register(ClusterSearchShardsAction.INSTANCE, TransportClusterSearchShardsAction.class); actions.register(ClusterFormationInfoAction.INSTANCE, ClusterFormationInfoAction.TransportAction.class); - actions.register(PendingClusterTasksAction.INSTANCE, TransportPendingClusterTasksAction.class); + actions.register(TransportPendingClusterTasksAction.TYPE, TransportPendingClusterTasksAction.class); actions.register(PutRepositoryAction.INSTANCE, TransportPutRepositoryAction.class); actions.register(GetRepositoriesAction.INSTANCE, TransportGetRepositoriesAction.class); actions.register(DeleteRepositoryAction.INSTANCE, TransportDeleteRepositoryAction.class); @@ -715,17 +704,17 @@ public void reg actions.register(DeleteIndexAction.INSTANCE, TransportDeleteIndexAction.class); actions.register(GetIndexAction.INSTANCE, TransportGetIndexAction.class); actions.register(OpenIndexAction.INSTANCE, TransportOpenIndexAction.class); - actions.register(CloseIndexAction.INSTANCE, TransportCloseIndexAction.class); + actions.register(TransportCloseIndexAction.TYPE, TransportCloseIndexAction.class); actions.register(AddIndexBlockAction.INSTANCE, TransportAddIndexBlockAction.class); actions.register(GetMappingsAction.INSTANCE, TransportGetMappingsAction.class); actions.register(GetFieldMappingsAction.INSTANCE, TransportGetFieldMappingsAction.class); actions.register(TransportGetFieldMappingsIndexAction.TYPE, TransportGetFieldMappingsIndexAction.class); actions.register(PutMappingAction.INSTANCE, TransportPutMappingAction.class); actions.register(AutoPutMappingAction.INSTANCE, TransportAutoPutMappingAction.class); - actions.register(IndicesAliasesAction.INSTANCE, TransportIndicesAliasesAction.class); + actions.register(TransportIndicesAliasesAction.TYPE, TransportIndicesAliasesAction.class); actions.register(UpdateSettingsAction.INSTANCE, TransportUpdateSettingsAction.class); actions.register(AnalyzeAction.INSTANCE, TransportAnalyzeAction.class); - actions.register(ReloadAnalyzerAction.INSTANCE, TransportReloadAnalyzersAction.class); + actions.register(TransportReloadAnalyzersAction.TYPE, TransportReloadAnalyzersAction.class); actions.register(PutIndexTemplateAction.INSTANCE, TransportPutIndexTemplateAction.class); actions.register(GetIndexTemplatesAction.INSTANCE, TransportGetIndexTemplatesAction.class); actions.register(DeleteIndexTemplateAction.INSTANCE, TransportDeleteIndexTemplateAction.class); @@ -745,14 +734,14 @@ public void reg actions.register(GetAliasesAction.INSTANCE, TransportGetAliasesAction.class); actions.register(GetSettingsAction.INSTANCE, TransportGetSettingsAction.class); - actions.register(IndexAction.INSTANCE, TransportIndexAction.class); - actions.register(GetAction.INSTANCE, TransportGetAction.class); + actions.register(TransportIndexAction.TYPE, TransportIndexAction.class); + actions.register(TransportGetAction.TYPE, TransportGetAction.class); actions.register(TermVectorsAction.INSTANCE, TransportTermVectorsAction.class); actions.register(MultiTermVectorsAction.INSTANCE, TransportMultiTermVectorsAction.class); actions.register(TransportShardMultiTermsVectorAction.TYPE, TransportShardMultiTermsVectorAction.class); - actions.register(DeleteAction.INSTANCE, TransportDeleteAction.class); - actions.register(UpdateAction.INSTANCE, TransportUpdateAction.class); - actions.register(MultiGetAction.INSTANCE, TransportMultiGetAction.class); + actions.register(TransportDeleteAction.TYPE, TransportDeleteAction.class); + actions.register(TransportUpdateAction.TYPE, TransportUpdateAction.class); + actions.register(TransportMultiGetAction.TYPE, TransportMultiGetAction.class); actions.register(TransportShardMultiGetAction.TYPE, TransportShardMultiGetAction.class); actions.register(BulkAction.INSTANCE, TransportBulkAction.class); actions.register(SimulateBulkAction.INSTANCE, TransportSimulateBulkAction.class); @@ -781,7 +770,7 @@ public void reg actions.register(GetScriptContextAction.INSTANCE, TransportGetScriptContextAction.class); actions.register(GetScriptLanguageAction.INSTANCE, TransportGetScriptLanguageAction.class); - actions.register(FieldCapabilitiesAction.INSTANCE, TransportFieldCapabilitiesAction.class); + actions.register(TransportFieldCapabilitiesAction.TYPE, TransportFieldCapabilitiesAction.class); actions.register(PutPipelineAction.INSTANCE, PutPipelineTransportAction.class); actions.register(GetPipelineAction.INSTANCE, GetPipelineTransportAction.class); diff --git a/server/src/main/java/org/elasticsearch/action/DocWriteResponse.java b/server/src/main/java/org/elasticsearch/action/DocWriteResponse.java index b6e5a51c117b7..230a8154b64ce 100644 --- a/server/src/main/java/org/elasticsearch/action/DocWriteResponse.java +++ b/server/src/main/java/org/elasticsearch/action/DocWriteResponse.java @@ -131,7 +131,7 @@ protected DocWriteResponse(ShardId shardId, StreamInput in) throws IOException { } /** - * Needed for deserialization of single item requests in {@link org.elasticsearch.action.index.IndexAction} and BwC + * Needed for deserialization of single item requests in {@link org.elasticsearch.action.index.TransportIndexAction} and BwC * deserialization path */ protected DocWriteResponse(StreamInput in) throws IOException { diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/health/ClusterHealthAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/health/ClusterHealthAction.java deleted file mode 100644 index 369c11a7e6290..0000000000000 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/health/ClusterHealthAction.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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.action.admin.cluster.health; - -import org.elasticsearch.action.ActionType; - -public class ClusterHealthAction extends ActionType { - - public static final ClusterHealthAction INSTANCE = new ClusterHealthAction(); - public static final String NAME = "cluster:monitor/health"; - - private ClusterHealthAction() { - super(NAME, ClusterHealthResponse::new); - } -} diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/health/ClusterHealthRequestBuilder.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/health/ClusterHealthRequestBuilder.java index e69c8862a4885..cfd1fd71b612e 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/health/ClusterHealthRequestBuilder.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/health/ClusterHealthRequestBuilder.java @@ -22,7 +22,7 @@ public class ClusterHealthRequestBuilder extends MasterNodeReadOperationRequestB ClusterHealthRequestBuilder> { public ClusterHealthRequestBuilder(ElasticsearchClient client) { - super(client, ClusterHealthAction.INSTANCE, new ClusterHealthRequest()); + super(client, TransportClusterHealthAction.TYPE, new ClusterHealthRequest()); } public ClusterHealthRequestBuilder setIndices(String... indices) { diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/health/TransportClusterHealthAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/health/TransportClusterHealthAction.java index 935cc15eefe51..5af2d546ac624 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/health/TransportClusterHealthAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/health/TransportClusterHealthAction.java @@ -12,6 +12,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.ActionType; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.ActiveShardCount; import org.elasticsearch.action.support.IndicesOptions; @@ -47,6 +48,8 @@ public class TransportClusterHealthAction extends TransportMasterNodeReadAction { + public static final String NAME = "cluster:monitor/health"; + public static final ActionType TYPE = new ActionType(NAME, ClusterHealthResponse::new); private static final Logger logger = LogManager.getLogger(TransportClusterHealthAction.class); private final AllocationService allocationService; @@ -61,7 +64,7 @@ public TransportClusterHealthAction( AllocationService allocationService ) { super( - ClusterHealthAction.NAME, + NAME, false, transportService, clusterService, @@ -157,6 +160,7 @@ public void onFailure(Exception e) { } else { final TimeValue taskTimeout = TimeValue.timeValueMillis(Math.max(0, endTimeRelativeMillis - threadPool.relativeTimeInMillis())); submitUnbatchedTask(source, new ClusterStateUpdateTask(request.waitForEvents(), taskTimeout) { + @Override public ClusterState execute(ClusterState currentState) { return currentState; @@ -207,6 +211,7 @@ static boolean isExpectedFailure(Exception e) { && e.getCause() instanceof EsRejectedExecutionException esre && esre.isExecutorShutdown(); } + }); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/tasks/PendingClusterTasksAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/tasks/PendingClusterTasksAction.java deleted file mode 100644 index ee76bd89fce3c..0000000000000 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/tasks/PendingClusterTasksAction.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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.action.admin.cluster.tasks; - -import org.elasticsearch.action.ActionType; - -public class PendingClusterTasksAction extends ActionType { - - public static final PendingClusterTasksAction INSTANCE = new PendingClusterTasksAction(); - public static final String NAME = "cluster:monitor/task"; - - private PendingClusterTasksAction() { - super(NAME, PendingClusterTasksResponse::new); - } -} diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/tasks/PendingClusterTasksRequestBuilder.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/tasks/PendingClusterTasksRequestBuilder.java index 4de6d262a06e2..aa3f226d23c9d 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/tasks/PendingClusterTasksRequestBuilder.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/tasks/PendingClusterTasksRequestBuilder.java @@ -17,6 +17,6 @@ public class PendingClusterTasksRequestBuilder extends MasterNodeReadOperationRe PendingClusterTasksRequestBuilder> { public PendingClusterTasksRequestBuilder(ElasticsearchClient client) { - super(client, PendingClusterTasksAction.INSTANCE, new PendingClusterTasksRequest()); + super(client, TransportPendingClusterTasksAction.TYPE, new PendingClusterTasksRequest()); } } 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 ba7e799095ef8..a03f0d36f7dad 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 @@ -11,6 +11,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.ActionType; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.master.TransportMasterNodeReadAction; import org.elasticsearch.cluster.ClusterState; @@ -30,6 +31,10 @@ public class TransportPendingClusterTasksAction extends TransportMasterNodeReadA PendingClusterTasksRequest, PendingClusterTasksResponse> { + public static final ActionType TYPE = new ActionType<>( + "cluster:monitor/task", + PendingClusterTasksResponse::new + ); private static final Logger logger = LogManager.getLogger(TransportPendingClusterTasksAction.class); private final ClusterService clusterService; @@ -43,7 +48,7 @@ public TransportPendingClusterTasksAction( IndexNameExpressionResolver indexNameExpressionResolver ) { super( - PendingClusterTasksAction.NAME, + TYPE.name(), transportService, clusterService, threadPool, diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/IndicesAliasesAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/IndicesAliasesAction.java deleted file mode 100644 index 6c3a5ec3eabc6..0000000000000 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/IndicesAliasesAction.java +++ /dev/null @@ -1,23 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.action.admin.indices.alias; - -import org.elasticsearch.action.ActionType; -import org.elasticsearch.action.support.master.AcknowledgedResponse; - -public class IndicesAliasesAction extends ActionType { - - public static final IndicesAliasesAction INSTANCE = new IndicesAliasesAction(); - public static final String NAME = "indices:admin/aliases"; - - private IndicesAliasesAction() { - super(NAME, AcknowledgedResponse::readFrom); - } - -} diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/IndicesAliasesRequestBuilder.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/IndicesAliasesRequestBuilder.java index 47aaf53bd1c98..4e49a5fe8d400 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/IndicesAliasesRequestBuilder.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/IndicesAliasesRequestBuilder.java @@ -25,7 +25,7 @@ public class IndicesAliasesRequestBuilder extends AcknowledgedRequestBuilder< IndicesAliasesRequestBuilder> { public IndicesAliasesRequestBuilder(ElasticsearchClient client) { - super(client, IndicesAliasesAction.INSTANCE, new IndicesAliasesRequest()); + super(client, TransportIndicesAliasesAction.TYPE, new IndicesAliasesRequest()); } /** 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 fd3a200075d75..66a489933c3ee 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 @@ -11,6 +11,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.ActionType; import org.elasticsearch.action.RequestValidators; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions; import org.elasticsearch.action.support.ActionFilters; @@ -57,6 +58,8 @@ */ public class TransportIndicesAliasesAction extends AcknowledgedTransportMasterNodeAction { + public static final String NAME = "indices:admin/aliases"; + public static final ActionType TYPE = new ActionType<>(NAME, AcknowledgedResponse::readFrom); private static final Logger logger = LogManager.getLogger(TransportIndicesAliasesAction.class); private final MetadataIndexAliasesService indexAliasesService; @@ -75,7 +78,7 @@ public TransportIndicesAliasesAction( final SystemIndices systemIndices ) { super( - IndicesAliasesAction.NAME, + NAME, transportService, clusterService, threadPool, diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/analyze/ReloadAnalyzerAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/analyze/ReloadAnalyzerAction.java deleted file mode 100644 index fb96ee1860392..0000000000000 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/analyze/ReloadAnalyzerAction.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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.action.admin.indices.analyze; - -import org.elasticsearch.action.ActionType; - -public class ReloadAnalyzerAction extends ActionType { - - public static final ReloadAnalyzerAction INSTANCE = new ReloadAnalyzerAction(); - public static final String NAME = "indices:admin/reload_analyzers"; - - private ReloadAnalyzerAction() { - super(NAME, ReloadAnalyzersResponse::new); - } -} 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 01e02b46b9cb7..2930d578a7b2f 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 @@ -11,6 +11,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.ActionType; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.broadcast.node.TransportBroadcastByNodeAction; import org.elasticsearch.cluster.ClusterState; @@ -50,6 +51,10 @@ public class TransportReloadAnalyzersAction extends TransportBroadcastByNodeActi ReloadAnalyzersResponse, TransportReloadAnalyzersAction.ReloadResult> { + public static final ActionType TYPE = new ActionType<>( + "indices:admin/reload_analyzers", + ReloadAnalyzersResponse::new + ); private static final Logger logger = LogManager.getLogger(TransportReloadAnalyzersAction.class); private final IndicesService indicesService; @@ -62,7 +67,7 @@ public TransportReloadAnalyzersAction( IndexNameExpressionResolver indexNameExpressionResolver ) { super( - ReloadAnalyzerAction.NAME, + TYPE.name(), clusterService, transportService, actionFilters, diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/close/CloseIndexAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/close/CloseIndexAction.java deleted file mode 100644 index 02afb59081131..0000000000000 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/close/CloseIndexAction.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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.action.admin.indices.close; - -import org.elasticsearch.action.ActionType; - -public class CloseIndexAction extends ActionType { - - public static final CloseIndexAction INSTANCE = new CloseIndexAction(); - public static final String NAME = "indices:admin/close"; - - private CloseIndexAction() { - super(NAME, CloseIndexResponse::new); - } -} diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/close/CloseIndexRequestBuilder.java b/server/src/main/java/org/elasticsearch/action/admin/indices/close/CloseIndexRequestBuilder.java index 0a9d7fb1bcf7a..0b19a9f6eb69a 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/close/CloseIndexRequestBuilder.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/close/CloseIndexRequestBuilder.java @@ -19,7 +19,7 @@ public class CloseIndexRequestBuilder extends AcknowledgedRequestBuilder { public CloseIndexRequestBuilder(ElasticsearchClient client, String... indices) { - super(client, CloseIndexAction.INSTANCE, new CloseIndexRequest(indices)); + super(client, TransportCloseIndexAction.TYPE, new CloseIndexRequest(indices)); } /** 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 0103e8abf654a..f4a65a2b6490f 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 @@ -11,6 +11,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.ActionType; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.DestructiveOperations; import org.elasticsearch.action.support.master.TransportMasterNodeAction; @@ -39,6 +40,8 @@ */ public class TransportCloseIndexAction extends TransportMasterNodeAction { + public static final String NAME = "indices:admin/close"; + public static final ActionType TYPE = new ActionType<>(NAME, CloseIndexResponse::new); private static final Logger logger = LogManager.getLogger(TransportCloseIndexAction.class); private final MetadataIndexStateService indexStateService; @@ -64,7 +67,7 @@ public TransportCloseIndexAction( DestructiveOperations destructiveOperations ) { super( - CloseIndexAction.NAME, + NAME, transportService, clusterService, threadPool, 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 c8ecbf273c93c..c5b5602a963d4 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 @@ -41,7 +41,7 @@ public class TransportVerifyShardBeforeCloseAction extends TransportReplicationA TransportVerifyShardBeforeCloseAction.ShardRequest, ReplicationResponse> { - public static final String NAME = CloseIndexAction.NAME + "[s]"; + public static final String NAME = TransportCloseIndexAction.NAME + "[s]"; public static final ActionType TYPE = new ActionType<>(NAME, ReplicationResponse::new); private static final Logger logger = LogManager.getLogger(TransportVerifyShardBeforeCloseAction.class); diff --git a/server/src/main/java/org/elasticsearch/action/delete/DeleteAction.java b/server/src/main/java/org/elasticsearch/action/delete/DeleteAction.java deleted file mode 100644 index 9a16cb8dd4eec..0000000000000 --- a/server/src/main/java/org/elasticsearch/action/delete/DeleteAction.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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.action.delete; - -import org.elasticsearch.action.ActionType; - -public class DeleteAction extends ActionType { - - public static final DeleteAction INSTANCE = new DeleteAction(); - public static final String NAME = "indices:data/write/delete"; - - private DeleteAction() { - super(NAME, DeleteResponse::new); - } -} diff --git a/server/src/main/java/org/elasticsearch/action/delete/DeleteRequestBuilder.java b/server/src/main/java/org/elasticsearch/action/delete/DeleteRequestBuilder.java index 7107073b6b738..f99bea1a64821 100644 --- a/server/src/main/java/org/elasticsearch/action/delete/DeleteRequestBuilder.java +++ b/server/src/main/java/org/elasticsearch/action/delete/DeleteRequestBuilder.java @@ -22,7 +22,7 @@ public class DeleteRequestBuilder extends ReplicationRequestBuilder { public DeleteRequestBuilder(ElasticsearchClient client, @Nullable String index) { - super(client, DeleteAction.INSTANCE, new DeleteRequest(index)); + super(client, TransportDeleteAction.TYPE, new DeleteRequest(index)); } /** 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 0b6824a1c7c49..6c275d994a4ed 100644 --- a/server/src/main/java/org/elasticsearch/action/delete/TransportDeleteAction.java +++ b/server/src/main/java/org/elasticsearch/action/delete/TransportDeleteAction.java @@ -8,6 +8,7 @@ package org.elasticsearch.action.delete; +import org.elasticsearch.action.ActionType; import org.elasticsearch.action.bulk.TransportBulkAction; import org.elasticsearch.action.bulk.TransportSingleItemBulkWriteAction; import org.elasticsearch.action.support.ActionFilters; @@ -22,8 +23,11 @@ @Deprecated public class TransportDeleteAction extends TransportSingleItemBulkWriteAction { + public static final String NAME = "indices:data/write/delete"; + public static final ActionType TYPE = new ActionType<>(NAME, DeleteResponse::new); + @Inject public TransportDeleteAction(TransportService transportService, ActionFilters actionFilters, TransportBulkAction bulkAction) { - super(DeleteAction.NAME, transportService, actionFilters, DeleteRequest::new, bulkAction); + super(NAME, transportService, actionFilters, DeleteRequest::new, bulkAction); } } diff --git a/server/src/main/java/org/elasticsearch/action/fieldcaps/FieldCapabilitiesAction.java b/server/src/main/java/org/elasticsearch/action/fieldcaps/FieldCapabilitiesAction.java deleted file mode 100644 index eb63f844f49bf..0000000000000 --- a/server/src/main/java/org/elasticsearch/action/fieldcaps/FieldCapabilitiesAction.java +++ /dev/null @@ -1,22 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.action.fieldcaps; - -import org.elasticsearch.action.ActionType; - -public class FieldCapabilitiesAction extends ActionType { - - public static final FieldCapabilitiesAction INSTANCE = new FieldCapabilitiesAction(); - public static final String NAME = "indices:data/read/field_caps"; - - private FieldCapabilitiesAction() { - super(NAME, FieldCapabilitiesResponse::new); - } - -} diff --git a/server/src/main/java/org/elasticsearch/action/fieldcaps/FieldCapabilitiesRequestBuilder.java b/server/src/main/java/org/elasticsearch/action/fieldcaps/FieldCapabilitiesRequestBuilder.java index 892a08c837949..511988cf561b9 100644 --- a/server/src/main/java/org/elasticsearch/action/fieldcaps/FieldCapabilitiesRequestBuilder.java +++ b/server/src/main/java/org/elasticsearch/action/fieldcaps/FieldCapabilitiesRequestBuilder.java @@ -16,7 +16,7 @@ public class FieldCapabilitiesRequestBuilder extends ActionRequestBuilder { public FieldCapabilitiesRequestBuilder(ElasticsearchClient client, String... indices) { - super(client, FieldCapabilitiesAction.INSTANCE, new FieldCapabilitiesRequest().indices(indices)); + super(client, TransportFieldCapabilitiesAction.TYPE, new FieldCapabilitiesRequest().indices(indices)); } /** 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 d9837f94b0996..2e3dd1ab443f9 100644 --- a/server/src/main/java/org/elasticsearch/action/fieldcaps/TransportFieldCapabilitiesAction.java +++ b/server/src/main/java/org/elasticsearch/action/fieldcaps/TransportFieldCapabilitiesAction.java @@ -12,6 +12,7 @@ import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionRunnable; +import org.elasticsearch.action.ActionType; import org.elasticsearch.action.OriginalIndices; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.ChannelActionListener; @@ -63,7 +64,9 @@ import static org.elasticsearch.action.search.TransportSearchHelper.checkCCSVersionCompatibility; public class TransportFieldCapabilitiesAction extends HandledTransportAction { - public static final String ACTION_NODE_NAME = FieldCapabilitiesAction.NAME + "[n]"; + public static final String NAME = "indices:data/read/field_caps"; + public static final ActionType TYPE = new ActionType<>(NAME, FieldCapabilitiesResponse::new); + public static final String ACTION_NODE_NAME = NAME + "[n]"; public static final Logger LOGGER = LogManager.getLogger(TransportFieldCapabilitiesAction.class); private final ThreadPool threadPool; @@ -86,7 +89,7 @@ public TransportFieldCapabilitiesAction( ) { // TODO replace SAME when removing workaround for https://github.com/elastic/elasticsearch/issues/97916 super( - FieldCapabilitiesAction.NAME, + NAME, transportService, actionFilters, FieldCapabilitiesRequest::new, diff --git a/server/src/main/java/org/elasticsearch/action/get/GetAction.java b/server/src/main/java/org/elasticsearch/action/get/GetAction.java deleted file mode 100644 index 7e4dbca6d46d7..0000000000000 --- a/server/src/main/java/org/elasticsearch/action/get/GetAction.java +++ /dev/null @@ -1,22 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.action.get; - -import org.elasticsearch.action.ActionType; - -public class GetAction extends ActionType { - - public static final GetAction INSTANCE = new GetAction(); - public static final String NAME = "indices:data/read/get"; - - private GetAction() { - super(NAME, GetResponse::new); - } - -} diff --git a/server/src/main/java/org/elasticsearch/action/get/GetRequestBuilder.java b/server/src/main/java/org/elasticsearch/action/get/GetRequestBuilder.java index f9e748a6e2b22..d581bfa73a1f5 100644 --- a/server/src/main/java/org/elasticsearch/action/get/GetRequestBuilder.java +++ b/server/src/main/java/org/elasticsearch/action/get/GetRequestBuilder.java @@ -21,11 +21,11 @@ public class GetRequestBuilder extends SingleShardOperationRequestBuilder { public GetRequestBuilder(ElasticsearchClient client) { - super(client, GetAction.INSTANCE, new GetRequest()); + super(client, TransportGetAction.TYPE, new GetRequest()); } public GetRequestBuilder(ElasticsearchClient client, @Nullable String index) { - super(client, GetAction.INSTANCE, new GetRequest(index)); + super(client, TransportGetAction.TYPE, new GetRequest(index)); } /** diff --git a/server/src/main/java/org/elasticsearch/action/get/MultiGetAction.java b/server/src/main/java/org/elasticsearch/action/get/MultiGetAction.java deleted file mode 100644 index 15dbdcee57428..0000000000000 --- a/server/src/main/java/org/elasticsearch/action/get/MultiGetAction.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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.action.get; - -import org.elasticsearch.action.ActionType; - -public class MultiGetAction extends ActionType { - - public static final MultiGetAction INSTANCE = new MultiGetAction(); - public static final String NAME = "indices:data/read/mget"; - - private MultiGetAction() { - super(NAME, MultiGetResponse::new); - } -} diff --git a/server/src/main/java/org/elasticsearch/action/get/MultiGetRequestBuilder.java b/server/src/main/java/org/elasticsearch/action/get/MultiGetRequestBuilder.java index f872406dbeda2..8512ae959cb52 100644 --- a/server/src/main/java/org/elasticsearch/action/get/MultiGetRequestBuilder.java +++ b/server/src/main/java/org/elasticsearch/action/get/MultiGetRequestBuilder.java @@ -17,7 +17,7 @@ public class MultiGetRequestBuilder extends ActionRequestBuilder { public MultiGetRequestBuilder(ElasticsearchClient client) { - super(client, MultiGetAction.INSTANCE, new MultiGetRequest()); + super(client, TransportMultiGetAction.TYPE, new MultiGetRequest()); } public MultiGetRequestBuilder add(String index, String id) { 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 9f2fe8ae5aa8c..6440304360bf3 100644 --- a/server/src/main/java/org/elasticsearch/action/get/TransportGetAction.java +++ b/server/src/main/java/org/elasticsearch/action/get/TransportGetAction.java @@ -11,6 +11,7 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionListenerResponseHandler; import org.elasticsearch.action.ActionRunnable; +import org.elasticsearch.action.ActionType; import org.elasticsearch.action.NoShardAvailableActionException; import org.elasticsearch.action.admin.indices.refresh.TransportShardRefreshAction; import org.elasticsearch.action.support.ActionFilters; @@ -46,6 +47,7 @@ */ public class TransportGetAction extends TransportSingleShardAction { + public static final ActionType TYPE = new ActionType<>("indices:data/read/get", GetResponse::new); private static final Logger logger = LogManager.getLogger(TransportGetAction.class); private final IndicesService indicesService; @@ -64,7 +66,7 @@ public TransportGetAction( NodeClient client ) { super( - GetAction.NAME, + TYPE.name(), threadPool, clusterService, transportService, 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 8669524504879..7db644415dbc2 100644 --- a/server/src/main/java/org/elasticsearch/action/get/TransportMultiGetAction.java +++ b/server/src/main/java/org/elasticsearch/action/get/TransportMultiGetAction.java @@ -9,6 +9,7 @@ package org.elasticsearch.action.get; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.ActionType; import org.elasticsearch.action.DelegatingActionListener; import org.elasticsearch.action.RoutingMissingException; import org.elasticsearch.action.support.ActionFilters; @@ -33,6 +34,8 @@ public class TransportMultiGetAction extends HandledTransportAction { + public static final String NAME = "indices:data/read/mget"; + public static final ActionType TYPE = new ActionType<>(NAME, MultiGetResponse::new); private final ClusterService clusterService; private final NodeClient client; private final IndexNameExpressionResolver indexNameExpressionResolver; @@ -46,7 +49,7 @@ public TransportMultiGetAction( IndexNameExpressionResolver resolver, IndicesService indicesService ) { - super(MultiGetAction.NAME, transportService, actionFilters, MultiGetRequest::new, EsExecutors.DIRECT_EXECUTOR_SERVICE); + super(NAME, transportService, actionFilters, MultiGetRequest::new, EsExecutors.DIRECT_EXECUTOR_SERVICE); this.clusterService = clusterService; this.client = client; this.indexNameExpressionResolver = resolver; 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 9986c4019c81b..a05bbf1bfd9d3 100644 --- a/server/src/main/java/org/elasticsearch/action/get/TransportShardMultiGetAction.java +++ b/server/src/main/java/org/elasticsearch/action/get/TransportShardMultiGetAction.java @@ -47,7 +47,7 @@ public class TransportShardMultiGetAction extends TransportSingleShardAction { - private static final String ACTION_NAME = MultiGetAction.NAME + "[shard]"; + private static final String ACTION_NAME = TransportMultiGetAction.NAME + "[shard]"; public static final ActionType TYPE = new ActionType<>(ACTION_NAME, MultiGetShardResponse::new); private static final Logger logger = LogManager.getLogger(TransportShardMultiGetAction.class); diff --git a/server/src/main/java/org/elasticsearch/action/index/IndexAction.java b/server/src/main/java/org/elasticsearch/action/index/IndexAction.java deleted file mode 100644 index 3cb01be92e734..0000000000000 --- a/server/src/main/java/org/elasticsearch/action/index/IndexAction.java +++ /dev/null @@ -1,25 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.action.index; - -import org.elasticsearch.action.ActionType; -import org.elasticsearch.action.DocWriteResponse; - -public class IndexAction extends ActionType { - - public static final IndexAction INSTANCE = new IndexAction(); - public static final String NAME = "indices:data/write/index"; - - private IndexAction() { - super(NAME, in -> { - assert false : "Might not be an IndexResponse!"; - return new IndexResponse(in); - }); - } -} diff --git a/server/src/main/java/org/elasticsearch/action/index/IndexRequestBuilder.java b/server/src/main/java/org/elasticsearch/action/index/IndexRequestBuilder.java index 4cc26f056245a..5e156070d0154 100644 --- a/server/src/main/java/org/elasticsearch/action/index/IndexRequestBuilder.java +++ b/server/src/main/java/org/elasticsearch/action/index/IndexRequestBuilder.java @@ -29,11 +29,11 @@ public class IndexRequestBuilder extends ReplicationRequestBuilder { public IndexRequestBuilder(ElasticsearchClient client) { - super(client, IndexAction.INSTANCE, new IndexRequest()); + super(client, TransportIndexAction.TYPE, new IndexRequest()); } public IndexRequestBuilder(ElasticsearchClient client, @Nullable String index) { - super(client, IndexAction.INSTANCE, new IndexRequest(index)); + super(client, TransportIndexAction.TYPE, new IndexRequest(index)); } /** 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 6c75374d51012..5e91498244dd0 100644 --- a/server/src/main/java/org/elasticsearch/action/index/TransportIndexAction.java +++ b/server/src/main/java/org/elasticsearch/action/index/TransportIndexAction.java @@ -8,6 +8,7 @@ package org.elasticsearch.action.index; +import org.elasticsearch.action.ActionType; import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.bulk.TransportBulkAction; import org.elasticsearch.action.bulk.TransportSingleItemBulkWriteAction; @@ -30,8 +31,14 @@ @Deprecated 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); + }); + @Inject public TransportIndexAction(ActionFilters actionFilters, TransportService transportService, TransportBulkAction bulkAction) { - super(IndexAction.NAME, transportService, actionFilters, IndexRequest::new, bulkAction); + super(NAME, transportService, actionFilters, IndexRequest::new, bulkAction); } } 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 dd85276bdf81a..c9deec8c504a1 100644 --- a/server/src/main/java/org/elasticsearch/action/update/TransportUpdateAction.java +++ b/server/src/main/java/org/elasticsearch/action/update/TransportUpdateAction.java @@ -11,6 +11,7 @@ import org.elasticsearch.ResourceAlreadyExistsException; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionRunnable; +import org.elasticsearch.action.ActionType; import org.elasticsearch.action.DocWriteRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; @@ -58,6 +59,8 @@ public class TransportUpdateAction extends TransportInstanceSingleOperationAction { + public static final String NAME = "indices:data/write/update"; + public static final ActionType TYPE = new ActionType<>(NAME, UpdateResponse::new); private final AutoCreateIndex autoCreateIndex; private final UpdateHelper updateHelper; private final IndicesService indicesService; @@ -76,15 +79,7 @@ public TransportUpdateAction( AutoCreateIndex autoCreateIndex, NodeClient client ) { - super( - UpdateAction.NAME, - threadPool, - clusterService, - transportService, - actionFilters, - indexNameExpressionResolver, - UpdateRequest::new - ); + super(NAME, threadPool, clusterService, transportService, actionFilters, indexNameExpressionResolver, UpdateRequest::new); this.updateHelper = updateHelper; this.indicesService = indicesService; this.autoCreateIndex = autoCreateIndex; diff --git a/server/src/main/java/org/elasticsearch/action/update/UpdateAction.java b/server/src/main/java/org/elasticsearch/action/update/UpdateAction.java deleted file mode 100644 index d99aa172169c7..0000000000000 --- a/server/src/main/java/org/elasticsearch/action/update/UpdateAction.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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.action.update; - -import org.elasticsearch.action.ActionType; - -public class UpdateAction extends ActionType { - - public static final UpdateAction INSTANCE = new UpdateAction(); - public static final String NAME = "indices:data/write/update"; - - private UpdateAction() { - super(NAME, UpdateResponse::new); - } -} diff --git a/server/src/main/java/org/elasticsearch/action/update/UpdateRequestBuilder.java b/server/src/main/java/org/elasticsearch/action/update/UpdateRequestBuilder.java index 6b7d79abc51a3..c7bd513ff84d4 100644 --- a/server/src/main/java/org/elasticsearch/action/update/UpdateRequestBuilder.java +++ b/server/src/main/java/org/elasticsearch/action/update/UpdateRequestBuilder.java @@ -27,11 +27,11 @@ public class UpdateRequestBuilder extends InstanceShardOperationRequestBuilder { public UpdateRequestBuilder(ElasticsearchClient client) { - super(client, UpdateAction.INSTANCE, new UpdateRequest()); + super(client, TransportUpdateAction.TYPE, new UpdateRequest()); } public UpdateRequestBuilder(ElasticsearchClient client, String index, String id) { - super(client, UpdateAction.INSTANCE, new UpdateRequest(index, id)); + super(client, TransportUpdateAction.TYPE, new UpdateRequest(index, id)); } /** diff --git a/server/src/main/java/org/elasticsearch/client/internal/support/AbstractClient.java b/server/src/main/java/org/elasticsearch/client/internal/support/AbstractClient.java index d5fa2f7796252..182e9ee497c07 100644 --- a/server/src/main/java/org/elasticsearch/client/internal/support/AbstractClient.java +++ b/server/src/main/java/org/elasticsearch/client/internal/support/AbstractClient.java @@ -20,10 +20,10 @@ import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainRequest; import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainRequestBuilder; import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainResponse; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequestBuilder; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.admin.cluster.node.hotthreads.NodesHotThreadsRequest; import org.elasticsearch.action.admin.cluster.node.hotthreads.NodesHotThreadsRequestBuilder; import org.elasticsearch.action.admin.cluster.node.hotthreads.NodesHotThreadsResponse; @@ -122,13 +122,13 @@ import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptAction; import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequest; import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequestBuilder; -import org.elasticsearch.action.admin.cluster.tasks.PendingClusterTasksAction; import org.elasticsearch.action.admin.cluster.tasks.PendingClusterTasksRequest; import org.elasticsearch.action.admin.cluster.tasks.PendingClusterTasksRequestBuilder; import org.elasticsearch.action.admin.cluster.tasks.PendingClusterTasksResponse; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction; +import org.elasticsearch.action.admin.cluster.tasks.TransportPendingClusterTasksAction; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequestBuilder; +import org.elasticsearch.action.admin.indices.alias.TransportIndicesAliasesAction; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesAction; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequestBuilder; @@ -139,10 +139,10 @@ import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheRequest; import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheRequestBuilder; import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheResponse; -import org.elasticsearch.action.admin.indices.close.CloseIndexAction; import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexRequestBuilder; import org.elasticsearch.action.admin.indices.close.CloseIndexResponse; +import org.elasticsearch.action.admin.indices.close.TransportCloseIndexAction; import org.elasticsearch.action.admin.indices.create.CreateIndexAction; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; @@ -242,29 +242,29 @@ import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.bulk.BulkResponse; -import org.elasticsearch.action.delete.DeleteAction; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.delete.DeleteRequestBuilder; import org.elasticsearch.action.delete.DeleteResponse; +import org.elasticsearch.action.delete.TransportDeleteAction; import org.elasticsearch.action.explain.ExplainRequest; import org.elasticsearch.action.explain.ExplainRequestBuilder; import org.elasticsearch.action.explain.ExplainResponse; import org.elasticsearch.action.explain.TransportExplainAction; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequestBuilder; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse; -import org.elasticsearch.action.get.GetAction; +import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetRequestBuilder; import org.elasticsearch.action.get.GetResponse; -import org.elasticsearch.action.get.MultiGetAction; import org.elasticsearch.action.get.MultiGetRequest; import org.elasticsearch.action.get.MultiGetRequestBuilder; import org.elasticsearch.action.get.MultiGetResponse; -import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.get.TransportGetAction; +import org.elasticsearch.action.get.TransportMultiGetAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexRequestBuilder; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.ingest.DeletePipelineAction; import org.elasticsearch.action.ingest.DeletePipelineRequest; import org.elasticsearch.action.ingest.DeletePipelineRequestBuilder; @@ -304,7 +304,7 @@ import org.elasticsearch.action.termvectors.TermVectorsRequest; import org.elasticsearch.action.termvectors.TermVectorsRequestBuilder; import org.elasticsearch.action.termvectors.TermVectorsResponse; -import org.elasticsearch.action.update.UpdateAction; +import org.elasticsearch.action.update.TransportUpdateAction; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateRequestBuilder; import org.elasticsearch.action.update.UpdateResponse; @@ -393,12 +393,12 @@ protected abstract index(final IndexRequest request) { - return execute(IndexAction.INSTANCE, request); + return execute(TransportIndexAction.TYPE, request); } @Override public void index(final IndexRequest request, final ActionListener listener) { - execute(IndexAction.INSTANCE, request, listener); + execute(TransportIndexAction.TYPE, request, listener); } @Override @@ -413,12 +413,12 @@ public IndexRequestBuilder prepareIndex(String index) { @Override public ActionFuture update(final UpdateRequest request) { - return execute(UpdateAction.INSTANCE, request); + return execute(TransportUpdateAction.TYPE, request); } @Override public void update(final UpdateRequest request, final ActionListener listener) { - execute(UpdateAction.INSTANCE, request, listener); + execute(TransportUpdateAction.TYPE, request, listener); } @Override @@ -433,12 +433,12 @@ public UpdateRequestBuilder prepareUpdate(String index, String id) { @Override public ActionFuture delete(final DeleteRequest request) { - return execute(DeleteAction.INSTANCE, request); + return execute(TransportDeleteAction.TYPE, request); } @Override public void delete(final DeleteRequest request, final ActionListener listener) { - execute(DeleteAction.INSTANCE, request, listener); + execute(TransportDeleteAction.TYPE, request, listener); } @Override @@ -473,12 +473,12 @@ public BulkRequestBuilder prepareBulk(@Nullable String globalIndex) { @Override public ActionFuture get(final GetRequest request) { - return execute(GetAction.INSTANCE, request); + return execute(TransportGetAction.TYPE, request); } @Override public void get(final GetRequest request, final ActionListener listener) { - execute(GetAction.INSTANCE, request, listener); + execute(TransportGetAction.TYPE, request, listener); } @Override @@ -493,12 +493,12 @@ public GetRequestBuilder prepareGet(String index, String id) { @Override public ActionFuture multiGet(final MultiGetRequest request) { - return execute(MultiGetAction.INSTANCE, request); + return execute(TransportMultiGetAction.TYPE, request); } @Override public void multiGet(final MultiGetRequest request, final ActionListener listener) { - execute(MultiGetAction.INSTANCE, request, listener); + execute(TransportMultiGetAction.TYPE, request, listener); } @Override @@ -618,12 +618,12 @@ public ClearScrollRequestBuilder prepareClearScroll() { @Override public void fieldCaps(FieldCapabilitiesRequest request, ActionListener listener) { - execute(FieldCapabilitiesAction.INSTANCE, request, listener); + execute(TransportFieldCapabilitiesAction.TYPE, request, listener); } @Override public ActionFuture fieldCaps(FieldCapabilitiesRequest request) { - return execute(FieldCapabilitiesAction.INSTANCE, request); + return execute(TransportFieldCapabilitiesAction.TYPE, request); } @Override @@ -684,12 +684,12 @@ public ThreadPool threadPool() { @Override public ActionFuture health(final ClusterHealthRequest request) { - return execute(ClusterHealthAction.INSTANCE, request); + return execute(TransportClusterHealthAction.TYPE, request); } @Override public void health(final ClusterHealthRequest request, final ActionListener listener) { - execute(ClusterHealthAction.INSTANCE, request, listener); + execute(TransportClusterHealthAction.TYPE, request, listener); } @Override @@ -872,7 +872,7 @@ public PendingClusterTasksRequestBuilder preparePendingClusterTasks() { @Override public void pendingClusterTasks(PendingClusterTasksRequest request, ActionListener listener) { - execute(PendingClusterTasksAction.INSTANCE, request, listener); + execute(TransportPendingClusterTasksAction.TYPE, request, listener); } @Override @@ -1164,12 +1164,12 @@ public ThreadPool threadPool() { @Override public ActionFuture aliases(final IndicesAliasesRequest request) { - return execute(IndicesAliasesAction.INSTANCE, request); + return execute(TransportIndicesAliasesAction.TYPE, request); } @Override public void aliases(final IndicesAliasesRequest request, final ActionListener listener) { - execute(IndicesAliasesAction.INSTANCE, request, listener); + execute(TransportIndicesAliasesAction.TYPE, request, listener); } @Override @@ -1254,12 +1254,12 @@ public DeleteIndexRequestBuilder prepareDelete(String... indices) { @Override public ActionFuture close(final CloseIndexRequest request) { - return execute(CloseIndexAction.INSTANCE, request); + return execute(TransportCloseIndexAction.TYPE, request); } @Override public void close(final CloseIndexRequest request, final ActionListener listener) { - execute(CloseIndexAction.INSTANCE, request, listener); + execute(TransportCloseIndexAction.TYPE, request, listener); } @Override diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestReloadAnalyzersAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestReloadAnalyzersAction.java index 0a93f964591a1..9c48d5285aae6 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestReloadAnalyzersAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestReloadAnalyzersAction.java @@ -8,8 +8,8 @@ package org.elasticsearch.rest.action.admin.indices; -import org.elasticsearch.action.admin.indices.analyze.ReloadAnalyzerAction; import org.elasticsearch.action.admin.indices.analyze.ReloadAnalyzersRequest; +import org.elasticsearch.action.admin.indices.analyze.TransportReloadAnalyzersAction; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.client.internal.node.NodeClient; import org.elasticsearch.common.Strings; @@ -43,6 +43,10 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC Strings.splitStringByCommaToArray(request.param("index")) ); reloadAnalyzersRequest.indicesOptions(IndicesOptions.fromRequest(request, reloadAnalyzersRequest.indicesOptions())); - return channel -> client.execute(ReloadAnalyzerAction.INSTANCE, reloadAnalyzersRequest, new RestToXContentListener<>(channel)); + return channel -> client.execute( + TransportReloadAnalyzersAction.TYPE, + reloadAnalyzersRequest, + new RestToXContentListener<>(channel) + ); } } diff --git a/server/src/main/java/org/elasticsearch/script/package-info.java b/server/src/main/java/org/elasticsearch/script/package-info.java index 6365530e3f4c8..b96d46b2f4d77 100644 --- a/server/src/main/java/org/elasticsearch/script/package-info.java +++ b/server/src/main/java/org/elasticsearch/script/package-info.java @@ -9,6 +9,7 @@ /** * Support for running user provided scripts (in the request, in cluster state, etc) in portions of various requests * ({@link org.elasticsearch.common.lucene.search.function.FunctionScoreQuery}, {@link org.elasticsearch.search.aggregations.Aggregation}, - * {@link org.elasticsearch.action.update.UpdateAction}, etc). Pluggable via implementing {@link org.elasticsearch.plugins.ScriptPlugin}. + * {@link org.elasticsearch.action.update.TransportUpdateAction}, etc). Pluggable via implementing + * {@link org.elasticsearch.plugins.ScriptPlugin}. */ package org.elasticsearch.script; diff --git a/server/src/main/java/org/elasticsearch/synonyms/SynonymsManagementAPIService.java b/server/src/main/java/org/elasticsearch/synonyms/SynonymsManagementAPIService.java index 20aac833190a7..9409aef96d8be 100644 --- a/server/src/main/java/org/elasticsearch/synonyms/SynonymsManagementAPIService.java +++ b/server/src/main/java/org/elasticsearch/synonyms/SynonymsManagementAPIService.java @@ -18,9 +18,9 @@ import org.elasticsearch.action.DelegatingActionListener; import org.elasticsearch.action.DocWriteRequest; import org.elasticsearch.action.DocWriteResponse; -import org.elasticsearch.action.admin.indices.analyze.ReloadAnalyzerAction; import org.elasticsearch.action.admin.indices.analyze.ReloadAnalyzersRequest; import org.elasticsearch.action.admin.indices.analyze.ReloadAnalyzersResponse; +import org.elasticsearch.action.admin.indices.analyze.TransportReloadAnalyzersAction; import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.index.IndexRequest; @@ -468,7 +468,7 @@ private void reloadAnalyzers( // auto-reload all reloadable analyzers (currently only those that use updateable synonym or keyword_marker filters) ReloadAnalyzersRequest reloadAnalyzersRequest = new ReloadAnalyzersRequest(synonymSetId, preview, "*"); client.execute( - ReloadAnalyzerAction.INSTANCE, + TransportReloadAnalyzersAction.TYPE, reloadAnalyzersRequest, listener.safeMap(reloadResponse -> new SynonymsReloadResult(synonymsOperationResult, reloadResponse)) ); diff --git a/server/src/test/java/org/elasticsearch/action/bulk/TransportBulkActionIngestTests.java b/server/src/test/java/org/elasticsearch/action/bulk/TransportBulkActionIngestTests.java index 95039f6fb0de1..f30bceada65d9 100644 --- a/server/src/test/java/org/elasticsearch/action/bulk/TransportBulkActionIngestTests.java +++ b/server/src/test/java/org/elasticsearch/action/bulk/TransportBulkActionIngestTests.java @@ -11,9 +11,9 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.DocWriteRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.ActionTestUtils; import org.elasticsearch.action.support.AutoCreateIndex; @@ -164,7 +164,7 @@ class TestSingleItemBulkWriteAction extends TransportSingleItemBulkWriteAction[] ACTIONS = new ActionType[] { // client actions - GetAction.INSTANCE, + TransportGetAction.TYPE, TransportSearchAction.TYPE, - DeleteAction.INSTANCE, + TransportDeleteAction.TYPE, DeleteStoredScriptAction.INSTANCE, - IndexAction.INSTANCE, + TransportIndexAction.TYPE, // cluster admin actions ClusterStatsAction.INSTANCE, @@ -96,9 +96,9 @@ public void testActions() { // validation in the settings??? - ugly and conceptually wrong) // choosing arbitrary top level actions to test - client.prepareGet("idx", "id").execute(new AssertingActionListener<>(GetAction.NAME, client.threadPool())); + client.prepareGet("idx", "id").execute(new AssertingActionListener<>(TransportGetAction.TYPE.name(), client.threadPool())); client.prepareSearch().execute(new AssertingActionListener<>(TransportSearchAction.TYPE.name(), client.threadPool())); - client.prepareDelete("idx", "id").execute(new AssertingActionListener<>(DeleteAction.NAME, client.threadPool())); + client.prepareDelete("idx", "id").execute(new AssertingActionListener<>(TransportDeleteAction.NAME, client.threadPool())); client.admin() .cluster() .prepareDeleteStoredScript("id") @@ -106,7 +106,7 @@ public void testActions() { client.prepareIndex("idx") .setId("id") .setSource("source", XContentType.JSON) - .execute(new AssertingActionListener<>(IndexAction.NAME, client.threadPool())); + .execute(new AssertingActionListener<>(TransportIndexAction.NAME, client.threadPool())); // choosing arbitrary cluster admin actions to test client.admin().cluster().prepareClusterStats().execute(new AssertingActionListener<>(ClusterStatsAction.NAME, client.threadPool())); @@ -132,7 +132,8 @@ public void testOverrideHeader() throws Exception { expected.put("key1", key1Val); expected.put("key2", "val 2"); client.threadPool().getThreadContext().putHeader("key1", key1Val); - client.prepareGet("idx", "id").execute(new AssertingActionListener<>(GetAction.NAME, expected, client.threadPool())); + client.prepareGet("idx", "id") + .execute(new AssertingActionListener<>(TransportGetAction.TYPE.name(), expected, client.threadPool())); client.admin() .cluster() diff --git a/server/src/test/java/org/elasticsearch/cluster/health/ClusterStateHealthTests.java b/server/src/test/java/org/elasticsearch/cluster/health/ClusterStateHealthTests.java index 3549b7a05d2b5..05e345bf4b52b 100644 --- a/server/src/test/java/org/elasticsearch/cluster/health/ClusterStateHealthTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/health/ClusterStateHealthTests.java @@ -8,7 +8,6 @@ package org.elasticsearch.cluster.health; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; @@ -159,7 +158,7 @@ public void testClusterHealthWaitsForClusterStateApplication() throws Interrupte PlainActionFuture listener = new PlainActionFuture<>(); ActionTestUtils.execute( action, - new CancellableTask(1, "direct", ClusterHealthAction.NAME, "", TaskId.EMPTY_TASK_ID, Map.of()), + new CancellableTask(1, "direct", TransportClusterHealthAction.NAME, "", TaskId.EMPTY_TASK_ID, Map.of()), new ClusterHealthRequest().waitForGreenStatus(), listener ); 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 6d4fe25705688..88958063dbbf3 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 @@ -8,9 +8,9 @@ package org.elasticsearch.test.disruption; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.cluster.NodeConnectionsService; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.settings.Settings; @@ -162,30 +162,35 @@ private static Tuple findDisruptedPair(Netwo } private static void sendRequest(TransportService source, TransportService target, CountDownLatch latch) { - source.sendRequest(target.getLocalNode(), ClusterHealthAction.NAME, new ClusterHealthRequest(), new TransportResponseHandler<>() { - private AtomicBoolean responded = new AtomicBoolean(); - - @Override - public Executor executor(ThreadPool threadPool) { - return TransportResponseHandler.TRANSPORT_WORKER; - } - - @Override - public void handleResponse(TransportResponse response) { - assertTrue(responded.compareAndSet(false, true)); - latch.countDown(); - } - - @Override - public void handleException(TransportException exp) { - assertTrue(responded.compareAndSet(false, true)); - latch.countDown(); - } - - @Override - public TransportResponse read(StreamInput in) throws IOException { - return ClusterHealthResponse.readResponseFrom(in); + source.sendRequest( + target.getLocalNode(), + TransportClusterHealthAction.NAME, + new ClusterHealthRequest(), + new TransportResponseHandler<>() { + private AtomicBoolean responded = new AtomicBoolean(); + + @Override + public Executor executor(ThreadPool threadPool) { + return TransportResponseHandler.TRANSPORT_WORKER; + } + + @Override + public void handleResponse(TransportResponse response) { + assertTrue(responded.compareAndSet(false, true)); + latch.countDown(); + } + + @Override + public void handleException(TransportException exp) { + assertTrue(responded.compareAndSet(false, true)); + latch.countDown(); + } + + @Override + public TransportResponse read(StreamInput in) throws IOException { + return ClusterHealthResponse.readResponseFrom(in); + } } - }); + ); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/annotations/AnnotationIndex.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/annotations/AnnotationIndex.java index 09c7348cdc870..d3a20235e3a38 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/annotations/AnnotationIndex.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/annotations/AnnotationIndex.java @@ -10,8 +10,8 @@ import org.apache.logging.log4j.Logger; import org.elasticsearch.ResourceAlreadyExistsException; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequestBuilder; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; @@ -77,7 +77,7 @@ public static void createAnnotationsIndexIfNecessaryAndWaitForYellow( executeAsyncWithOrigin( client, ML_ORIGIN, - ClusterHealthAction.INSTANCE, + TransportClusterHealthAction.TYPE, request, delegate.delegateFailureAndWrap((l, r) -> l.onResponse(r.isTimedOut() == false)) ); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/job/persistence/AnomalyDetectorsIndex.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/job/persistence/AnomalyDetectorsIndex.java index 2b622a1798508..d81541698e49b 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/job/persistence/AnomalyDetectorsIndex.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/job/persistence/AnomalyDetectorsIndex.java @@ -7,8 +7,8 @@ package org.elasticsearch.xpack.core.ml.job.persistence; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; @@ -109,7 +109,7 @@ public static void createStateIndexAndAliasIfNecessaryAndWaitForYellow( executeAsyncWithOrigin( client, ML_ORIGIN, - ClusterHealthAction.INSTANCE, + TransportClusterHealthAction.TYPE, request, delegate.delegateFailureAndWrap((l, r) -> l.onResponse(r.isTimedOut() == false)) ); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/IndexPrivilege.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/IndexPrivilege.java index 35c32780d2e4c..ca8932ced81b4 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/IndexPrivilege.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/IndexPrivilege.java @@ -11,7 +11,7 @@ import org.apache.lucene.util.automaton.Automaton; import org.elasticsearch.action.admin.cluster.shards.ClusterSearchShardsAction; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesAction; -import org.elasticsearch.action.admin.indices.close.CloseIndexAction; +import org.elasticsearch.action.admin.indices.close.TransportCloseIndexAction; import org.elasticsearch.action.admin.indices.create.AutoCreateAction; import org.elasticsearch.action.admin.indices.create.CreateIndexAction; import org.elasticsearch.action.admin.indices.delete.DeleteIndexAction; @@ -28,7 +28,7 @@ import org.elasticsearch.action.datastreams.DeleteDataStreamAction; import org.elasticsearch.action.datastreams.GetDataStreamAction; import org.elasticsearch.action.datastreams.PromoteDataStreamAction; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; +import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; import org.elasticsearch.action.search.TransportSearchShardsAction; import org.elasticsearch.common.Strings; import org.elasticsearch.index.seqno.RetentionLeaseActions; @@ -104,7 +104,7 @@ public final class IndexPrivilege extends Privilege { private static final Automaton MANAGE_AUTOMATON = unionAndMinimize( Arrays.asList( MONITOR_AUTOMATON, - patterns("indices:admin/*", FieldCapabilitiesAction.NAME + "*", GetRollupIndexCapsAction.NAME + "*") + patterns("indices:admin/*", TransportFieldCapabilitiesAction.NAME + "*", GetRollupIndexCapsAction.NAME + "*") ) ); private static final Automaton CREATE_INDEX_AUTOMATON = patterns( @@ -127,14 +127,14 @@ public final class IndexPrivilege extends Privilege { "indices:admin/data_stream/lifecycle/explain", GetDataStreamAction.NAME, ResolveIndexAction.NAME, - FieldCapabilitiesAction.NAME + "*", + TransportFieldCapabilitiesAction.NAME + "*", GetRollupIndexCapsAction.NAME + "*", GetCheckpointAction.NAME + "*" // transform internal action ); private static final Automaton MANAGE_FOLLOW_INDEX_AUTOMATON = patterns( PutFollowAction.NAME, UnfollowAction.NAME, - CloseIndexAction.NAME + "*", + TransportCloseIndexAction.NAME + "*", PromoteDataStreamAction.NAME, RolloverAction.NAME ); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/KibanaOwnedReservedRoleDescriptors.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/KibanaOwnedReservedRoleDescriptors.java index f11f5c450b270..fc0df87425239 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/KibanaOwnedReservedRoleDescriptors.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/KibanaOwnedReservedRoleDescriptors.java @@ -7,7 +7,7 @@ package org.elasticsearch.xpack.core.security.authz.store; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction; +import org.elasticsearch.action.admin.indices.alias.TransportIndicesAliasesAction; import org.elasticsearch.action.admin.indices.delete.DeleteIndexAction; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingAction; import org.elasticsearch.action.admin.indices.rollover.RolloverAction; @@ -298,7 +298,14 @@ static RoleDescriptor kibanaSystem(String name) { ".metrics-endpoint.metadata_current_default*", ".metrics-endpoint.metadata_united_default*" ) - .privileges("create_index", "delete_index", "read", "index", IndicesAliasesAction.NAME, UpdateSettingsAction.NAME) + .privileges( + "create_index", + "delete_index", + "read", + "index", + TransportIndicesAliasesAction.NAME, + UpdateSettingsAction.NAME + ) .build(), // For destination indices of the Threat Intel (ti_*) packages that ships a transform for supporting IOC expiration RoleDescriptor.IndicesPrivileges.builder() @@ -310,7 +317,7 @@ static RoleDescriptor kibanaSystem(String name) { "index", "delete", "manage", - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, UpdateSettingsAction.NAME ) .build(), @@ -334,7 +341,7 @@ static RoleDescriptor kibanaSystem(String name) { "read", "index", "view_index_metadata", - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, UpdateSettingsAction.NAME ) .build(), @@ -349,7 +356,7 @@ static RoleDescriptor kibanaSystem(String name) { "logs-cloud_security_posture.scores-default*", "logs-cloud_security_posture.vulnerabilities_latest-default*" ) - .privileges("create_index", "read", "index", "delete", IndicesAliasesAction.NAME, UpdateSettingsAction.NAME) + .privileges("create_index", "read", "index", "delete", TransportIndicesAliasesAction.NAME, UpdateSettingsAction.NAME) .build(), RoleDescriptor.IndicesPrivileges.builder().indices("risk-score.risk-*").privileges("all").build(), RoleDescriptor.IndicesPrivileges.builder() diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStore.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStore.java index da8e97b10dc87..96eaec5d93158 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStore.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStore.java @@ -9,7 +9,7 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.admin.cluster.remote.TransportRemoteInfoAction; import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesAction; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction; +import org.elasticsearch.action.admin.indices.alias.TransportIndicesAliasesAction; import org.elasticsearch.action.admin.indices.rollover.RolloverAction; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Setting; @@ -212,7 +212,13 @@ private static Map initializeReservedRoles() { RoleDescriptor.IndicesPrivileges.builder().indices(".monitoring-*").privileges("all").build(), RoleDescriptor.IndicesPrivileges.builder() .indices("metricbeat-*") - .privileges("index", "create_index", "view_index_metadata", IndicesAliasesAction.NAME, RolloverAction.NAME) + .privileges( + "index", + "create_index", + "view_index_metadata", + TransportIndicesAliasesAction.NAME, + RolloverAction.NAME + ) .build() }, null, MetadataUtils.DEFAULT_RESERVED_METADATA diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/user/InternalUsers.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/user/InternalUsers.java index 652d6815eea46..0cc5c9367ea50 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/user/InternalUsers.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/user/InternalUsers.java @@ -7,7 +7,7 @@ package org.elasticsearch.xpack.core.security.user; -import org.elasticsearch.action.admin.indices.analyze.ReloadAnalyzerAction; +import org.elasticsearch.action.admin.indices.analyze.TransportReloadAnalyzersAction; import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeAction; import org.elasticsearch.action.admin.indices.readonly.AddIndexBlockAction; import org.elasticsearch.action.admin.indices.refresh.RefreshAction; @@ -189,7 +189,7 @@ public class InternalUsers { null, new RoleDescriptor.IndicesPrivileges[] { RoleDescriptor.IndicesPrivileges.builder().indices(".synonyms*").privileges("all").allowRestrictedIndices(true).build(), - RoleDescriptor.IndicesPrivileges.builder().indices("*").privileges(ReloadAnalyzerAction.NAME).build(), }, + RoleDescriptor.IndicesPrivileges.builder().indices("*").privileges(TransportReloadAnalyzersAction.TYPE.name()).build(), }, null, null, null, diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ClientHelperTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ClientHelperTests.java index 99826b5537258..b98a8abc019d0 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ClientHelperTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ClientHelperTests.java @@ -9,9 +9,9 @@ import org.elasticsearch.TransportVersion; import org.elasticsearch.TransportVersions; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.ShardSearchFailure; @@ -110,7 +110,7 @@ public void testExecuteWithClient() throws Exception { }).when(client).execute(any(), any(), any()); threadContext.putHeader(headerName, headerValue); - ClientHelper.executeAsyncWithOrigin(client, origin, ClusterHealthAction.INSTANCE, new ClusterHealthRequest(), listener); + ClientHelper.executeAsyncWithOrigin(client, origin, TransportClusterHealthAction.TYPE, new ClusterHealthRequest(), listener); latch.await(); } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/common/notifications/AbstractAuditorTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/common/notifications/AbstractAuditorTests.java index cfd5b4cd381c5..db6f303d98ca8 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/common/notifications/AbstractAuditorTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/common/notifications/AbstractAuditorTests.java @@ -10,8 +10,8 @@ import org.elasticsearch.action.admin.indices.template.put.PutComposableIndexTemplateAction; import org.elasticsearch.action.bulk.BulkAction; import org.elasticsearch.action.bulk.BulkRequest; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.client.internal.AdminClient; import org.elasticsearch.client.internal.Client; @@ -98,7 +98,7 @@ public void testInfo() throws IOException { AbstractAuditor auditor = createTestAuditorWithTemplateInstalled(); auditor.info("foo", "Here is my info"); - verify(client).execute(eq(IndexAction.INSTANCE), indexRequestCaptor.capture(), any()); + verify(client).execute(eq(TransportIndexAction.TYPE), indexRequestCaptor.capture(), any()); IndexRequest indexRequest = indexRequestCaptor.getValue(); assertThat(indexRequest.indices(), arrayContaining(TEST_INDEX)); assertThat(indexRequest.timeout(), equalTo(TimeValue.timeValueSeconds(5))); @@ -117,7 +117,7 @@ public void testWarning() throws IOException { AbstractAuditor auditor = createTestAuditorWithTemplateInstalled(); auditor.warning("bar", "Here is my warning"); - verify(client).execute(eq(IndexAction.INSTANCE), indexRequestCaptor.capture(), any()); + verify(client).execute(eq(TransportIndexAction.TYPE), indexRequestCaptor.capture(), any()); IndexRequest indexRequest = indexRequestCaptor.getValue(); assertThat(indexRequest.indices(), arrayContaining(TEST_INDEX)); assertThat(indexRequest.timeout(), equalTo(TimeValue.timeValueSeconds(5))); @@ -136,7 +136,7 @@ public void testError() throws IOException { AbstractAuditor auditor = createTestAuditorWithTemplateInstalled(); auditor.error("foobar", "Here is my error"); - verify(client).execute(eq(IndexAction.INSTANCE), indexRequestCaptor.capture(), any()); + verify(client).execute(eq(TransportIndexAction.TYPE), indexRequestCaptor.capture(), any()); IndexRequest indexRequest = indexRequestCaptor.getValue(); assertThat(indexRequest.indices(), arrayContaining(TEST_INDEX)); assertThat(indexRequest.timeout(), equalTo(TimeValue.timeValueSeconds(5))); @@ -157,7 +157,7 @@ public void testAudit() throws IOException { AbstractAuditor auditor = createTestAuditorWithTemplateInstalled(); auditor.audit(level, "r_id", "Here is my audit"); - verify(client).execute(eq(IndexAction.INSTANCE), indexRequestCaptor.capture(), any()); + verify(client).execute(eq(TransportIndexAction.TYPE), indexRequestCaptor.capture(), any()); IndexRequest indexRequest = indexRequestCaptor.getValue(); assertThat(indexRequest.indices(), arrayContaining(TEST_INDEX)); assertThat(indexRequest.timeout(), equalTo(TimeValue.timeValueSeconds(5))); @@ -182,7 +182,7 @@ public void testAuditingBeforeTemplateInstalled() throws Exception { auditor.warning("foobar", "Here is my warning to queue"); auditor.info("foobar", "Here is my info to queue"); - verify(client, never()).execute(eq(IndexAction.INSTANCE), any(), any()); + verify(client, never()).execute(eq(TransportIndexAction.TYPE), any(), any()); // fire the put template response writeSomeDocsBeforeTemplateLatch.countDown(); @@ -194,7 +194,7 @@ public void testAuditingBeforeTemplateInstalled() throws Exception { assertThat(bulkRequest.numberOfActions(), equalTo(3)); auditor.info("foobar", "Here is another message"); - verify(client, times(1)).execute(eq(IndexAction.INSTANCE), any(), any()); + verify(client, times(1)).execute(eq(TransportIndexAction.TYPE), any(), any()); } public void testMaxBufferSize() throws Exception { diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/SwapAliasesAndDeleteSourceIndexStepTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/SwapAliasesAndDeleteSourceIndexStepTests.java index 7a09b375ed53b..f9f06b10ad2f9 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/SwapAliasesAndDeleteSourceIndexStepTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/SwapAliasesAndDeleteSourceIndexStepTests.java @@ -10,9 +10,9 @@ import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.ActionType; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions; +import org.elasticsearch.action.admin.indices.alias.TransportIndicesAliasesAction; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.AliasMetadata; import org.elasticsearch.cluster.metadata.IndexMetadata; @@ -134,7 +134,7 @@ protected void Request request, ActionListener listener ) { - assertThat(action.name(), is(IndicesAliasesAction.NAME)); + assertThat(action.name(), is(TransportIndicesAliasesAction.NAME)); assertTrue(request instanceof IndicesAliasesRequest); assertThat(((IndicesAliasesRequest) request).getAliasActions(), equalTo(expectedAliasActions)); } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/IndexPrivilegeTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/IndexPrivilegeTests.java index 9dde594653367..b755d3497f649 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/IndexPrivilegeTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/IndexPrivilegeTests.java @@ -11,10 +11,10 @@ import org.elasticsearch.action.admin.indices.refresh.RefreshAction; import org.elasticsearch.action.admin.indices.shrink.ShrinkAction; import org.elasticsearch.action.admin.indices.stats.IndicesStatsAction; -import org.elasticsearch.action.delete.DeleteAction; -import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.delete.TransportDeleteAction; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.TransportSearchAction; -import org.elasticsearch.action.update.UpdateAction; +import org.elasticsearch.action.update.TransportUpdateAction; import org.elasticsearch.common.util.iterable.Iterables; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.core.rollup.action.GetRollupIndexCapsAction; @@ -60,9 +60,9 @@ public void testOrderingOfPrivilegeNames() throws Exception { public void testFindPrivilegesThatGrant() { assertThat(findPrivilegesThatGrant(TransportSearchAction.TYPE.name()), equalTo(List.of("read", "all"))); - assertThat(findPrivilegesThatGrant(IndexAction.NAME), equalTo(List.of("create_doc", "create", "index", "write", "all"))); - assertThat(findPrivilegesThatGrant(UpdateAction.NAME), equalTo(List.of("index", "write", "all"))); - assertThat(findPrivilegesThatGrant(DeleteAction.NAME), equalTo(List.of("delete", "write", "all"))); + assertThat(findPrivilegesThatGrant(TransportIndexAction.NAME), equalTo(List.of("create_doc", "create", "index", "write", "all"))); + assertThat(findPrivilegesThatGrant(TransportUpdateAction.NAME), equalTo(List.of("index", "write", "all"))); + assertThat(findPrivilegesThatGrant(TransportDeleteAction.NAME), equalTo(List.of("delete", "write", "all"))); assertThat( findPrivilegesThatGrant(IndicesStatsAction.NAME), equalTo(List.of("monitor", "cross_cluster_replication", "manage", "all")) diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/PrivilegeTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/PrivilegeTests.java index 59add1cac3539..2e2368ece0612 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/PrivilegeTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/PrivilegeTests.java @@ -7,7 +7,7 @@ package org.elasticsearch.xpack.core.security.authz.privilege; import org.apache.lucene.util.automaton.Operations; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.admin.cluster.node.tasks.cancel.CancelTasksAction; import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteAction; import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsAction; @@ -301,7 +301,7 @@ public void testReadSecurityPrivilege() { CreateServiceAccountTokenAction.NAME, CreateApiKeyAction.NAME, InvalidateApiKeyAction.NAME, - ClusterHealthAction.NAME, + TransportClusterHealthAction.NAME, ClusterStateAction.NAME, ClusterStatsAction.NAME, NodeEnrollmentAction.NAME, @@ -353,7 +353,7 @@ public void testManageUserProfilePrivilege() { ); verifyClusterActionDenied( ClusterPrivilegeResolver.MANAGE_USER_PROFILE, - ClusterHealthAction.NAME, + TransportClusterHealthAction.NAME, ClusterStateAction.NAME, ClusterStatsAction.NAME, PutIndexTemplateAction.NAME, diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java index 6ee70173f505e..ed77e9a1d4d9a 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java @@ -7,7 +7,7 @@ package org.elasticsearch.xpack.core.security.authz.store; import org.elasticsearch.Version; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.admin.cluster.remote.TransportRemoteInfoAction; import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesAction; import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryAction; @@ -19,7 +19,7 @@ import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusAction; import org.elasticsearch.action.admin.cluster.state.ClusterStateAction; import org.elasticsearch.action.admin.cluster.stats.ClusterStatsAction; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction; +import org.elasticsearch.action.admin.indices.alias.TransportIndicesAliasesAction; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesAction; import org.elasticsearch.action.admin.indices.create.AutoCreateAction; import org.elasticsearch.action.admin.indices.create.CreateIndexAction; @@ -44,10 +44,10 @@ import org.elasticsearch.action.datastreams.CreateDataStreamAction; import org.elasticsearch.action.datastreams.DeleteDataStreamAction; import org.elasticsearch.action.datastreams.GetDataStreamAction; -import org.elasticsearch.action.delete.DeleteAction; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; -import org.elasticsearch.action.get.GetAction; -import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.delete.TransportDeleteAction; +import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; +import org.elasticsearch.action.get.TransportGetAction; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.ingest.DeletePipelineAction; import org.elasticsearch.action.ingest.GetPipelineAction; import org.elasticsearch.action.ingest.PutPipelineAction; @@ -57,7 +57,7 @@ import org.elasticsearch.action.search.TransportSearchShardsAction; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.action.support.WriteRequest; -import org.elasticsearch.action.update.UpdateAction; +import org.elasticsearch.action.update.TransportUpdateAction; import org.elasticsearch.cluster.metadata.AliasMetadata; import org.elasticsearch.cluster.metadata.IndexAbstraction; import org.elasticsearch.cluster.metadata.IndexMetadata; @@ -328,7 +328,7 @@ public void testSnapshotUserRole() { assertThat( snapshotUserRole.indices() - .allowedIndicesMatcher(IndexAction.NAME) + .allowedIndicesMatcher(TransportIndexAction.NAME) .test(mockIndexAbstraction(randomAlphaOfLengthBetween(8, 24))), is(false) ); @@ -337,11 +337,15 @@ public void testSnapshotUserRole() { is(false) ); assertThat( - snapshotUserRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(randomAlphaOfLengthBetween(8, 24))), + snapshotUserRole.indices() + .allowedIndicesMatcher(TransportGetAction.TYPE.name()) + .test(mockIndexAbstraction(randomAlphaOfLengthBetween(8, 24))), is(false) ); assertThat( - snapshotUserRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(randomAlphaOfLengthBetween(8, 24))), + snapshotUserRole.indices() + .allowedIndicesMatcher(TransportGetAction.TYPE.name()) + .test(mockIndexAbstraction(randomAlphaOfLengthBetween(8, 24))), is(false) ); @@ -393,13 +397,15 @@ public void testIngestAdminRole() { assertThat(ingestAdminRole.cluster().check(GetProfilesAction.NAME, request, authentication), is(false)); assertThat(ingestAdminRole.cluster().check(ProfileHasPrivilegesAction.NAME, request, authentication), is(false)); - assertThat(ingestAdminRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); + assertThat(ingestAdminRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); assertThat( ingestAdminRole.indices().allowedIndicesMatcher("indices:foo").test(mockIndexAbstraction(randomAlphaOfLengthBetween(8, 24))), is(false) ); assertThat( - ingestAdminRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(randomAlphaOfLengthBetween(8, 24))), + ingestAdminRole.indices() + .allowedIndicesMatcher(TransportGetAction.TYPE.name()) + .test(mockIndexAbstraction(randomAlphaOfLengthBetween(8, 24))), is(false) ); @@ -419,7 +425,7 @@ public void testKibanaSystemRole() { assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role kibanaRole = Role.buildFromRoleDescriptor(roleDescriptor, new FieldPermissionsCache(Settings.EMPTY), RESTRICTED_INDICES); - assertThat(kibanaRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(true)); + assertThat(kibanaRole.cluster().check(TransportClusterHealthAction.NAME, request, authentication), is(true)); assertThat(kibanaRole.cluster().check(ClusterStateAction.NAME, request, authentication), is(true)); assertThat(kibanaRole.cluster().check(ClusterStatsAction.NAME, request, authentication), is(true)); assertThat(kibanaRole.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(true)); @@ -581,8 +587,11 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.runAs().check(randomAlphaOfLengthBetween(1, 12)), is(false)); assertThat(kibanaRole.cluster().check(DelegatePkiAuthenticationAction.NAME, request, authentication), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(".reporting")), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); + assertThat( + kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(".reporting")), + is(false) + ); assertThat( kibanaRole.indices().allowedIndicesMatcher("indices:foo").test(mockIndexAbstraction(randomAlphaOfLengthBetween(8, 24))), is(false) @@ -612,8 +621,8 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher("indices:bar").test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat( kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), @@ -623,7 +632,10 @@ public void testKibanaSystemRole() { kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true) ); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat( + kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), + is(true) + ); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(mockIndexAbstraction(index)), is(true)); }); @@ -637,8 +649,8 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher("indices:bar").test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat( kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), @@ -648,7 +660,10 @@ public void testKibanaSystemRole() { kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true) ); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat( + kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), + is(true) + ); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(mockIndexAbstraction(index)), is(false)); }); @@ -662,8 +677,8 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher("indices:bar").test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat( kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), @@ -673,7 +688,10 @@ public void testKibanaSystemRole() { kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true) ); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat( + kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), + is(true) + ); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(mockIndexAbstraction(index)), is(false)); }); @@ -684,8 +702,8 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat( kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), @@ -695,7 +713,10 @@ public void testKibanaSystemRole() { kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true) ); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat( + kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), + is(true) + ); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(mockIndexAbstraction(index)), is(true)); }); @@ -710,8 +731,8 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher("indices:bar").test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat( kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true) @@ -720,7 +741,10 @@ public void testKibanaSystemRole() { kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true) ); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat( + kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), + is(true) + ); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(mockIndexAbstraction(index)), is(true)); }); @@ -730,8 +754,8 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher("indices:bar").test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat( kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true) @@ -740,7 +764,10 @@ public void testKibanaSystemRole() { kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true) ); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat( + kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), + is(true) + ); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(mockIndexAbstraction(index)), is(false)); // Privileges needed for Fleet package upgrades @@ -759,11 +786,11 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(PutMappingAction.NAME).test(indexAbstraction), is(true)); @@ -778,11 +805,11 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(PutMappingAction.NAME).test(indexAbstraction), is(true)); @@ -804,14 +831,14 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher("indices:bar").test(dotFleetSecretsIndex), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(dotFleetSecretsIndex), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(dotFleetSecretsIndex), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(dotFleetSecretsIndex), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(dotFleetSecretsIndex), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(dotFleetSecretsIndex), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(dotFleetSecretsIndex), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(dotFleetSecretsIndex), is(false)); assertThat( kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(dotFleetSecretsIndex), is(false) ); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(dotFleetSecretsIndex), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(dotFleetSecretsIndex), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(dotFleetSecretsIndex), is(false)); assertThat(kibanaRole.cluster().check("cluster:admin/fleet/secrets/get", request, authentication), is(false)); @@ -824,8 +851,8 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher("indices:bar").test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat( kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true) @@ -834,7 +861,10 @@ public void testKibanaSystemRole() { kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true) ); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat( + kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), + is(true) + ); }); // read-only index for Endpoint and Osquery manager specific action responses @@ -845,11 +875,11 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(PutMappingAction.NAME).test(indexAbstraction), is(true)); @@ -863,11 +893,11 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(PutMappingAction.NAME).test(indexAbstraction), is(true)); @@ -882,11 +912,11 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(PutMappingAction.NAME).test(indexAbstraction), is(true)); @@ -901,11 +931,11 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(PutMappingAction.NAME).test(indexAbstraction), is(true)); @@ -922,8 +952,8 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher("indices:bar").test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat( kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), @@ -933,7 +963,10 @@ public void testKibanaSystemRole() { kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(false) ); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat( + kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), + is(false) + ); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(mockIndexAbstraction(index)), is(false)); }); @@ -967,11 +1000,11 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(PutMappingAction.NAME).test(indexAbstraction), is(true)); @@ -986,11 +1019,11 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(PutMappingAction.NAME).test(indexAbstraction), is(true)); @@ -1003,8 +1036,8 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher("indices:bar").test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat( kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), @@ -1014,7 +1047,7 @@ public void testKibanaSystemRole() { kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true) ); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(mockIndexAbstraction(index)), is(false)); assertNoAccessAllowed(kibanaRole, TestRestrictedIndices.SAMPLE_RESTRICTED_NAMES); @@ -1076,8 +1109,14 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(AutoCreateAction.NAME).test(indexAbstraction), is(isAlsoAutoCreateIndex)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateDataStreamAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(isAlsoAutoCreateIndex)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(indexAbstraction), is(isAlsoAutoCreateIndex)); + assertThat( + kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), + is(isAlsoAutoCreateIndex) + ); + assertThat( + kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(indexAbstraction), + is(isAlsoAutoCreateIndex) + ); // Endpoint diagnostic and actions data streams also have read access, all others should not. final boolean isAlsoReadIndex = indexName.startsWith(".logs-endpoint.diagnostic.collection-") @@ -1085,7 +1124,10 @@ public void testKibanaSystemRole() { || indexName.startsWith(".logs-endpoint.action.responses-") || indexName.startsWith(".logs-endpoint.heartbeat-") || indexName.startsWith(".logs-osquery_manager.actions-"); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(isAlsoReadIndex)); + assertThat( + kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), + is(isAlsoReadIndex) + ); assertThat( kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(isAlsoReadIndex) @@ -1142,9 +1184,9 @@ public void testKibanaSystemRole() { final IndexAbstraction indexAbstraction = mockIndexAbstraction(indexName); // Allow indexing assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportUpdateAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(BulkAction.NAME).test(indexAbstraction), is(true)); // Allow create and delete index, modifying aliases, and updating index settings assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(true)); @@ -1153,7 +1195,7 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteDataStreamAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAliasesAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndicesAliasesAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndicesAliasesAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(indexAbstraction), is(true)); // Implied by the overall view_index_metadata and monitor privilege @@ -1170,7 +1212,7 @@ public void testKibanaSystemRole() { ); // Deny deleting documents and rollover - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(RolloverAction.NAME).test(indexAbstraction), is(false)); }); @@ -1180,19 +1222,19 @@ public void testKibanaSystemRole() { final IndexAbstraction indexAbstraction = mockIndexAbstraction(indexName); // Allow search and indexing assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportUpdateAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(BulkAction.NAME).test(indexAbstraction), is(true)); // Allow create and delete index, modifying aliases, and updating index settings assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAliasesAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndicesAliasesAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndicesAliasesAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(indexAbstraction), is(true)); // Allow deleting documents - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(indexAbstraction), is(true)); // Implied by the overall view_index_metadata and monitor privilege assertViewIndexMetadata(kibanaRole, indexName); @@ -1215,15 +1257,15 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher("indices:foo").test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher("indices:bar").test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(PutMappingAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(RolloverAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); // Implied by the overall view_index_metadata and monitor privilege assertViewIndexMetadata(kibanaRole, indexName); @@ -1241,9 +1283,9 @@ public void testKibanaSystemRole() { final IndexAbstraction indexAbstraction = mockIndexAbstraction(indexName); // Allow indexing assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportUpdateAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(BulkAction.NAME).test(indexAbstraction), is(true)); // Allow create and delete index assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(true)); @@ -1266,11 +1308,11 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(PutMappingAction.NAME).test(indexAbstraction), is(true)); @@ -1284,11 +1326,11 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(PutMappingAction.NAME).test(indexAbstraction), is(true)); @@ -1307,16 +1349,16 @@ public void testKibanaSystemRole() { final IndexAbstraction indexAbstraction = mockIndexAbstraction(indexName); // Allow indexing assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportUpdateAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(BulkAction.NAME).test(indexAbstraction), is(true)); // Allow create and delete index, modifying aliases, and updating index settings assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(AutoCreateAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateDataStreamAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAliasesAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndicesAliasesAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndicesAliasesAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(indexAbstraction), is(true)); // Implied by the overall view_index_metadata and monitor privilege @@ -1341,11 +1383,11 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(false)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(false)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(indexAbstraction), is(false)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(PutMappingAction.NAME).test(indexAbstraction), is(true)); @@ -1382,15 +1424,15 @@ public void testKibanaSystemRole() { final IndexAbstraction indexAbstraction = mockIndexAbstraction(indexName); // Allow search and indexing assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportUpdateAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(BulkAction.NAME).test(indexAbstraction), is(true)); // Allow create and delete index, modifying aliases, and updating index settings assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAliasesAction.NAME).test(indexAbstraction), is(true)); - assertThat(kibanaRole.indices().allowedIndicesMatcher(IndicesAliasesAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndicesAliasesAction.NAME).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(indexAbstraction), is(true)); // Implied by the overall view_index_metadata and monitor privilege @@ -1428,7 +1470,7 @@ public void testKibanaAdminRole() { RESTRICTED_INDICES, List.of(new ApplicationPrivilegeDescriptor("kibana-.kibana", "all", Set.of(allowedApplicationActionPattern), Map.of())) ); - assertThat(kibanaAdminRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(false)); + assertThat(kibanaAdminRole.cluster().check(TransportClusterHealthAction.NAME, request, authentication), is(false)); assertThat(kibanaAdminRole.cluster().check(ClusterStateAction.NAME, request, authentication), is(false)); assertThat(kibanaAdminRole.cluster().check(ClusterStatsAction.NAME, request, authentication), is(false)); assertThat(kibanaAdminRole.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(false)); @@ -1439,8 +1481,11 @@ public void testKibanaAdminRole() { assertThat(kibanaAdminRole.runAs().check(randomAlphaOfLengthBetween(1, 12)), is(false)); - assertThat(kibanaAdminRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); - assertThat(kibanaAdminRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(".reporting")), is(false)); + assertThat(kibanaAdminRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); + assertThat( + kibanaAdminRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(".reporting")), + is(false) + ); assertThat( kibanaAdminRole.indices().allowedIndicesMatcher("indices:foo").test(mockIndexAbstraction(randomAlphaOfLengthBetween(8, 24))), is(false) @@ -1489,7 +1534,7 @@ public void testKibanaUserRole() { RESTRICTED_INDICES, List.of(new ApplicationPrivilegeDescriptor("kibana-.kibana", "all", Set.of(allowedApplicationActionPattern), Map.of())) ); - assertThat(kibanaUserRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(false)); + assertThat(kibanaUserRole.cluster().check(TransportClusterHealthAction.NAME, request, authentication), is(false)); assertThat(kibanaUserRole.cluster().check(ClusterStateAction.NAME, request, authentication), is(false)); assertThat(kibanaUserRole.cluster().check(ClusterStatsAction.NAME, request, authentication), is(false)); assertThat(kibanaUserRole.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(false)); @@ -1500,8 +1545,11 @@ public void testKibanaUserRole() { assertThat(kibanaUserRole.runAs().check(randomAlphaOfLengthBetween(1, 12)), is(false)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(".reporting")), is(false)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); + assertThat( + kibanaUserRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(".reporting")), + is(false) + ); assertThat( kibanaUserRole.indices().allowedIndicesMatcher("indices:foo").test(mockIndexAbstraction(randomAlphaOfLengthBetween(8, 24))), is(false) @@ -1569,7 +1617,7 @@ public void testMonitoringUserRole() { assertThat(monitoringUserRole.cluster().check(MainRestPlugin.MAIN_ACTION.name(), request, authentication), is(true)); assertThat(monitoringUserRole.cluster().check(XPackInfoAction.NAME, request, authentication), is(true)); assertThat(monitoringUserRole.cluster().check(TransportRemoteInfoAction.TYPE.name(), request, authentication), is(true)); - assertThat(monitoringUserRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(false)); + assertThat(monitoringUserRole.cluster().check(TransportClusterHealthAction.NAME, request, authentication), is(false)); assertThat(monitoringUserRole.cluster().check(ClusterStateAction.NAME, request, authentication), is(false)); assertThat(monitoringUserRole.cluster().check(ClusterStatsAction.NAME, request, authentication), is(false)); assertThat(monitoringUserRole.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(false)); @@ -1619,8 +1667,14 @@ public void testMonitoringUserRole() { assertThat(monitoringUserRole.indices().allowedIndicesMatcher("indices:bar").test(mockIndexAbstraction(index)), is(false)); assertThat(monitoringUserRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(monitoringUserRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(monitoringUserRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(monitoringUserRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat( + monitoringUserRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), + is(false) + ); + assertThat( + monitoringUserRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), + is(false) + ); assertThat( monitoringUserRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(mockIndexAbstraction(index)), is(false) @@ -1629,7 +1683,10 @@ public void testMonitoringUserRole() { monitoringUserRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true) ); - assertThat(monitoringUserRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat( + monitoringUserRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), + is(true) + ); assertThat(monitoringUserRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(mockIndexAbstraction(index)), is(true)); assertNoAccessAllowed(monitoringUserRole, TestRestrictedIndices.SAMPLE_RESTRICTED_NAMES); @@ -1693,7 +1750,7 @@ public void testRemoteMonitoringAgentRole() { new FieldPermissionsCache(Settings.EMPTY), RESTRICTED_INDICES ); - assertThat(remoteMonitoringAgentRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(true)); + assertThat(remoteMonitoringAgentRole.cluster().check(TransportClusterHealthAction.NAME, request, authentication), is(true)); assertThat(remoteMonitoringAgentRole.cluster().check(ClusterStateAction.NAME, request, authentication), is(true)); assertThat(remoteMonitoringAgentRole.cluster().check(ClusterStatsAction.NAME, request, authentication), is(true)); assertThat(remoteMonitoringAgentRole.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(true)); @@ -1763,11 +1820,15 @@ public void testRemoteMonitoringAgentRole() { is(true) ); assertThat( - remoteMonitoringAgentRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(monitoringIndex)), + remoteMonitoringAgentRole.indices() + .allowedIndicesMatcher(TransportIndexAction.NAME) + .test(mockIndexAbstraction(monitoringIndex)), is(true) ); assertThat( - remoteMonitoringAgentRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(monitoringIndex)), + remoteMonitoringAgentRole.indices() + .allowedIndicesMatcher(TransportDeleteAction.NAME) + .test(mockIndexAbstraction(monitoringIndex)), is(true) ); assertThat( @@ -1783,7 +1844,9 @@ public void testRemoteMonitoringAgentRole() { is(true) ); assertThat( - remoteMonitoringAgentRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(monitoringIndex)), + remoteMonitoringAgentRole.indices() + .allowedIndicesMatcher(TransportGetAction.TYPE.name()) + .test(mockIndexAbstraction(monitoringIndex)), is(true) ); assertThat( @@ -1809,7 +1872,9 @@ public void testRemoteMonitoringAgentRole() { is(true) ); assertThat( - remoteMonitoringAgentRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(metricbeatIndex)), + remoteMonitoringAgentRole.indices() + .allowedIndicesMatcher(TransportIndexAction.NAME) + .test(mockIndexAbstraction(metricbeatIndex)), is(true) ); assertThat( @@ -1822,7 +1887,7 @@ public void testRemoteMonitoringAgentRole() { ); assertThat( remoteMonitoringAgentRole.indices() - .allowedIndicesMatcher(IndicesAliasesAction.NAME) + .allowedIndicesMatcher(TransportIndicesAliasesAction.NAME) .test(mockIndexAbstraction(metricbeatIndex)), is(true) ); @@ -1843,7 +1908,9 @@ public void testRemoteMonitoringAgentRole() { is(false) ); assertThat( - remoteMonitoringAgentRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(metricbeatIndex)), + remoteMonitoringAgentRole.indices() + .allowedIndicesMatcher(TransportDeleteAction.NAME) + .test(mockIndexAbstraction(metricbeatIndex)), is(false) ); assertThat( @@ -1859,7 +1926,9 @@ public void testRemoteMonitoringAgentRole() { is(false) ); assertThat( - remoteMonitoringAgentRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(metricbeatIndex)), + remoteMonitoringAgentRole.indices() + .allowedIndicesMatcher(TransportGetAction.TYPE.name()) + .test(mockIndexAbstraction(metricbeatIndex)), is(false) ); @@ -1880,7 +1949,7 @@ public void testRemoteMonitoringCollectorRole() { new FieldPermissionsCache(Settings.EMPTY), RESTRICTED_INDICES ); - assertThat(remoteMonitoringCollectorRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(true)); + assertThat(remoteMonitoringCollectorRole.cluster().check(TransportClusterHealthAction.NAME, request, authentication), is(true)); assertThat(remoteMonitoringCollectorRole.cluster().check(ClusterStateAction.NAME, request, authentication), is(true)); assertThat(remoteMonitoringCollectorRole.cluster().check(ClusterStatsAction.NAME, request, authentication), is(true)); assertThat(remoteMonitoringCollectorRole.cluster().check(GetIndexTemplatesAction.NAME, request, authentication), is(true)); @@ -1916,7 +1985,9 @@ public void testRemoteMonitoringCollectorRole() { is(true) ); assertThat( - remoteMonitoringCollectorRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(".kibana")), + remoteMonitoringCollectorRole.indices() + .allowedIndicesMatcher(TransportGetAction.TYPE.name()) + .test(mockIndexAbstraction(".kibana")), is(true) ); assertThat( @@ -1948,7 +2019,7 @@ public void testRemoteMonitoringCollectorRole() { is(false) ); assertThat( - remoteMonitoringCollectorRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), + remoteMonitoringCollectorRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(false) ); assertThat( @@ -1966,7 +2037,7 @@ public void testRemoteMonitoringCollectorRole() { is(false) ); assertThat( - remoteMonitoringCollectorRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), + remoteMonitoringCollectorRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(false) ); assertThat( @@ -1980,7 +2051,9 @@ public void testRemoteMonitoringCollectorRole() { is(false) ); assertThat( - remoteMonitoringCollectorRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), + remoteMonitoringCollectorRole.indices() + .allowedIndicesMatcher(TransportGetAction.TYPE.name()) + .test(mockIndexAbstraction(index)), is(false) ); assertThat( @@ -2066,37 +2139,37 @@ public void testRemoteMonitoringCollectorRole() { ); assertThat( remoteMonitoringCollectorRole.indices() - .allowedIndicesMatcher(GetAction.NAME) + .allowedIndicesMatcher(TransportGetAction.TYPE.name()) .test(mockIndexAbstraction(randomFrom(TestRestrictedIndices.SAMPLE_RESTRICTED_NAMES))), is(false) ); assertThat( remoteMonitoringCollectorRole.indices() - .allowedIndicesMatcher(GetAction.NAME) + .allowedIndicesMatcher(TransportGetAction.TYPE.name()) .test(mockIndexAbstraction(XPackPlugin.ASYNC_RESULTS_INDEX + randomAlphaOfLengthBetween(0, 2))), is(false) ); assertThat( remoteMonitoringCollectorRole.indices() - .allowedIndicesMatcher(DeleteAction.NAME) + .allowedIndicesMatcher(TransportDeleteAction.NAME) .test(mockIndexAbstraction(randomFrom(TestRestrictedIndices.SAMPLE_RESTRICTED_NAMES))), is(false) ); assertThat( remoteMonitoringCollectorRole.indices() - .allowedIndicesMatcher(DeleteAction.NAME) + .allowedIndicesMatcher(TransportDeleteAction.NAME) .test(mockIndexAbstraction(XPackPlugin.ASYNC_RESULTS_INDEX + randomAlphaOfLengthBetween(0, 2))), is(false) ); assertThat( remoteMonitoringCollectorRole.indices() - .allowedIndicesMatcher(IndexAction.NAME) + .allowedIndicesMatcher(TransportIndexAction.NAME) .test(mockIndexAbstraction(randomFrom(TestRestrictedIndices.SAMPLE_RESTRICTED_NAMES))), is(false) ); assertThat( remoteMonitoringCollectorRole.indices() - .allowedIndicesMatcher(IndexAction.NAME) + .allowedIndicesMatcher(TransportIndexAction.NAME) .test(mockIndexAbstraction(XPackPlugin.ASYNC_RESULTS_INDEX + randomAlphaOfLengthBetween(0, 2))), is(false) ); @@ -2158,7 +2231,7 @@ public void testReportingUserRole() { new FieldPermissionsCache(Settings.EMPTY), RESTRICTED_INDICES ); - assertThat(reportingUserRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(false)); + assertThat(reportingUserRole.cluster().check(TransportClusterHealthAction.NAME, request, authentication), is(false)); assertThat(reportingUserRole.cluster().check(ClusterStateAction.NAME, request, authentication), is(false)); assertThat(reportingUserRole.cluster().check(ClusterStatsAction.NAME, request, authentication), is(false)); assertThat(reportingUserRole.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(false)); @@ -2199,10 +2272,22 @@ public void testReportingUserRole() { reportingUserRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(false) ); - assertThat(reportingUserRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(reportingUserRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(reportingUserRole.indices().allowedIndicesMatcher(UpdateAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(reportingUserRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat( + reportingUserRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), + is(false) + ); + assertThat( + reportingUserRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), + is(false) + ); + assertThat( + reportingUserRole.indices().allowedIndicesMatcher(TransportUpdateAction.NAME).test(mockIndexAbstraction(index)), + is(false) + ); + assertThat( + reportingUserRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), + is(false) + ); assertThat(reportingUserRole.indices().allowedIndicesMatcher(BulkAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertNoAccessAllowed(reportingUserRole, TestRestrictedIndices.SAMPLE_RESTRICTED_NAMES); @@ -2218,7 +2303,7 @@ public void testSuperuserRole() { assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role superuserRole = Role.buildFromRoleDescriptor(roleDescriptor, new FieldPermissionsCache(Settings.EMPTY), RESTRICTED_INDICES); - assertThat(superuserRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(true)); + assertThat(superuserRole.cluster().check(TransportClusterHealthAction.NAME, request, authentication), is(true)); assertThat(superuserRole.cluster().check(ClusterUpdateSettingsAction.NAME, request, authentication), is(true)); assertThat(superuserRole.cluster().check(PutUserAction.NAME, request, authentication), is(true)); assertThat(superuserRole.cluster().check(PutRoleAction.NAME, request, authentication), is(true)); @@ -2273,7 +2358,7 @@ public void testSuperuserRole() { iac = superuserRole.indices().authorize(DeleteIndexAction.NAME, Sets.newHashSet("a1", "ba"), lookup, fieldPermissionsCache); assertThat(iac.hasIndexPermissions("a1"), is(true)); assertThat(iac.hasIndexPermissions("b"), is(true)); - iac = superuserRole.indices().authorize(IndexAction.NAME, Sets.newHashSet("a2", "ba"), lookup, fieldPermissionsCache); + iac = superuserRole.indices().authorize(TransportIndexAction.NAME, Sets.newHashSet("a2", "ba"), lookup, fieldPermissionsCache); assertThat(iac.hasIndexPermissions("a2"), is(true)); assertThat(iac.hasIndexPermissions("b"), is(true)); iac = superuserRole.indices().authorize(UpdateSettingsAction.NAME, Sets.newHashSet("aaaaaa", "ba"), lookup, fieldPermissionsCache); @@ -2294,7 +2379,7 @@ public void testSuperuserRole() { // Write security indices => denied iac = superuserRole.indices() .authorize( - randomFrom(IndexAction.NAME, DeleteIndexAction.NAME), + randomFrom(TransportIndexAction.NAME, DeleteIndexAction.NAME), Sets.newHashSet(TestRestrictedIndices.SECURITY_MAIN_ALIAS), lookup, fieldPermissionsCache @@ -2310,13 +2395,13 @@ public void testSuperuserRole() { // Read security indices => allowed assertThat( superuserRole.indices() - .allowedIndicesMatcher(randomFrom(GetAction.NAME, IndicesStatsAction.NAME)) + .allowedIndicesMatcher(randomFrom(TransportGetAction.TYPE.name(), IndicesStatsAction.NAME)) .test(mockIndexAbstraction(TestRestrictedIndices.SECURITY_MAIN_ALIAS)), is(true) ); assertThat( superuserRole.indices() - .allowedIndicesMatcher(randomFrom(GetAction.NAME, IndicesStatsAction.NAME)) + .allowedIndicesMatcher(randomFrom(TransportGetAction.TYPE.name(), IndicesStatsAction.NAME)) .test(mockIndexAbstraction(internalSecurityIndex)), is(true) ); @@ -2324,13 +2409,13 @@ public void testSuperuserRole() { // Write security indices => denied assertThat( superuserRole.indices() - .allowedIndicesMatcher(randomFrom(IndexAction.NAME, DeleteIndexAction.NAME)) + .allowedIndicesMatcher(randomFrom(TransportIndexAction.NAME, DeleteIndexAction.NAME)) .test(mockIndexAbstraction(TestRestrictedIndices.SECURITY_MAIN_ALIAS)), is(false) ); assertThat( superuserRole.indices() - .allowedIndicesMatcher(randomFrom(IndexAction.NAME, DeleteIndexAction.NAME)) + .allowedIndicesMatcher(randomFrom(TransportIndexAction.NAME, DeleteIndexAction.NAME)) .test(mockIndexAbstraction(internalSecurityIndex)), is(false) ); @@ -2349,7 +2434,7 @@ public void testLogstashSystemRole() { new FieldPermissionsCache(Settings.EMPTY), RESTRICTED_INDICES ); - assertThat(logstashSystemRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(true)); + assertThat(logstashSystemRole.cluster().check(TransportClusterHealthAction.NAME, request, authentication), is(true)); assertThat(logstashSystemRole.cluster().check(ClusterStateAction.NAME, request, authentication), is(true)); assertThat(logstashSystemRole.cluster().check(ClusterStatsAction.NAME, request, authentication), is(true)); assertThat(logstashSystemRole.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(false)); @@ -2360,9 +2445,12 @@ public void testLogstashSystemRole() { assertThat(logstashSystemRole.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false)); - assertThat(logstashSystemRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); assertThat( - logstashSystemRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(".reporting")), + logstashSystemRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction("foo")), + is(false) + ); + assertThat( + logstashSystemRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(".reporting")), is(false) ); assertThat( @@ -2387,7 +2475,7 @@ public void testBeatsAdminRole() { new FieldPermissionsCache(Settings.EMPTY), RESTRICTED_INDICES ); - assertThat(beatsAdminRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(false)); + assertThat(beatsAdminRole.cluster().check(TransportClusterHealthAction.NAME, request, authentication), is(false)); assertThat(beatsAdminRole.cluster().check(ClusterStateAction.NAME, request, authentication), is(false)); assertThat(beatsAdminRole.cluster().check(ClusterStatsAction.NAME, request, authentication), is(false)); assertThat(beatsAdminRole.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(false)); @@ -2414,8 +2502,8 @@ public void testBeatsAdminRole() { assertThat(beatsAdminRole.indices().allowedIndicesMatcher("indices:bar").test(mockIndexAbstraction(index)), is(true)); assertThat(beatsAdminRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat(beatsAdminRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(beatsAdminRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(beatsAdminRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat(beatsAdminRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat(beatsAdminRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat(beatsAdminRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat( beatsAdminRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), @@ -2425,7 +2513,10 @@ public void testBeatsAdminRole() { beatsAdminRole.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true) ); - assertThat(beatsAdminRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat( + beatsAdminRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), + is(true) + ); assertNoAccessAllowed(beatsAdminRole, TestRestrictedIndices.SAMPLE_RESTRICTED_NAMES); assertNoAccessAllowed(beatsAdminRole, XPackPlugin.ASYNC_RESULTS_INDEX + randomAlphaOfLengthBetween(0, 2)); @@ -2440,7 +2531,7 @@ public void testBeatsSystemRole() { assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role beatsSystemRole = Role.buildFromRoleDescriptor(roleDescriptor, new FieldPermissionsCache(Settings.EMPTY), RESTRICTED_INDICES); - assertThat(beatsSystemRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(true)); + assertThat(beatsSystemRole.cluster().check(TransportClusterHealthAction.NAME, request, authentication), is(true)); assertThat(beatsSystemRole.cluster().check(ClusterStateAction.NAME, request, authentication), is(true)); assertThat(beatsSystemRole.cluster().check(ClusterStatsAction.NAME, request, authentication), is(true)); assertThat(beatsSystemRole.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(false)); @@ -2458,15 +2549,21 @@ public void testBeatsSystemRole() { final String index = ".monitoring-beats-" + randomIntBetween(0, 5); logger.info("beats monitoring index name [{}]", index); - assertThat(beatsSystemRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); - assertThat(beatsSystemRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(".reporting")), is(false)); + assertThat(beatsSystemRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); + assertThat( + beatsSystemRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(".reporting")), + is(false) + ); assertThat( beatsSystemRole.indices().allowedIndicesMatcher("indices:foo").test(mockIndexAbstraction(randomAlphaOfLengthBetween(8, 24))), is(false) ); assertThat(beatsSystemRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(beatsSystemRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(beatsSystemRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(beatsSystemRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat( + beatsSystemRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), + is(false) + ); assertThat(beatsSystemRole.indices().allowedIndicesMatcher(BulkAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertNoAccessAllowed(beatsSystemRole, TestRestrictedIndices.SAMPLE_RESTRICTED_NAMES); @@ -2482,7 +2579,7 @@ public void testAPMSystemRole() { assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role APMSystemRole = Role.buildFromRoleDescriptor(roleDescriptor, new FieldPermissionsCache(Settings.EMPTY), RESTRICTED_INDICES); - assertThat(APMSystemRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(true)); + assertThat(APMSystemRole.cluster().check(TransportClusterHealthAction.NAME, request, authentication), is(true)); assertThat(APMSystemRole.cluster().check(ClusterStateAction.NAME, request, authentication), is(true)); assertThat(APMSystemRole.cluster().check(ClusterStatsAction.NAME, request, authentication), is(true)); assertThat(APMSystemRole.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(false)); @@ -2493,8 +2590,11 @@ public void testAPMSystemRole() { assertThat(APMSystemRole.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false)); - assertThat(APMSystemRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); - assertThat(APMSystemRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(".reporting")), is(false)); + assertThat(APMSystemRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); + assertThat( + APMSystemRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(".reporting")), + is(false) + ); assertThat( APMSystemRole.indices().allowedIndicesMatcher("indices:foo").test(mockIndexAbstraction(randomAlphaOfLengthBetween(8, 24))), is(false) @@ -2508,7 +2608,7 @@ public void testAPMSystemRole() { APMSystemRole.indices().allowedIndicesMatcher("indices:data/write/index:op_type/create").test(mockIndexAbstraction(index)), is(true) ); - assertThat(APMSystemRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(APMSystemRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(APMSystemRole.indices().allowedIndicesMatcher(BulkAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat( @@ -3077,7 +3177,7 @@ public void testWatcherAdminRole() { assertThat(role.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false)); - assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); + assertThat(role.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); for (String index : new String[] { Watch.INDEX, HistoryStoreField.DATA_STREAM, TriggeredWatchStoreField.INDEX_NAME }) { assertOnlyReadAllowed(role, index); @@ -3108,9 +3208,9 @@ public void testWatcherUserRole() { assertThat(role.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false)); - assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); + assertThat(role.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); assertThat( - role.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(TriggeredWatchStoreField.INDEX_NAME)), + role.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(TriggeredWatchStoreField.INDEX_NAME)), is(false) ); @@ -3138,7 +3238,7 @@ public void testPredefinedViewerRole() { List.of(new ApplicationPrivilegeDescriptor("kibana-.kibana", "read", Set.of(allowedApplicationActionPattern), Map.of())) ); // No cluster privileges - assertThat(role.cluster().check(ClusterHealthAction.NAME, request, authentication), is(false)); + assertThat(role.cluster().check(TransportClusterHealthAction.NAME, request, authentication), is(false)); assertThat(role.cluster().check(ClusterStateAction.NAME, request, authentication), is(false)); assertThat(role.cluster().check(ClusterStatsAction.NAME, request, authentication), is(false)); assertThat(role.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(false)); @@ -3212,7 +3312,7 @@ public void testPredefinedEditorRole() { ); // No cluster privileges - assertThat(role.cluster().check(ClusterHealthAction.NAME, request, authentication), is(false)); + assertThat(role.cluster().check(TransportClusterHealthAction.NAME, request, authentication), is(false)); assertThat(role.cluster().check(ClusterStateAction.NAME, request, authentication), is(false)); assertThat(role.cluster().check(ClusterStatsAction.NAME, request, authentication), is(false)); assertThat(role.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(false)); @@ -3328,15 +3428,15 @@ private void assertAllIndicesAccessAllowed(Role role, String index) { assertThat(role.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat(role.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat(role.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(role.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat(role.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat(role.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true)); assertThat( role.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true) ); - assertThat(role.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true)); // inherits from 'all' assertThat(role.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(mockIndexAbstraction(index)), is(true)); } @@ -3344,10 +3444,10 @@ private void assertAllIndicesAccessAllowed(Role role, String index) { private void assertReadWriteDocsAndMaintenanceButNotDeleteIndexAllowed(Role role, String index) { assertThat(role.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(role.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true)); - assertThat(role.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(role.indices().allowedIndicesMatcher(UpdateAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(role.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportUpdateAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat(role.indices().allowedIndicesMatcher(BulkAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat(role.indices().allowedIndicesMatcher("indices:admin/refresh*").test(mockIndexAbstraction(index)), is(true)); assertThat(role.indices().allowedIndicesMatcher("indices:admin/flush*").test(mockIndexAbstraction(index)), is(true)); @@ -3358,10 +3458,10 @@ private void assertReadWriteDocsAndMaintenanceButNotDeleteIndexAllowed(Role role private void assertReadWriteDocsButNotDeleteIndexAllowed(Role role, String index) { assertThat(role.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(role.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true)); - assertThat(role.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(role.indices().allowedIndicesMatcher(UpdateAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(role.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportUpdateAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat(role.indices().allowedIndicesMatcher(BulkAction.NAME).test(mockIndexAbstraction(index)), is(true)); } @@ -3370,10 +3470,10 @@ private void assertOnlyReadAllowed(Role role, String index) { assertThat(role.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(role.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(role.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true)); - assertThat(role.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(role.indices().allowedIndicesMatcher(UpdateAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(role.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(role.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(role.indices().allowedIndicesMatcher(TransportUpdateAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(role.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(role.indices().allowedIndicesMatcher(BulkAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertNoAccessAllowed(role, TestRestrictedIndices.SAMPLE_RESTRICTED_NAMES); @@ -3393,7 +3493,7 @@ private void assertViewIndexMetadata(Role role, String index) { ExplainLifecycleAction.NAME, GetDataStreamAction.NAME, ResolveIndexAction.NAME, - FieldCapabilitiesAction.NAME + "*", + TransportFieldCapabilitiesAction.NAME + "*", GetRollupIndexCapsAction.NAME + "*" ).forEach(action -> assertThat(role.indices().allowedIndicesMatcher(action).test(mockIndexAbstraction(index)), is(true))); } @@ -3409,10 +3509,10 @@ private void assertNoAccessAllowed(Role role, String index) { assertThat(role.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(role.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(role.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(false)); - assertThat(role.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(role.indices().allowedIndicesMatcher(UpdateAction.NAME).test(mockIndexAbstraction(index)), is(false)); - assertThat(role.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(role.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), is(false)); + assertThat(role.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(role.indices().allowedIndicesMatcher(TransportUpdateAction.NAME).test(mockIndexAbstraction(index)), is(false)); + assertThat(role.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), is(false)); assertThat(role.indices().allowedIndicesMatcher(BulkAction.NAME).test(mockIndexAbstraction(index)), is(false)); } @@ -3429,7 +3529,7 @@ public void testLogstashAdminRole() { new FieldPermissionsCache(Settings.EMPTY), RESTRICTED_INDICES ); - assertThat(logstashAdminRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(false)); + assertThat(logstashAdminRole.cluster().check(TransportClusterHealthAction.NAME, request, authentication), is(false)); assertThat(logstashAdminRole.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(false)); assertThat(logstashAdminRole.cluster().check(ClusterRerouteAction.NAME, request, authentication), is(false)); assertThat(logstashAdminRole.cluster().check(ClusterUpdateSettingsAction.NAME, request, authentication), is(false)); @@ -3441,9 +3541,18 @@ public void testLogstashAdminRole() { assertThat(logstashAdminRole.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false)); - assertThat(logstashAdminRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction("foo")), is(false)); - assertThat(logstashAdminRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(".reporting")), is(false)); - assertThat(logstashAdminRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(".logstash")), is(true)); + assertThat( + logstashAdminRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction("foo")), + is(false) + ); + assertThat( + logstashAdminRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(".reporting")), + is(false) + ); + assertThat( + logstashAdminRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(".logstash")), + is(true) + ); assertThat( logstashAdminRole.indices().allowedIndicesMatcher("indices:foo").test(mockIndexAbstraction(randomAlphaOfLengthBetween(8, 24))), is(false) @@ -3451,11 +3560,20 @@ public void testLogstashAdminRole() { final String index = ".logstash-" + randomIntBetween(0, 5); - assertThat(logstashAdminRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat( + logstashAdminRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(mockIndexAbstraction(index)), + is(true) + ); assertThat(logstashAdminRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); assertThat(logstashAdminRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(logstashAdminRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction(index)), is(true)); - assertThat(logstashAdminRole.indices().allowedIndicesMatcher(GetAction.NAME).test(mockIndexAbstraction(index)), is(true)); + assertThat( + logstashAdminRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction(index)), + is(true) + ); + assertThat( + logstashAdminRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(mockIndexAbstraction(index)), + is(true) + ); assertThat( logstashAdminRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(mockIndexAbstraction(index)), is(true) @@ -3561,7 +3679,7 @@ public void testEnrichUserRole() { assertTrue(role.cluster().check("cluster:admin/xpack/enrich/esql/resolve", request, authentication)); assertTrue(role.cluster().check("cluster:admin/xpack/enrich/esql/lookup", request, authentication)); assertFalse(role.runAs().check(randomAlphaOfLengthBetween(1, 30))); - assertFalse(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(mockIndexAbstraction("foo"))); + assertFalse(role.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(mockIndexAbstraction("foo"))); assertOnlyReadAllowed(role, ".enrich-foo"); } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/user/InternalUsersTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/user/InternalUsersTests.java index 6603353e967ea..f9a12b1fecf0b 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/user/InternalUsersTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/user/InternalUsersTests.java @@ -27,7 +27,7 @@ import org.elasticsearch.action.admin.indices.template.put.PutComponentTemplateAction; import org.elasticsearch.action.bulk.BulkAction; import org.elasticsearch.action.downsample.DownsampleAction; -import org.elasticsearch.action.get.GetAction; +import org.elasticsearch.action.get.TransportGetAction; import org.elasticsearch.cluster.metadata.DataStream; import org.elasticsearch.cluster.metadata.IndexAbstraction; import org.elasticsearch.cluster.metadata.IndexMetadata; @@ -87,7 +87,7 @@ public void testXPackUser() { checkClusterAccess(InternalUsers.XPACK_USER, role, randomFrom(sampleClusterActions), true); final List sampleIndexActions = List.of( - GetAction.NAME, + TransportGetAction.TYPE.name(), BulkAction.NAME, RefreshAction.NAME, CreateIndexAction.NAME, @@ -122,7 +122,7 @@ public void testXPackSecurityUser() { checkClusterAccess(InternalUsers.XPACK_SECURITY_USER, role, randomFrom(sampleClusterActions), true); final List sampleIndexActions = List.of( - GetAction.NAME, + TransportGetAction.TYPE.name(), BulkAction.NAME, RefreshAction.NAME, CreateIndexAction.NAME, @@ -149,7 +149,7 @@ public void testSecurityProfileUser() { assertThat(role.remoteIndices(), is(RemoteIndicesPermission.NONE)); final List sampleAllowedActions = List.of( - GetAction.NAME, + TransportGetAction.TYPE.name(), BulkAction.NAME, RefreshAction.NAME, CreateIndexAction.NAME, @@ -180,7 +180,7 @@ public void testAsyncSearchUser() { checkClusterAccess(InternalUsers.ASYNC_SEARCH_USER, role, ClusterStateAction.NAME, false); final List sampleAllowedActions = List.of( - GetAction.NAME, + TransportGetAction.TYPE.name(), BulkAction.NAME, RefreshAction.NAME, CreateIndexAction.NAME, @@ -212,7 +212,12 @@ public void testStorageUser() { checkIndexAccess(role, randomFrom(sampleAllowedActions), ".ds-" + randomAlphaOfLengthBetween(4, 8), true); checkIndexAccess(role, randomFrom(sampleAllowedActions), INTERNAL_SECURITY_MAIN_INDEX_7, true); - final List sampleDeniedActions = List.of(GetAction.NAME, BulkAction.NAME, PutMappingAction.NAME, DeleteIndexAction.NAME); + final List sampleDeniedActions = List.of( + TransportGetAction.TYPE.name(), + BulkAction.NAME, + PutMappingAction.NAME, + DeleteIndexAction.NAME + ); checkIndexAccess(role, randomFrom(sampleDeniedActions), randomAlphaOfLengthBetween(4, 8), false); checkIndexAccess(role, randomFrom(sampleDeniedActions), ".ds-" + randomAlphaOfLengthBetween(4, 8), false); checkIndexAccess(role, randomFrom(sampleDeniedActions), INTERNAL_SECURITY_MAIN_INDEX_7, false); diff --git a/x-pack/plugin/enrich/src/test/java/org/elasticsearch/xpack/enrich/EnrichPolicyRunnerTests.java b/x-pack/plugin/enrich/src/test/java/org/elasticsearch/xpack/enrich/EnrichPolicyRunnerTests.java index aac9f5e74cf0e..9ab7f7dea9b2d 100644 --- a/x-pack/plugin/enrich/src/test/java/org/elasticsearch/xpack/enrich/EnrichPolicyRunnerTests.java +++ b/x-pack/plugin/enrich/src/test/java/org/elasticsearch/xpack/enrich/EnrichPolicyRunnerTests.java @@ -13,7 +13,7 @@ import org.elasticsearch.action.ActionType; import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.LatchedActionListener; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.admin.indices.create.CreateIndexAction; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; @@ -2071,7 +2071,7 @@ public void testRunnerCancel() throws Exception { RefreshAction.INSTANCE, IndicesSegmentsAction.INSTANCE, UpdateSettingsAction.INSTANCE, - ClusterHealthAction.INSTANCE + TransportClusterHealthAction.TYPE ); logger.info("Selected [{}] to perform cancel", randomActionType.name()); Client client = new FilterClient(client()) { diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/rules/RuleQueryBuilderTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/rules/RuleQueryBuilderTests.java index c2876a9b9ee4d..1d19011fdd4a9 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/rules/RuleQueryBuilderTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/rules/RuleQueryBuilderTests.java @@ -11,9 +11,9 @@ import org.apache.lucene.search.Query; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.get.GetAction; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; +import org.elasticsearch.action.get.TransportGetAction; import org.elasticsearch.client.internal.Client; import org.elasticsearch.client.internal.ElasticsearchClient; import org.elasticsearch.common.ParsingException; @@ -131,7 +131,7 @@ protected Object simulateMethod(Method method, Object[] args) { // Get request, to pull the query ruleset from the system index using clientWithOrigin if (method.getDeclaringClass().equals(ElasticsearchClient.class) && method.getName().equals("execute") - && args[0] instanceof GetAction) { + && args[0] == TransportGetAction.TYPE) { GetRequest getRequest = (GetRequest) args[1]; assertThat(getRequest.index(), Matchers.equalTo(QueryRulesIndexService.QUERY_RULES_ALIAS_NAME)); diff --git a/x-pack/plugin/eql/src/internalClusterTest/java/org/elasticsearch/xpack/eql/action/AbstractEqlBlockingIntegTestCase.java b/x-pack/plugin/eql/src/internalClusterTest/java/org/elasticsearch/xpack/eql/action/AbstractEqlBlockingIntegTestCase.java index 9e43cc15f48cf..c0a286cc5c464 100644 --- a/x-pack/plugin/eql/src/internalClusterTest/java/org/elasticsearch/xpack/eql/action/AbstractEqlBlockingIntegTestCase.java +++ b/x-pack/plugin/eql/src/internalClusterTest/java/org/elasticsearch/xpack/eql/action/AbstractEqlBlockingIntegTestCase.java @@ -14,7 +14,7 @@ import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.admin.cluster.node.tasks.cancel.CancelTasksResponse; import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksResponse; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; +import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; import org.elasticsearch.action.support.ActionFilter; import org.elasticsearch.action.support.ActionFilterChain; import org.elasticsearch.common.settings.Settings; @@ -195,7 +195,7 @@ public void app ActionFilterChain chain ) { - if (action.equals(FieldCapabilitiesAction.NAME)) { + if (action.equals(TransportFieldCapabilitiesAction.NAME)) { final Consumer actionWrapper = resp -> { try { fieldCaps.incrementAndGet(); diff --git a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/DeleteExpiredDataIT.java b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/DeleteExpiredDataIT.java index 00fdaa348409a..8c245a4543abe 100644 --- a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/DeleteExpiredDataIT.java +++ b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/DeleteExpiredDataIT.java @@ -14,7 +14,7 @@ import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.support.WriteRequest; -import org.elasticsearch.action.update.UpdateAction; +import org.elasticsearch.action.update.TransportUpdateAction; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.common.Strings; import org.elasticsearch.core.TimeValue; @@ -233,7 +233,7 @@ private void testExpiredDeletion(Float customThrottle, int numUnusedState) throw String snapshotUpdate = "{ \"timestamp\": " + oneDayAgo + "}"; UpdateRequest updateSnapshotRequest = new UpdateRequest(".ml-anomalies-" + job.getId(), snapshotDocId); updateSnapshotRequest.doc(snapshotUpdate.getBytes(StandardCharsets.UTF_8), XContentType.JSON); - client().execute(UpdateAction.INSTANCE, updateSnapshotRequest).get(); + client().execute(TransportUpdateAction.TYPE, updateSnapshotRequest).get(); // Now let's create some forecasts openJob(job.getId()); diff --git a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/ModelSnapshotRetentionIT.java b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/ModelSnapshotRetentionIT.java index 11ab23bf665bd..a5c47524b6934 100644 --- a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/ModelSnapshotRetentionIT.java +++ b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/ModelSnapshotRetentionIT.java @@ -11,8 +11,8 @@ import org.elasticsearch.action.bulk.BulkAction; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.TransportSearchAction; import org.elasticsearch.action.support.PlainActionFuture; @@ -239,7 +239,7 @@ private void persistModelSnapshotDoc(String jobId, String snapshotId, Date times modelSnapshotBuilder.build().toXContent(xContentBuilder, ToXContent.EMPTY_PARAMS); indexRequest.source(xContentBuilder); - DocWriteResponse indexResponse = client().execute(IndexAction.INSTANCE, indexRequest).actionGet(); + DocWriteResponse indexResponse = client().execute(TransportIndexAction.TYPE, indexRequest).actionGet(); assertThat(indexResponse.getResult(), is(DocWriteResponse.Result.CREATED)); } diff --git a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/ModelSnapshotSearchIT.java b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/ModelSnapshotSearchIT.java index 9852517ff0231..aa85f78355fb3 100644 --- a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/ModelSnapshotSearchIT.java +++ b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/ModelSnapshotSearchIT.java @@ -11,8 +11,8 @@ import org.elasticsearch.action.bulk.BulkAction; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.action.support.master.MasterNodeRequest; @@ -126,7 +126,7 @@ private void persistModelSnapshotDoc(String jobId, String snapshotId, Date times modelSnapshotBuilder.build().toXContent(xContentBuilder, ToXContent.EMPTY_PARAMS); indexRequest.source(xContentBuilder); - DocWriteResponse indexResponse = client().execute(IndexAction.INSTANCE, indexRequest).actionGet(); + DocWriteResponse indexResponse = client().execute(TransportIndexAction.TYPE, indexRequest).actionGet(); assertThat(indexResponse.getResult(), is(DocWriteResponse.Result.CREATED)); } diff --git a/x-pack/plugin/ml/src/internalClusterTest/java/org/elasticsearch/xpack/ml/integration/JobsAndModelsIT.java b/x-pack/plugin/ml/src/internalClusterTest/java/org/elasticsearch/xpack/ml/integration/JobsAndModelsIT.java index 1458b9ccf693c..7f0a4cc381ee2 100644 --- a/x-pack/plugin/ml/src/internalClusterTest/java/org/elasticsearch/xpack/ml/integration/JobsAndModelsIT.java +++ b/x-pack/plugin/ml/src/internalClusterTest/java/org/elasticsearch/xpack/ml/integration/JobsAndModelsIT.java @@ -7,8 +7,8 @@ package org.elasticsearch.xpack.ml.integration; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.cluster.node.DiscoveryNodeRole; import org.elasticsearch.common.bytes.BytesArray; @@ -108,7 +108,7 @@ public void testCluster_GivenAnomalyDetectionJobAndTrainedModelDeployment_Should try (XContentBuilder builder = JsonXContent.contentBuilder()) { modelDefinitionDoc.toXContent(builder, null); client().execute( - IndexAction.INSTANCE, + TransportIndexAction.TYPE, new IndexRequest(InferenceIndexConstants.nativeDefinitionStore()).source(builder) .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) ).actionGet(); diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MlInitializationService.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MlInitializationService.java index e52a60691d150..d7c5f15fcaf47 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MlInitializationService.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MlInitializationService.java @@ -9,8 +9,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.TransportIndicesAliasesAction; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesAction; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse; @@ -202,7 +202,7 @@ private void makeMlInternalIndicesHidden() { .map(aliasAction -> aliasAction.indices()[0] + ": " + String.join(",", aliasAction.aliases())) .collect(Collectors.joining("; ")); logger.debug("The following ML internal aliases will now be made hidden: [{}]", indicesWithNonHiddenAliasesString); - executeAsyncWithOrigin(client, ML_ORIGIN, IndicesAliasesAction.INSTANCE, indicesAliasesRequest, finalListener); + executeAsyncWithOrigin(client, ML_ORIGIN, TransportIndicesAliasesAction.TYPE, indicesAliasesRequest, finalListener); }, finalListener::onFailure); // Step 3: Once indices are hidden, fetch ML internal aliases to find out whether the aliases are hidden or not. diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportDeleteCalendarEventAction.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportDeleteCalendarEventAction.java index d7a50b5f87f04..60993e12a2088 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportDeleteCalendarEventAction.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportDeleteCalendarEventAction.java @@ -8,11 +8,11 @@ import org.elasticsearch.ResourceNotFoundException; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.delete.DeleteAction; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.delete.DeleteResponse; -import org.elasticsearch.action.get.GetAction; +import org.elasticsearch.action.delete.TransportDeleteAction; import org.elasticsearch.action.get.GetRequest; +import org.elasticsearch.action.get.TransportGetAction; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.HandledTransportAction; import org.elasticsearch.action.support.WriteRequest; @@ -67,7 +67,7 @@ protected void doExecute(Task task, DeleteCalendarEventAction.Request request, A ActionListener calendarListener = ActionListener.wrap(calendar -> { GetRequest getRequest = new GetRequest(MlMetaIndex.indexName(), eventId); - executeAsyncWithOrigin(client, ML_ORIGIN, GetAction.INSTANCE, getRequest, ActionListener.wrap(getResponse -> { + executeAsyncWithOrigin(client, ML_ORIGIN, TransportGetAction.TYPE, getRequest, ActionListener.wrap(getResponse -> { if (getResponse.isExists() == false) { listener.onFailure(new ResourceNotFoundException("No event with id [" + eventId + "]")); return; @@ -115,7 +115,7 @@ private void deleteEvent(String eventId, Calendar calendar, ActionListener() { + executeAsyncWithOrigin(client, ML_ORIGIN, TransportDeleteAction.TYPE, deleteRequest, new ActionListener() { @Override public void onResponse(DeleteResponse response) { diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportFinalizeJobExecutionAction.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportFinalizeJobExecutionAction.java index 80fabff58d101..6d183501d2043 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportFinalizeJobExecutionAction.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportFinalizeJobExecutionAction.java @@ -13,7 +13,7 @@ import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.action.support.master.AcknowledgedTransportMasterNodeAction; -import org.elasticsearch.action.update.UpdateAction; +import org.elasticsearch.action.update.TransportUpdateAction; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.ClusterState; @@ -94,7 +94,7 @@ protected void masterOperation( executeAsyncWithOrigin( client, ML_ORIGIN, - UpdateAction.INSTANCE, + TransportUpdateAction.TYPE, updateRequest, ActionListener.wrap(updateResponse -> chainedListener.onResponse(null), chainedListener::onFailure) ); diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportPreviewDatafeedAction.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportPreviewDatafeedAction.java index 5dd671962569a..9d28619ba1db6 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportPreviewDatafeedAction.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportPreviewDatafeedAction.java @@ -8,8 +8,8 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.fieldcaps.FieldCapabilities; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest; +import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.HandledTransportAction; import org.elasticsearch.client.internal.Client; @@ -197,7 +197,7 @@ private void isDateNanos(DatafeedConfig datafeed, String timeField, ActionListen datafeed.getHeaders(), ML_ORIGIN, client, - FieldCapabilitiesAction.INSTANCE, + TransportFieldCapabilitiesAction.TYPE, fieldCapabilitiesRequest, ActionListener.wrap(fieldCapsResponse -> { Map timeFieldCaps = fieldCapsResponse.getField(timeField); diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportPutCalendarAction.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportPutCalendarAction.java index df8fd9c506924..119b1d2e9ab1b 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportPutCalendarAction.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportPutCalendarAction.java @@ -9,8 +9,8 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.DocWriteRequest; import org.elasticsearch.action.DocWriteResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.HandledTransportAction; import org.elasticsearch.action.support.WriteRequest; @@ -65,7 +65,7 @@ protected void doExecute(Task task, PutCalendarAction.Request request, ActionLis indexRequest.opType(DocWriteRequest.OpType.CREATE); indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE); - executeAsyncWithOrigin(client, ML_ORIGIN, IndexAction.INSTANCE, indexRequest, new ActionListener<>() { + executeAsyncWithOrigin(client, ML_ORIGIN, TransportIndexAction.TYPE, indexRequest, new ActionListener<>() { @Override public void onResponse(DocWriteResponse indexResponse) { listener.onResponse(new PutCalendarAction.Response(calendar)); diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportPutFilterAction.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportPutFilterAction.java index ea37661c7c08e..9237c23e537c1 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportPutFilterAction.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportPutFilterAction.java @@ -10,8 +10,8 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.DocWriteRequest; import org.elasticsearch.action.DocWriteResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.HandledTransportAction; import org.elasticsearch.action.support.WriteRequest; @@ -59,7 +59,7 @@ protected void doExecute(Task task, PutFilterAction.Request request, ActionListe throw new IllegalStateException("Failed to serialise filter with id [" + filter.getId() + "]", e); } - executeAsyncWithOrigin(client, ML_ORIGIN, IndexAction.INSTANCE, indexRequest, new ActionListener<>() { + executeAsyncWithOrigin(client, ML_ORIGIN, TransportIndexAction.TYPE, indexRequest, new ActionListener<>() { @Override public void onResponse(DocWriteResponse indexResponse) { listener.onResponse(new PutFilterAction.Response(filter)); diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportUpdateFilterAction.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportUpdateFilterAction.java index 622d5ccab6940..c1e77d953ab54 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportUpdateFilterAction.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportUpdateFilterAction.java @@ -9,11 +9,11 @@ import org.elasticsearch.ResourceNotFoundException; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.DocWriteResponse; -import org.elasticsearch.action.get.GetAction; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; -import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.get.TransportGetAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.HandledTransportAction; import org.elasticsearch.action.support.WriteRequest; @@ -135,7 +135,7 @@ private void indexUpdatedFilter( throw new IllegalStateException("Failed to serialise filter with id [" + filter.getId() + "]", e); } - executeAsyncWithOrigin(client, ML_ORIGIN, IndexAction.INSTANCE, indexRequest, new ActionListener<>() { + executeAsyncWithOrigin(client, ML_ORIGIN, TransportIndexAction.TYPE, indexRequest, new ActionListener<>() { @Override public void onResponse(DocWriteResponse indexResponse) { jobManager.notifyFilterChanged( @@ -164,7 +164,7 @@ public void onFailure(Exception e) { private void getFilterWithVersion(String filterId, ActionListener listener) { GetRequest getRequest = new GetRequest(MlMetaIndex.indexName(), MlFilter.documentId(filterId)); - executeAsyncWithOrigin(client, ML_ORIGIN, GetAction.INSTANCE, getRequest, listener.delegateFailure((l, getDocResponse) -> { + executeAsyncWithOrigin(client, ML_ORIGIN, TransportGetAction.TYPE, getRequest, listener.delegateFailure((l, getDocResponse) -> { try { if (getDocResponse.isExists()) { BytesReference docSource = getDocResponse.getSourceAsBytesRef(); diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/extractor/scroll/ScrollDataExtractorFactory.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/extractor/scroll/ScrollDataExtractorFactory.java index 27838795aedd2..7d3a063e3435c 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/extractor/scroll/ScrollDataExtractorFactory.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/extractor/scroll/ScrollDataExtractorFactory.java @@ -9,9 +9,9 @@ import org.elasticsearch.ResourceNotFoundException; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.fieldcaps.FieldCapabilities; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse; +import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; import org.elasticsearch.client.internal.Client; import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.index.query.QueryBuilder; @@ -152,7 +152,7 @@ public static void create( .toArray(String[]::new); fieldCapabilitiesRequest.fields(requestFields); ClientHelper.executeWithHeaders(datafeed.getHeaders(), ClientHelper.ML_ORIGIN, client, () -> { - client.execute(FieldCapabilitiesAction.INSTANCE, fieldCapabilitiesRequest, fieldCapabilitiesHandler); + client.execute(TransportFieldCapabilitiesAction.TYPE, fieldCapabilitiesRequest, fieldCapabilitiesHandler); // This response gets discarded - the listener handles the real response return null; }); diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/persistence/DatafeedConfigProvider.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/persistence/DatafeedConfigProvider.java index 211fd8743f49c..56c34aa590fb9 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/persistence/DatafeedConfigProvider.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/persistence/DatafeedConfigProvider.java @@ -13,14 +13,14 @@ import org.elasticsearch.action.DelegatingActionListener; import org.elasticsearch.action.DocWriteRequest; import org.elasticsearch.action.DocWriteResponse; -import org.elasticsearch.action.delete.DeleteAction; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.delete.DeleteResponse; -import org.elasticsearch.action.get.GetAction; +import org.elasticsearch.action.delete.TransportDeleteAction; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; -import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.get.TransportGetAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.support.IndicesOptions; @@ -138,7 +138,7 @@ public void putDatafeedConfig( executeAsyncWithOrigin( client, ML_ORIGIN, - IndexAction.INSTANCE, + TransportIndexAction.TYPE, indexRequest, ActionListener.wrap(r -> listener.onResponse(Tuple.tuple(finalConfig, r)), e -> { if (ExceptionsHelper.unwrapCause(e) instanceof VersionConflictEngineException) { @@ -176,7 +176,7 @@ public void getDatafeedConfig( if (parentTaskId != null) { getRequest.setParentTask(parentTaskId); } - executeAsyncWithOrigin(client, ML_ORIGIN, GetAction.INSTANCE, getRequest, new ActionListener() { + executeAsyncWithOrigin(client, ML_ORIGIN, TransportGetAction.TYPE, getRequest, new ActionListener() { @Override public void onResponse(GetResponse getResponse) { if (getResponse.isExists() == false) { @@ -280,14 +280,20 @@ public void findDatafeedsByJobIds( public void deleteDatafeedConfig(String datafeedId, ActionListener actionListener) { DeleteRequest request = new DeleteRequest(MlConfigIndex.indexName(), DatafeedConfig.documentId(datafeedId)); request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE); - executeAsyncWithOrigin(client, ML_ORIGIN, DeleteAction.INSTANCE, request, actionListener.delegateFailure((l, deleteResponse) -> { - if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) { - l.onFailure(ExceptionsHelper.missingDatafeedException(datafeedId)); - return; - } - assert deleteResponse.getResult() == DocWriteResponse.Result.DELETED; - l.onResponse(deleteResponse); - })); + executeAsyncWithOrigin( + client, + ML_ORIGIN, + TransportDeleteAction.TYPE, + request, + actionListener.delegateFailure((l, deleteResponse) -> { + if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) { + l.onFailure(ExceptionsHelper.missingDatafeedException(datafeedId)); + return; + } + assert deleteResponse.getResult() == DocWriteResponse.Result.DELETED; + l.onResponse(deleteResponse); + }) + ); } /** @@ -314,42 +320,48 @@ public void updateDatefeedConfig( ) { GetRequest getRequest = new GetRequest(MlConfigIndex.indexName(), DatafeedConfig.documentId(datafeedId)); - executeAsyncWithOrigin(client, ML_ORIGIN, GetAction.INSTANCE, getRequest, new DelegatingActionListener<>(updatedConfigListener) { - @Override - public void onResponse(GetResponse getResponse) { - if (getResponse.isExists() == false) { - delegate.onFailure(ExceptionsHelper.missingDatafeedException(datafeedId)); - return; - } - final long seqNo = getResponse.getSeqNo(); - final long primaryTerm = getResponse.getPrimaryTerm(); - BytesReference source = getResponse.getSourceAsBytesRef(); - DatafeedConfig.Builder configBuilder; - try { - configBuilder = parseLenientlyFromSource(source); - } catch (IOException e) { - delegate.onFailure(new ElasticsearchParseException("Failed to parse datafeed config [" + datafeedId + "]", e)); - return; - } + executeAsyncWithOrigin( + client, + ML_ORIGIN, + TransportGetAction.TYPE, + getRequest, + new DelegatingActionListener<>(updatedConfigListener) { + @Override + public void onResponse(GetResponse getResponse) { + if (getResponse.isExists() == false) { + delegate.onFailure(ExceptionsHelper.missingDatafeedException(datafeedId)); + return; + } + final long seqNo = getResponse.getSeqNo(); + final long primaryTerm = getResponse.getPrimaryTerm(); + BytesReference source = getResponse.getSourceAsBytesRef(); + DatafeedConfig.Builder configBuilder; + try { + configBuilder = parseLenientlyFromSource(source); + } catch (IOException e) { + delegate.onFailure(new ElasticsearchParseException("Failed to parse datafeed config [" + datafeedId + "]", e)); + return; + } - DatafeedConfig updatedConfig; - try { - updatedConfig = update.apply(configBuilder.build(), headers, clusterService.state()); - } catch (Exception e) { - delegate.onFailure(e); - return; - } + DatafeedConfig updatedConfig; + try { + updatedConfig = update.apply(configBuilder.build(), headers, clusterService.state()); + } catch (Exception e) { + delegate.onFailure(e); + return; + } - ActionListener validatedListener = ActionListener.wrap( - ok -> indexUpdatedConfig(updatedConfig, seqNo, primaryTerm, ActionListener.wrap(indexResponse -> { - assert indexResponse.getResult() == DocWriteResponse.Result.UPDATED; - delegate.onResponse(updatedConfig); - }, delegate::onFailure)), - delegate::onFailure - ); - validator.accept(updatedConfig, validatedListener); + ActionListener validatedListener = ActionListener.wrap( + ok -> indexUpdatedConfig(updatedConfig, seqNo, primaryTerm, ActionListener.wrap(indexResponse -> { + assert indexResponse.getResult() == DocWriteResponse.Result.UPDATED; + delegate.onResponse(updatedConfig); + }, delegate::onFailure)), + delegate::onFailure + ); + validator.accept(updatedConfig, validatedListener); + } } - }); + ); } private void indexUpdatedConfig(DatafeedConfig updatedConfig, long seqNo, long primaryTerm, ActionListener listener) { @@ -362,7 +374,7 @@ private void indexUpdatedConfig(DatafeedConfig updatedConfig, long seqNo, long p indexRequest.setIfSeqNo(seqNo); indexRequest.setIfPrimaryTerm(primaryTerm); - executeAsyncWithOrigin(client, ML_ORIGIN, IndexAction.INSTANCE, indexRequest, listener); + executeAsyncWithOrigin(client, ML_ORIGIN, TransportIndexAction.TYPE, indexRequest, listener); } catch (IOException e) { listener.onFailure( diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/DataFrameAnalyticsTask.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/DataFrameAnalyticsTask.java index 7f50be8a663fe..1467bd6ca0530 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/DataFrameAnalyticsTask.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/DataFrameAnalyticsTask.java @@ -11,8 +11,8 @@ import org.apache.lucene.util.SetOnce; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.DocWriteResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.TransportSearchAction; @@ -262,7 +262,7 @@ void persistProgress(Client clientToUse, String jobId, Runnable runnable) { storedProgress.get().toXContent(jsonBuilder, Payload.XContent.EMPTY_PARAMS); indexRequest.source(jsonBuilder); } - executeAsyncWithOrigin(clientToUse, ML_ORIGIN, IndexAction.INSTANCE, indexRequest, indexProgressDocListener); + executeAsyncWithOrigin(clientToUse, ML_ORIGIN, TransportIndexAction.TYPE, indexRequest, indexProgressDocListener); }, e -> { LOGGER.error( () -> format("[%s] cannot persist progress as an error occurred while retrieving former progress document", jobId), diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/DestinationIndex.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/DestinationIndex.java index 4798e699f46c4..8c6b78f41285c 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/DestinationIndex.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/DestinationIndex.java @@ -18,9 +18,9 @@ import org.elasticsearch.action.admin.indices.settings.get.GetSettingsAction; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse; +import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.client.internal.Client; @@ -183,7 +183,7 @@ private static void getFieldCapsForRequiredFields( config.getHeaders(), ML_ORIGIN, client, - FieldCapabilitiesAction.INSTANCE, + TransportFieldCapabilitiesAction.TYPE, fieldCapabilitiesRequest, listener ); diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/extractor/ExtractedFieldsDetectorFactory.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/extractor/ExtractedFieldsDetectorFactory.java index 9e925ff3f8fee..1d78ad22f3f85 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/extractor/ExtractedFieldsDetectorFactory.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/extractor/ExtractedFieldsDetectorFactory.java @@ -14,9 +14,9 @@ import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.action.fieldcaps.FieldCapabilities; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse; +import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.TransportSearchAction; @@ -182,7 +182,7 @@ private void getFieldCaps(String[] index, DataFrameAnalyticsConfig config, Actio fieldCapabilitiesRequest.runtimeFields(config.getSource().getRuntimeMappings()); LOGGER.debug(() -> format("[%s] Requesting field caps for index %s", config.getId(), Arrays.toString(index))); ClientHelper.executeWithHeaders(config.getHeaders(), ML_ORIGIN, client, () -> { - client.execute(FieldCapabilitiesAction.INSTANCE, fieldCapabilitiesRequest, listener); + client.execute(TransportFieldCapabilitiesAction.TYPE, fieldCapabilitiesRequest, listener); // This response gets discarded - the listener handles the real response return null; }); diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/persistence/DataFrameAnalyticsConfigProvider.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/persistence/DataFrameAnalyticsConfigProvider.java index bbdd6167414a6..618cbc075bd99 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/persistence/DataFrameAnalyticsConfigProvider.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/persistence/DataFrameAnalyticsConfigProvider.java @@ -13,11 +13,11 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.DelegatingActionListener; import org.elasticsearch.action.DocWriteRequest; -import org.elasticsearch.action.get.GetAction; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; -import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.get.TransportGetAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.support.IndicesOptions; @@ -139,7 +139,7 @@ private void exists(String jobId, ActionListener listener) { GetRequest getRequest = new GetRequest(MlConfigIndex.indexName(), DataFrameAnalyticsConfig.documentId(jobId)); getRequest.fetchSourceContext(FetchSourceContext.DO_NOT_FETCH_SOURCE); - executeAsyncWithOrigin(client, ML_ORIGIN, GetAction.INSTANCE, getRequest, getListener); + executeAsyncWithOrigin(client, ML_ORIGIN, TransportGetAction.TYPE, getRequest, getListener); } private void deleteLeftOverDocs(DataFrameAnalyticsConfig config, TimeValue timeout, ActionListener listener) { @@ -166,7 +166,7 @@ public void update( String id = update.getId(); GetRequest getRequest = new GetRequest(MlConfigIndex.indexName(), DataFrameAnalyticsConfig.documentId(id)); - executeAsyncWithOrigin(client, ML_ORIGIN, GetAction.INSTANCE, getRequest, ActionListener.wrap(getResponse -> { + executeAsyncWithOrigin(client, ML_ORIGIN, TransportGetAction.TYPE, getRequest, ActionListener.wrap(getResponse -> { // Fail the update request if the config to be updated doesn't exist if (getResponse.isExists() == false) { @@ -255,7 +255,7 @@ private void index( executeAsyncWithOrigin( client, ML_ORIGIN, - IndexAction.INSTANCE, + TransportIndexAction.TYPE, indexRequest, ActionListener.wrap(indexResponse -> listener.onResponse(config), e -> { if (ExceptionsHelper.unwrapCause(e) instanceof VersionConflictEngineException) { diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/persistence/DataFrameAnalyticsDeleter.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/persistence/DataFrameAnalyticsDeleter.java index 4ceb3b693cf89..843d9d74a1c7d 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/persistence/DataFrameAnalyticsDeleter.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/persistence/DataFrameAnalyticsDeleter.java @@ -12,8 +12,8 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.bulk.BulkItemResponse; -import org.elasticsearch.action.delete.DeleteAction; import org.elasticsearch.action.delete.DeleteRequest; +import org.elasticsearch.action.delete.TransportDeleteAction; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.action.support.master.AcknowledgedResponse; @@ -107,7 +107,7 @@ private void deleteConfig(String id, ActionListener listen DeleteRequest deleteRequest = new DeleteRequest(MlConfigIndex.indexName()); deleteRequest.id(DataFrameAnalyticsConfig.documentId(id)); deleteRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE); - executeAsyncWithOrigin(client, ML_ORIGIN, DeleteAction.INSTANCE, deleteRequest, ActionListener.wrap(deleteResponse -> { + executeAsyncWithOrigin(client, ML_ORIGIN, TransportDeleteAction.TYPE, deleteRequest, ActionListener.wrap(deleteResponse -> { if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) { listener.onFailure(ExceptionsHelper.missingDataFrameAnalytics(id)); return; diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/steps/FinalStep.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/steps/FinalStep.java index 20791534b9801..7b27090dc302d 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/steps/FinalStep.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/steps/FinalStep.java @@ -14,8 +14,8 @@ import org.elasticsearch.action.admin.indices.refresh.RefreshAction; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.client.internal.node.NodeClient; import org.elasticsearch.core.TimeValue; @@ -83,7 +83,7 @@ private void indexDataCounts(ActionListener listener) { IndexRequest indexRequest = new IndexRequest(MlStatsIndex.writeAlias()).id(DataCounts.documentId(config.getId())) .setRequireAlias(true) .source(builder); - executeAsyncWithOrigin(parentTaskClient(), ML_ORIGIN, IndexAction.INSTANCE, indexRequest, listener); + executeAsyncWithOrigin(parentTaskClient(), ML_ORIGIN, TransportIndexAction.TYPE, indexRequest, listener); } catch (IOException e) { listener.onFailure(ExceptionsHelper.serverError("[{}] Error persisting final data counts", e, config.getId())); } diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/inference/persistence/TrainedModelProvider.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/inference/persistence/TrainedModelProvider.java index 02a841e44585f..2be4fe12884b0 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/inference/persistence/TrainedModelProvider.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/inference/persistence/TrainedModelProvider.java @@ -21,8 +21,8 @@ import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.bulk.BulkResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.MultiSearchRequest; import org.elasticsearch.action.search.MultiSearchResponse; import org.elasticsearch.action.search.SearchRequest; @@ -206,7 +206,7 @@ public void storeTrainedModelConfig(TrainedModelConfig trainedModelConfig, Actio executeAsyncWithOrigin( client, ML_ORIGIN, - IndexAction.INSTANCE, + TransportIndexAction.TYPE, request, ActionListener.wrap(indexResponse -> listener.onResponse(true), e -> { if (ExceptionsHelper.unwrapCause(e) instanceof VersionConflictEngineException) { @@ -255,7 +255,7 @@ public void storeTrainedModelVocabulary( executeAsyncWithOrigin( client, ML_ORIGIN, - IndexAction.INSTANCE, + TransportIndexAction.TYPE, createRequest(VocabularyConfig.docId(modelId), vocabularyConfig.getIndex(), vocabulary, allowOverwriting).setRefreshPolicy( WriteRequest.RefreshPolicy.IMMEDIATE ), @@ -303,7 +303,7 @@ public void storeTrainedModelDefinitionDoc( executeAsyncWithOrigin( client, ML_ORIGIN, - IndexAction.INSTANCE, + TransportIndexAction.TYPE, createRequest(trainedModelDefinitionDoc.getDocId(), index, trainedModelDefinitionDoc, allowOverwriting), ActionListener.wrap(indexResponse -> listener.onResponse(null), e -> { if (ExceptionsHelper.unwrapCause(e) instanceof VersionConflictEngineException) { @@ -353,7 +353,7 @@ public void storeTrainedModelMetadata( executeAsyncWithOrigin( client, ML_ORIGIN, - IndexAction.INSTANCE, + TransportIndexAction.TYPE, createRequest( trainedModelMetadata.getDocId(), InferenceIndexConstants.LATEST_INDEX_NAME, diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/persistence/JobConfigProvider.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/persistence/JobConfigProvider.java index 4c71f8fbce139..b77401f06f507 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/persistence/JobConfigProvider.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/persistence/JobConfigProvider.java @@ -14,14 +14,14 @@ import org.elasticsearch.action.DelegatingActionListener; import org.elasticsearch.action.DocWriteRequest; import org.elasticsearch.action.DocWriteResponse; -import org.elasticsearch.action.delete.DeleteAction; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.delete.DeleteResponse; -import org.elasticsearch.action.get.GetAction; +import org.elasticsearch.action.delete.TransportDeleteAction; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; -import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.get.TransportGetAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.support.IndicesOptions; @@ -127,14 +127,20 @@ public void putJob(Job job, ActionListener listener) { .opType(DocWriteRequest.OpType.CREATE) .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE); - executeAsyncWithOrigin(client, ML_ORIGIN, IndexAction.INSTANCE, indexRequest, ActionListener.wrap(listener::onResponse, e -> { - if (ExceptionsHelper.unwrapCause(e) instanceof VersionConflictEngineException) { - // the job already exists - listener.onFailure(ExceptionsHelper.jobAlreadyExists(job.getId())); - } else { - listener.onFailure(e); - } - })); + executeAsyncWithOrigin( + client, + ML_ORIGIN, + TransportIndexAction.TYPE, + indexRequest, + ActionListener.wrap(listener::onResponse, e -> { + if (ExceptionsHelper.unwrapCause(e) instanceof VersionConflictEngineException) { + // the job already exists + listener.onFailure(ExceptionsHelper.jobAlreadyExists(job.getId())); + } else { + listener.onFailure(e); + } + }) + ); } catch (IOException e) { listener.onFailure(new ElasticsearchParseException("Failed to serialise job with id [" + job.getId() + "]", e)); @@ -196,16 +202,22 @@ public void deleteJob(String jobId, boolean errorIfMissing, ActionListener { - if (errorIfMissing) { - if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) { - l.onFailure(ExceptionsHelper.missingJobException(jobId)); - return; + executeAsyncWithOrigin( + client, + ML_ORIGIN, + TransportDeleteAction.TYPE, + request, + actionListener.delegateFailure((l, deleteResponse) -> { + if (errorIfMissing) { + if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) { + l.onFailure(ExceptionsHelper.missingJobException(jobId)); + return; + } + assert deleteResponse.getResult() == DocWriteResponse.Result.DELETED; } - assert deleteResponse.getResult() == DocWriteResponse.Result.DELETED; - } - l.onResponse(deleteResponse); - })); + l.onResponse(deleteResponse); + }) + ); } /** @@ -223,7 +235,7 @@ public void deleteJob(String jobId, boolean errorIfMissing, ActionListener updatedJobListener) { GetRequest getRequest = new GetRequest(MlConfigIndex.indexName(), Job.documentId(jobId)); - executeAsyncWithOrigin(client, ML_ORIGIN, GetAction.INSTANCE, getRequest, new DelegatingActionListener<>(updatedJobListener) { + executeAsyncWithOrigin(client, ML_ORIGIN, TransportGetAction.TYPE, getRequest, new DelegatingActionListener<>(updatedJobListener) { @Override public void onResponse(GetResponse getResponse) { if (getResponse.isExists() == false) { @@ -285,7 +297,7 @@ public void updateJobWithValidation( ) { GetRequest getRequest = new GetRequest(MlConfigIndex.indexName(), Job.documentId(jobId)); - executeAsyncWithOrigin(client, ML_ORIGIN, GetAction.INSTANCE, getRequest, ActionListener.wrap(getResponse -> { + executeAsyncWithOrigin(client, ML_ORIGIN, TransportGetAction.TYPE, getRequest, ActionListener.wrap(getResponse -> { if (getResponse.isExists() == false) { listener.onFailure(ExceptionsHelper.missingJobException(jobId)); return; @@ -332,7 +344,7 @@ private void indexUpdatedJob(Job updatedJob, long seqNo, long primaryTerm, Actio indexRequest.setIfSeqNo(seqNo); indexRequest.setIfPrimaryTerm(primaryTerm); - executeAsyncWithOrigin(client, ML_ORIGIN, IndexAction.INSTANCE, indexRequest, ActionListener.wrap(indexResponse -> { + executeAsyncWithOrigin(client, ML_ORIGIN, TransportIndexAction.TYPE, indexRequest, ActionListener.wrap(indexResponse -> { assert indexResponse.getResult() == DocWriteResponse.Result.UPDATED; updatedJobListener.onResponse(updatedJob); }, updatedJobListener::onFailure)); @@ -366,7 +378,7 @@ public void jobExists(String jobId, boolean errorIfMissing, @Nullable TaskId par getRequest.setParentTask(parentTaskId); } - executeAsyncWithOrigin(client, ML_ORIGIN, GetAction.INSTANCE, getRequest, ActionListener.wrap(getResponse -> { + executeAsyncWithOrigin(client, ML_ORIGIN, TransportGetAction.TYPE, getRequest, ActionListener.wrap(getResponse -> { if (getResponse.isExists() == false) { if (errorIfMissing) { listener.onFailure(ExceptionsHelper.missingJobException(jobId)); diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/persistence/JobDataCountsPersister.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/persistence/JobDataCountsPersister.java index c3758aeda9b15..40951162045c3 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/persistence/JobDataCountsPersister.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/persistence/JobDataCountsPersister.java @@ -9,8 +9,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.client.internal.Client; import org.elasticsearch.xcontent.ToXContent; @@ -124,7 +124,7 @@ public void persistDataCountsAsync(String jobId, DataCounts counts, ActionListen .setRequireAlias(true) .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) .source(content); - executeAsyncWithOrigin(client, ML_ORIGIN, IndexAction.INSTANCE, request, listener.safeMap(r -> true)); + executeAsyncWithOrigin(client, ML_ORIGIN, TransportIndexAction.TYPE, request, listener.safeMap(r -> true)); } catch (IOException ioe) { String msg = "[" + jobId + "] Failed writing data_counts stats"; logger.error(msg, ioe); diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/action/TransportFinalizeJobExecutionActionTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/action/TransportFinalizeJobExecutionActionTests.java index 1c0243fcab098..25d9a9570c7c4 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/action/TransportFinalizeJobExecutionActionTests.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/action/TransportFinalizeJobExecutionActionTests.java @@ -11,7 +11,7 @@ import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.ActionTestUtils; import org.elasticsearch.action.support.master.AcknowledgedResponse; -import org.elasticsearch.action.update.UpdateAction; +import org.elasticsearch.action.update.TransportUpdateAction; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterState; @@ -59,7 +59,7 @@ private void setupMocks() { ActionListener listener = (ActionListener) invocationOnMock.getArguments()[2]; listener.onResponse(null); return null; - }).when(client).execute(eq(UpdateAction.INSTANCE), any(), any()); + }).when(client).execute(eq(TransportUpdateAction.TYPE), any(), any()); when(client.threadPool()).thenReturn(threadPool); when(threadPool.getThreadContext()).thenReturn(new ThreadContext(Settings.EMPTY)); @@ -76,7 +76,7 @@ public void testOperation() { action.masterOperation(null, request, clusterState, ActionTestUtils.assertNoFailureListener(ack::set)); assertTrue(ack.get().isAcknowledged()); - verify(client, times(2)).execute(eq(UpdateAction.INSTANCE), any(), any()); + verify(client, times(2)).execute(eq(TransportUpdateAction.TYPE), any(), any()); verify(clusterService, never()).submitUnbatchedStateUpdateTask(any(), any()); } diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/datafeed/extractor/DataExtractorFactoryTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/datafeed/extractor/DataExtractorFactoryTests.java index 680f7a2964f3d..4a7109f39df54 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/datafeed/extractor/DataExtractorFactoryTests.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/datafeed/extractor/DataExtractorFactoryTests.java @@ -8,8 +8,8 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.fieldcaps.FieldCapabilities; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse; +import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; import org.elasticsearch.action.support.ActionTestUtils; import org.elasticsearch.client.internal.Client; import org.elasticsearch.common.settings.Settings; @@ -94,7 +94,7 @@ public void setUpTests() { ActionListener listener = (ActionListener) invocationMock.getArguments()[2]; listener.onResponse(fieldsCapabilities); return null; - }).when(client).execute(same(FieldCapabilitiesAction.INSTANCE), any(), any()); + }).when(client).execute(same(TransportFieldCapabilitiesAction.TYPE), any(), any()); doAnswer(invocationMock -> { ActionListener listener = (ActionListener) invocationMock.getArguments()[2]; diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/dataframe/DataFrameAnalyticsTaskTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/dataframe/DataFrameAnalyticsTaskTests.java index 70bacebd3609f..63afc4ef6659c 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/dataframe/DataFrameAnalyticsTaskTests.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/dataframe/DataFrameAnalyticsTaskTests.java @@ -7,9 +7,9 @@ package org.elasticsearch.xpack.ml.dataframe; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.TransportSearchAction; import org.elasticsearch.client.internal.Client; @@ -191,7 +191,7 @@ private void testPersistProgress(SearchHits searchHits, String expectedIndexOrAl doAnswer(withResponse(searchResponse)).when(client).execute(eq(TransportSearchAction.TYPE), any(), any()); IndexResponse indexResponse = mock(IndexResponse.class); - doAnswer(withResponse(indexResponse)).when(client).execute(eq(IndexAction.INSTANCE), any(), any()); + doAnswer(withResponse(indexResponse)).when(client).execute(eq(TransportIndexAction.TYPE), any(), any()); TaskManager taskManager = mock(TaskManager.class); @@ -218,7 +218,7 @@ private void testPersistProgress(SearchHits searchHits, String expectedIndexOrAl InOrder inOrder = inOrder(client, runnable); inOrder.verify(client).execute(eq(TransportSearchAction.TYPE), any(), any()); - inOrder.verify(client).execute(eq(IndexAction.INSTANCE), indexRequestCaptor.capture(), any()); + inOrder.verify(client).execute(eq(TransportIndexAction.TYPE), indexRequestCaptor.capture(), any()); inOrder.verify(runnable).run(); inOrder.verifyNoMoreInteractions(); @@ -287,7 +287,7 @@ private void testSetFailed(boolean nodeShuttingDown) throws IOException { doAnswer(withResponse(searchResponse)).when(client).execute(eq(TransportSearchAction.TYPE), any(), any()); IndexResponse indexResponse = mock(IndexResponse.class); - doAnswer(withResponse(indexResponse)).when(client).execute(eq(IndexAction.INSTANCE), any(), any()); + doAnswer(withResponse(indexResponse)).when(client).execute(eq(TransportIndexAction.TYPE), any(), any()); DataFrameAnalyticsTask task = new DataFrameAnalyticsTask( 123, @@ -316,7 +316,7 @@ private void testSetFailed(boolean nodeShuttingDown) throws IOException { // Verify progress was persisted ArgumentCaptor indexRequestCaptor = ArgumentCaptor.forClass(IndexRequest.class); verify(client).execute(eq(TransportSearchAction.TYPE), any(), any()); - verify(client).execute(eq(IndexAction.INSTANCE), indexRequestCaptor.capture(), any()); + verify(client).execute(eq(TransportIndexAction.TYPE), indexRequestCaptor.capture(), any()); IndexRequest indexRequest = indexRequestCaptor.getValue(); assertThat(indexRequest.index(), equalTo(AnomalyDetectorsIndex.jobStateIndexWriteAlias())); diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/dataframe/DestinationIndexTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/dataframe/DestinationIndexTests.java index 9ec0540569689..d90696761e668 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/dataframe/DestinationIndexTests.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/dataframe/DestinationIndexTests.java @@ -20,9 +20,9 @@ import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.action.fieldcaps.FieldCapabilities; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse; +import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; import org.elasticsearch.action.support.ActionTestUtils; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.support.master.AcknowledgedResponse; @@ -293,7 +293,7 @@ private Map testCreateDestinationIndex(DataFrameAnalysis analysi }); doAnswer(callListenerOnResponse(fieldCapabilitiesResponse)).when(client) - .execute(eq(FieldCapabilitiesAction.INSTANCE), fieldCapabilitiesRequestCaptor.capture(), any()); + .execute(eq(TransportFieldCapabilitiesAction.TYPE), fieldCapabilitiesRequestCaptor.capture(), any()); String errorMessage = ""; switch (expectedError) { @@ -627,7 +627,7 @@ private Map testUpdateMappingsToDestIndex(DataFrameAnalysis anal }); doAnswer(callListenerOnResponse(fieldCapabilitiesResponse)).when(client) - .execute(eq(FieldCapabilitiesAction.INSTANCE), fieldCapabilitiesRequestCaptor.capture(), any()); + .execute(eq(TransportFieldCapabilitiesAction.TYPE), fieldCapabilitiesRequestCaptor.capture(), any()); DestinationIndex.updateMappingsToDestIndex( client, @@ -637,7 +637,7 @@ private Map testUpdateMappingsToDestIndex(DataFrameAnalysis anal ); verify(client, atLeastOnce()).threadPool(); - verify(client, atMost(1)).execute(eq(FieldCapabilitiesAction.INSTANCE), any(), any()); + verify(client, atMost(1)).execute(eq(TransportFieldCapabilitiesAction.TYPE), any(), any()); verify(client).execute(eq(PutMappingAction.INSTANCE), any(), any()); verifyNoMoreInteractions(client); diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/inference/persistence/TrainedModelProviderTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/inference/persistence/TrainedModelProviderTests.java index 164d4efe6b6f5..24b575b8f89be 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/inference/persistence/TrainedModelProviderTests.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/inference/persistence/TrainedModelProviderTests.java @@ -10,8 +10,8 @@ import org.elasticsearch.action.DocWriteRequest; import org.elasticsearch.action.bulk.BulkAction; import org.elasticsearch.action.bulk.BulkRequest; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.client.internal.Client; import org.elasticsearch.common.bytes.BytesArray; @@ -542,7 +542,7 @@ private Client createMockClient(ThreadPool threadPool) { private void assertThatIndexRequestHasOperation(Client client, DocWriteRequest.OpType operation) { var indexRequestArg = ArgumentCaptor.forClass(IndexRequest.class); - verify(client).execute(eq(IndexAction.INSTANCE), indexRequestArg.capture(), any()); + verify(client).execute(eq(TransportIndexAction.TYPE), indexRequestArg.capture(), any()); assertThat(indexRequestArg.getValue().opType(), Matchers.is(operation)); } diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/persistence/JobResultsPersisterTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/persistence/JobResultsPersisterTests.java index 696c32f9863ec..baae42b99640f 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/persistence/JobResultsPersisterTests.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/persistence/JobResultsPersisterTests.java @@ -11,9 +11,9 @@ import org.elasticsearch.action.bulk.BulkAction; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.TransportSearchAction; import org.elasticsearch.action.support.ActionTestUtils; @@ -373,7 +373,7 @@ private void testPersistQuantilesAsync(SearchHits searchHits, String expectedInd doAnswer(withResponse(searchResponse)).when(client).execute(eq(TransportSearchAction.TYPE), any(), any()); IndexResponse indexResponse = mock(IndexResponse.class); - doAnswer(withResponse(indexResponse)).when(client).execute(eq(IndexAction.INSTANCE), any(), any()); + doAnswer(withResponse(indexResponse)).when(client).execute(eq(TransportIndexAction.TYPE), any(), any()); Quantiles quantiles = new Quantiles("foo", new Date(), "bar"); ActionListener indexResponseListener = mock(ActionListener.class); @@ -381,7 +381,7 @@ private void testPersistQuantilesAsync(SearchHits searchHits, String expectedInd InOrder inOrder = inOrder(client, indexResponseListener); inOrder.verify(client).execute(eq(TransportSearchAction.TYPE), any(), any()); - inOrder.verify(client).execute(eq(IndexAction.INSTANCE), indexRequestCaptor.capture(), any()); + inOrder.verify(client).execute(eq(TransportIndexAction.TYPE), indexRequestCaptor.capture(), any()); inOrder.verify(indexResponseListener).onResponse(any()); inOrder.verifyNoMoreInteractions(); diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/process/autodetect/AutodetectProcessManagerTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/process/autodetect/AutodetectProcessManagerTests.java index 36828423ce8e9..aff3f006b1a8a 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/process/autodetect/AutodetectProcessManagerTests.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/process/autodetect/AutodetectProcessManagerTests.java @@ -10,6 +10,7 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionType; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.support.ActionTestUtils; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.client.internal.Client; @@ -163,6 +164,13 @@ public void setup() throws Exception { doAnswer(invocationOnMock -> { if (invocationOnMock.getArguments()[0] instanceof ActionType v) { ActionListener l = (ActionListener) invocationOnMock.getArguments()[2]; + if (v == TransportClusterHealthAction.TYPE) { + ActionListener listener = (ActionListener) l; + listener.onResponse( + new ClusterHealthResponse("test", new String[0], ClusterState.EMPTY_STATE, 0, 0, 0, TimeValue.ZERO) + ); + return null; + } ParameterizedType parameterizedType = (ParameterizedType) v.getClass().getGenericSuperclass(); Type t = parameterizedType.getActualTypeArguments()[0]; if (t.getTypeName().contains("AcknowledgedResponse")) { @@ -170,13 +178,6 @@ public void setup() throws Exception { listener.onResponse(AcknowledgedResponse.TRUE); return null; } - if (t.getTypeName().contains("ClusterHealthResponse")) { - ActionListener listener = (ActionListener) l; - listener.onResponse( - new ClusterHealthResponse("test", new String[0], ClusterState.EMPTY_STATE, 0, 0, 0, TimeValue.ZERO) - ); - return null; - } fail("Mock not configured to handle generic type " + t.getTypeName()); } return null; diff --git a/x-pack/plugin/searchable-snapshots/src/test/java/org/elasticsearch/xpack/searchablesnapshots/cache/blob/BlobStoreCacheServiceTests.java b/x-pack/plugin/searchable-snapshots/src/test/java/org/elasticsearch/xpack/searchablesnapshots/cache/blob/BlobStoreCacheServiceTests.java index b5e476ecbf25f..8083d3c729ba3 100644 --- a/x-pack/plugin/searchable-snapshots/src/test/java/org/elasticsearch/xpack/searchablesnapshots/cache/blob/BlobStoreCacheServiceTests.java +++ b/x-pack/plugin/searchable-snapshots/src/test/java/org/elasticsearch/xpack/searchablesnapshots/cache/blob/BlobStoreCacheServiceTests.java @@ -8,12 +8,12 @@ package org.elasticsearch.xpack.searchablesnapshots.cache.blob; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.get.GetAction; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; -import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.get.TransportGetAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.blobcache.common.ByteRange; import org.elasticsearch.client.internal.Client; @@ -98,7 +98,7 @@ public void testGetWhenServiceNotStarted() { ) ); return null; - }).when(mockClient).execute(eq(GetAction.INSTANCE), any(GetRequest.class), any(ActionListener.class)); + }).when(mockClient).execute(eq(TransportGetAction.TYPE), any(GetRequest.class), any(ActionListener.class)); BlobStoreCacheService blobCacheService = new BlobStoreCacheService(null, mockClient, SNAPSHOT_BLOB_CACHE_INDEX); blobCacheService.start(); @@ -130,7 +130,7 @@ public void testPutWhenServiceNotStarted() { ) ); return null; - }).when(mockClient).execute(eq(IndexAction.INSTANCE), any(IndexRequest.class), any(ActionListener.class)); + }).when(mockClient).execute(eq(TransportIndexAction.TYPE), any(IndexRequest.class), any(ActionListener.class)); BlobStoreCacheService blobCacheService = new BlobStoreCacheService(null, mockClient, SNAPSHOT_BLOB_CACHE_INDEX); blobCacheService.start(); @@ -168,7 +168,7 @@ public void testWaitForInFlightCacheFillsToComplete() throws Exception { ) ); return null; - }).when(mockClient).execute(eq(IndexAction.INSTANCE), any(IndexRequest.class), any(ActionListener.class)); + }).when(mockClient).execute(eq(TransportIndexAction.TYPE), any(IndexRequest.class), any(ActionListener.class)); final BlobStoreCacheService blobCacheService = new BlobStoreCacheService(null, mockClient, SNAPSHOT_BLOB_CACHE_INDEX); blobCacheService.start(); diff --git a/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityFcActionAuthorizationIT.java b/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityFcActionAuthorizationIT.java index a0b4222478e59..8b54bd060fa19 100644 --- a/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityFcActionAuthorizationIT.java +++ b/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityFcActionAuthorizationIT.java @@ -10,9 +10,9 @@ import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.TransportVersion; import org.elasticsearch.action.admin.cluster.remote.RemoteClusterNodesAction; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse; +import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; import org.elasticsearch.client.Request; import org.elasticsearch.client.Response; import org.elasticsearch.client.internal.Client; @@ -344,7 +344,7 @@ public void testUpdateCrossClusterApiKey() throws IOException { "node", threadPool, (String) crossClusterApiKeyMap.get("encoded"), - Map.of(FieldCapabilitiesAction.NAME, crossClusterAccessSubjectInfo) + Map.of(TransportFieldCapabilitiesAction.NAME, crossClusterAccessSubjectInfo) ) ) { final RemoteClusterService remoteClusterService = service.getRemoteClusterService(); @@ -360,7 +360,7 @@ public void testUpdateCrossClusterApiKey() throws IOException { // 1. Not accessible because API key does not grant the access final ElasticsearchSecurityException e1 = expectThrows( ElasticsearchSecurityException.class, - () -> remoteClusterClient.execute(FieldCapabilitiesAction.INSTANCE, request).actionGet() + () -> remoteClusterClient.execute(TransportFieldCapabilitiesAction.TYPE, request).actionGet() ); assertThat( e1.getMessage(), @@ -387,7 +387,7 @@ public void testUpdateCrossClusterApiKey() throws IOException { }"""); assertOK(performRequestWithAdminUser(adminClient(), updateApiKeyRequest)); final FieldCapabilitiesResponse fieldCapabilitiesResponse = remoteClusterClient.execute( - FieldCapabilitiesAction.INSTANCE, + TransportFieldCapabilitiesAction.TYPE, request ).actionGet(); assertThat(fieldCapabilitiesResponse.getIndices(), arrayContaining("index")); @@ -407,7 +407,7 @@ public void testUpdateCrossClusterApiKey() throws IOException { assertOK(performRequestWithAdminUser(adminClient(), updateApiKeyRequest)); final ElasticsearchSecurityException e2 = expectThrows( ElasticsearchSecurityException.class, - () -> remoteClusterClient.execute(FieldCapabilitiesAction.INSTANCE, request).actionGet() + () -> remoteClusterClient.execute(TransportFieldCapabilitiesAction.TYPE, request).actionGet() ); assertThat( e2.getMessage(), diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/SecurityFeatureStateIntegTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/SecurityFeatureStateIntegTests.java index 0b50b7cdfe78e..daea0e38c2c40 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/SecurityFeatureStateIntegTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/SecurityFeatureStateIntegTests.java @@ -9,7 +9,7 @@ import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusResponse; import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest; -import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.client.Request; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.Response; @@ -125,7 +125,7 @@ public void testSecurityFeatureStateSnapshotAndRestore() throws Exception { assertThat(exception.getResponse().getStatusLine().getStatusCode(), equalTo(403)); assertThat( exception.getMessage(), - containsString("action [" + IndexAction.NAME + "] is unauthorized for user [" + LOCAL_TEST_USER_NAME + "]") + containsString("action [" + TransportIndexAction.NAME + "] is unauthorized for user [" + LOCAL_TEST_USER_NAME + "]") ); client().admin().indices().prepareClose("test_index").get(); diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authc/ApiKeyIntegTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authc/ApiKeyIntegTests.java index 673956199677b..72a6b6049932c 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authc/ApiKeyIntegTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authc/ApiKeyIntegTests.java @@ -16,8 +16,8 @@ import org.elasticsearch.action.admin.indices.close.CloseIndexResponse; import org.elasticsearch.action.admin.indices.refresh.RefreshRequestBuilder; import org.elasticsearch.action.admin.indices.refresh.RefreshResponse; -import org.elasticsearch.action.get.GetAction; import org.elasticsearch.action.get.GetRequest; +import org.elasticsearch.action.get.TransportGetAction; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.Request; @@ -2834,7 +2834,7 @@ private void expectRoleDescriptorsForApiKey( } private Map getApiKeyDocument(String apiKeyId) { - return client().execute(GetAction.INSTANCE, new GetRequest(SECURITY_MAIN_ALIAS, apiKeyId)).actionGet().getSource(); + return client().execute(TransportGetAction.TYPE, new GetRequest(SECURITY_MAIN_ALIAS, apiKeyId)).actionGet().getSource(); } private ApiKey getApiKeyInfo(Client client, String apiKeyId, boolean withLimitedBy, boolean useGetApiKey) { diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authc/apikey/ApiKeySingleNodeTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authc/apikey/ApiKeySingleNodeTests.java index 9b1350a43f9a2..91884086af959 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authc/apikey/ApiKeySingleNodeTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authc/apikey/ApiKeySingleNodeTests.java @@ -9,15 +9,15 @@ import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.ElasticsearchStatusException; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequest; import org.elasticsearch.action.admin.cluster.node.info.TransportNodesInfoAction; import org.elasticsearch.action.admin.indices.create.CreateIndexAction; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; -import org.elasticsearch.action.get.GetAction; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; +import org.elasticsearch.action.get.TransportGetAction; import org.elasticsearch.action.ingest.GetPipelineAction; import org.elasticsearch.action.ingest.GetPipelineRequest; import org.elasticsearch.action.support.PlainActionFuture; @@ -314,7 +314,7 @@ public void testGrantApiKeyForUserWithRunAs() throws IOException { assertThat(securityClient.getApiKey(apiKeyId).getUsername(), equalTo("user2")); final Client clientWithGrantedKey = client().filterWithHeader(Map.of("Authorization", "ApiKey " + base64ApiKeyKeyValue)); // The API key has privileges (inherited from user2) to check cluster health - clientWithGrantedKey.execute(ClusterHealthAction.INSTANCE, new ClusterHealthRequest()).actionGet(); + clientWithGrantedKey.execute(TransportClusterHealthAction.TYPE, new ClusterHealthRequest()).actionGet(); // If the API key is granted with limiting descriptors, it should not be able to read pipeline if (grantApiKeyRequest.getApiKeyRequest().getRoleDescriptors().isEmpty()) { clientWithGrantedKey.execute(GetPipelineAction.INSTANCE, new GetPipelineRequest()).actionGet(); @@ -575,7 +575,7 @@ public void testCreateCrossClusterApiKey() throws IOException { ); // Check the API key attributes with raw document - final Map document = client().execute(GetAction.INSTANCE, new GetRequest(SECURITY_MAIN_ALIAS, apiKeyId)) + final Map document = client().execute(TransportGetAction.TYPE, new GetRequest(SECURITY_MAIN_ALIAS, apiKeyId)) .actionGet() .getSource(); assertThat(document.get("type"), equalTo("cross_cluster")); @@ -804,7 +804,7 @@ private GrantApiKeyRequest buildGrantApiKeyRequest(String username, SecureString } private Map getApiKeyDocument(String apiKeyId) { - final GetResponse getResponse = client().execute(GetAction.INSTANCE, new GetRequest(".security-7", apiKeyId)).actionGet(); + final GetResponse getResponse = client().execute(TransportGetAction.TYPE, new GetRequest(".security-7", apiKeyId)).actionGet(); return getResponse.getSource(); } } diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/IndexAliasesTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/IndexAliasesTests.java index f7bc8a1770981..7a0cb604f4ce9 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/IndexAliasesTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/IndexAliasesTests.java @@ -7,8 +7,8 @@ package org.elasticsearch.xpack.security.authz; import org.elasticsearch.action.admin.indices.alias.Alias; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.TransportIndicesAliasesAction; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesAction; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequestBuilder; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse; @@ -133,13 +133,13 @@ public void testCreateIndexThenAliasesCreateOnlyPermission() { assertThrowsAuthorizationException( client.admin().indices().prepareAliases().addAlias("test_1", "test_alias")::get, - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, "create_only" ); assertThrowsAuthorizationException( client.admin().indices().prepareAliases().addAlias("test_*", "test_alias")::get, - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, "create_only" ); } @@ -154,7 +154,7 @@ public void testCreateIndexAndAliasesCreateOnlyPermission() { assertThrowsAuthorizationException( client(headers).admin().indices().prepareCreate("test_1").addAlias(new Alias("test_2"))::get, - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, "create_only" ); } @@ -169,19 +169,19 @@ public void testDeleteAliasesCreateOnlyPermission() { assertThrowsAuthorizationException( client.admin().indices().prepareAliases().removeAlias("test_1", "alias_1")::get, - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, "create_only" ); assertThrowsAuthorizationException( client.admin().indices().prepareAliases().removeAlias("test_1", "alias_*")::get, - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, "create_only" ); assertThrowsAuthorizationException( client.admin().indices().prepareAliases().removeAlias("test_1", "_all")::get, - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, "create_only" ); } @@ -308,7 +308,7 @@ public void testCreateIndexThenAliasesCreateAndAliasesPermission() { // fails: user doesn't have manage_aliases on alias_1 assertThrowsAuthorizationException( client.admin().indices().prepareAliases().addAlias("test_1", "alias_1").addAlias("test_1", "test_alias")::get, - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, "create_test_aliases_test" ); } @@ -328,7 +328,7 @@ public void testCreateIndexAndAliasesCreateAndAliasesPermission() { // fails: user doesn't have manage_aliases on alias_1 assertThrowsAuthorizationException( client.admin().indices().prepareCreate("test_2").addAlias(new Alias("test_alias")).addAlias(new Alias("alias_2"))::get, - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, "create_test_aliases_test" ); } @@ -386,14 +386,14 @@ public void testDeleteAliasesCreateAndAliasesPermission() { // fails: user doesn't have manage_aliases on alias_1 assertThrowsAuthorizationException( client.admin().indices().prepareAliases().removeAlias("test_1", "alias_1")::get, - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, "create_test_aliases_test" ); // fails: user doesn't have manage_aliases on alias_1 assertThrowsAuthorizationException( client.admin().indices().prepareAliases().removeAlias("test_1", new String[] { "_all", "alias_1" })::get, - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, "create_test_aliases_test" ); @@ -471,14 +471,14 @@ public void testCreateIndexThenAliasesCreateAndAliasesPermission2() { // fails: user doesn't have manage_aliases aliases on test_1 assertThrowsAuthorizationException( client.admin().indices().prepareAliases().addAlias("test_1", "test_alias")::get, - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, "create_test_aliases_alias" ); // fails: user doesn't have manage_aliases aliases on test_1 assertThrowsAuthorizationException( client.admin().indices().prepareAliases().addAlias("test_1", "alias_1")::get, - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, "create_test_aliases_alias" ); @@ -503,7 +503,7 @@ public void testCreateIndexAndAliasesCreateAndAliasesPermission2() { // fails: user doesn't have manage_aliases on test_1, create index is rejected as a whole assertThrowsAuthorizationException( client.admin().indices().prepareCreate("test_1").addAlias(new Alias("test_alias"))::get, - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, "create_test_aliases_alias" ); } @@ -521,7 +521,7 @@ public void testDeleteAliasesCreateAndAliasesPermission2() { // fails: user doesn't have manage_aliases on test_1 assertThrowsAuthorizationException( client.admin().indices().prepareAliases().removeAlias("test_1", "test_alias")::get, - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, "create_test_aliases_alias" ); @@ -642,7 +642,7 @@ public void testDeleteAliasesCreateAndAliasesPermission3() { // fails: user doesn't have manage_aliases privilege on non_authorized assertThrowsAuthorizationException( client.admin().indices().prepareAliases().removeAlias("test_1", "non_authorized").removeAlias("test_1", "test_alias")::get, - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, "create_test_aliases_test_alias" ); diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/ReadActionsTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/ReadActionsTests.java index a5399e3699bb8..7e5fd3a8717e2 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/ReadActionsTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/ReadActionsTests.java @@ -7,9 +7,9 @@ package org.elasticsearch.xpack.security.authz; import org.elasticsearch.ElasticsearchSecurityException; -import org.elasticsearch.action.get.GetAction; -import org.elasticsearch.action.get.MultiGetAction; import org.elasticsearch.action.get.MultiGetResponse; +import org.elasticsearch.action.get.TransportGetAction; +import org.elasticsearch.action.get.TransportMultiGetAction; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; @@ -351,9 +351,9 @@ public void testGet() { client().prepareGet("test1", "id").get(); - assertThrowsAuthorizationExceptionDefaultUsers(client().prepareGet("index1", "id")::get, GetAction.NAME); + assertThrowsAuthorizationExceptionDefaultUsers(client().prepareGet("index1", "id")::get, TransportGetAction.TYPE.name()); - assertThrowsAuthorizationExceptionDefaultUsers(client().prepareGet("missing", "id")::get, GetAction.NAME); + assertThrowsAuthorizationExceptionDefaultUsers(client().prepareGet("missing", "id")::get, TransportGetAction.TYPE.name()); expectThrows(IndexNotFoundException.class, () -> client().prepareGet("test5", "id").get()); } @@ -374,7 +374,7 @@ public void testMultiGet() { assertEquals("index1", multiGetResponse.getResponses()[1].getFailure().getIndex()); assertAuthorizationExceptionDefaultUsers( multiGetResponse.getResponses()[1].getFailure().getFailure(), - MultiGetAction.NAME + "[shard]" + TransportMultiGetAction.NAME + "[shard]" ); assertFalse(multiGetResponse.getResponses()[2].isFailed()); assertEquals("test3", multiGetResponse.getResponses()[2].getResponse().getIndex()); diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/WriteActionsTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/WriteActionsTests.java index 8cd85297377ce..159228dd1c1b2 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/WriteActionsTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/WriteActionsTests.java @@ -12,7 +12,7 @@ import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.index.IndexRequest; -import org.elasticsearch.action.update.UpdateAction; +import org.elasticsearch.action.update.TransportUpdateAction; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.client.internal.Requests; import org.elasticsearch.core.Strings; @@ -88,7 +88,7 @@ public void testUpdate() { assertThrowsAuthorizationExceptionDefaultUsers( client().prepareUpdate("index1", "id").setDoc(Requests.INDEX_CONTENT_TYPE, "field2", "value2")::get, - UpdateAction.NAME + TransportUpdateAction.NAME ); expectThrows( @@ -98,7 +98,7 @@ public void testUpdate() { assertThrowsAuthorizationExceptionDefaultUsers( client().prepareUpdate("missing", "id").setDoc(Requests.INDEX_CONTENT_TYPE, "field2", "value2")::get, - UpdateAction.NAME + TransportUpdateAction.NAME ); ensureGreen(); } diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/user/AnonymousUserIntegTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/user/AnonymousUserIntegTests.java index 85b33b2ead61a..1a05807d158b0 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/user/AnonymousUserIntegTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/user/AnonymousUserIntegTests.java @@ -9,9 +9,9 @@ import org.apache.http.Header; import org.apache.http.util.EntityUtils; import org.elasticsearch.ElasticsearchStatusException; -import org.elasticsearch.action.get.GetAction; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; +import org.elasticsearch.action.get.TransportGetAction; import org.elasticsearch.client.Request; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.Response; @@ -169,7 +169,7 @@ public void testGrantApiKeyForAnonymousUserTokenWithRunAsWillFail() throws IOExc } private Map getApiKeyDocument(String apiKeyId) { - final GetResponse getResponse = client().execute(GetAction.INSTANCE, new GetRequest(".security-7", apiKeyId)).actionGet(); + final GetResponse getResponse = client().execute(TransportGetAction.TYPE, new GetRequest(".security-7", apiKeyId)).actionGet(); return getResponse.getSource(); } } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilter.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilter.java index bd951dc760b2c..997f58a01c0e1 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilter.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilter.java @@ -13,7 +13,7 @@ import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.IndicesRequest; -import org.elasticsearch.action.admin.indices.close.CloseIndexAction; +import org.elasticsearch.action.admin.indices.close.TransportCloseIndexAction; import org.elasticsearch.action.admin.indices.delete.DeleteIndexAction; import org.elasticsearch.action.admin.indices.open.OpenIndexAction; import org.elasticsearch.action.support.ActionFilter; @@ -131,7 +131,7 @@ private void ap Request request, ActionListener listener ) { - if (CloseIndexAction.NAME.equals(action) || OpenIndexAction.NAME.equals(action) || DeleteIndexAction.NAME.equals(action)) { + if (TransportCloseIndexAction.NAME.equals(action) || OpenIndexAction.NAME.equals(action) || DeleteIndexAction.NAME.equals(action)) { IndicesRequest indicesRequest = (IndicesRequest) request; try { destructiveOperations.failDestructive(indicesRequest.indices()); diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/TokenService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/TokenService.java index 794bcd96a66c3..aeb101ac0caa4 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/TokenService.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/TokenService.java @@ -27,8 +27,8 @@ import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.support.ContextPreservingActionListener; @@ -438,7 +438,7 @@ private void createOAuth2Tokens( () -> executeAsyncWithOrigin( client, SECURITY_ORIGIN, - IndexAction.INSTANCE, + TransportIndexAction.TYPE, indexTokenRequest, ActionListener.wrap(indexResponse -> { if (indexResponse.getResult() == Result.CREATED) { diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/service/IndexServiceAccountTokenStore.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/service/IndexServiceAccountTokenStore.java index 7749500465f65..c2d8be1c26629 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/service/IndexServiceAccountTokenStore.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/service/IndexServiceAccountTokenStore.java @@ -17,11 +17,11 @@ import org.elasticsearch.action.bulk.BulkAction; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.TransportBulkAction; -import org.elasticsearch.action.delete.DeleteAction; import org.elasticsearch.action.delete.DeleteRequest; -import org.elasticsearch.action.get.GetAction; +import org.elasticsearch.action.delete.TransportDeleteAction; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; +import org.elasticsearch.action.get.TransportGetAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.SearchRequest; @@ -108,7 +108,7 @@ void doAuthenticate(ServiceAccountToken token, ActionListener executeAsyncWithOrigin( client, SECURITY_ORIGIN, - GetAction.INSTANCE, + TransportGetAction.TYPE, getRequest, ActionListener.wrap(response -> { if (response.isExists()) { @@ -225,7 +225,7 @@ void deleteToken(DeleteServiceAccountTokenRequest request, ActionListener { final ClearSecurityCacheRequest clearSecurityCacheRequest = new ClearSecurityCacheRequest().cacheName( diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java index 142490aa90331..8a0a9c09b7d1a 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java @@ -16,18 +16,18 @@ import org.elasticsearch.action.DelegatingActionListener; import org.elasticsearch.action.DocWriteRequest; import org.elasticsearch.action.admin.indices.alias.Alias; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction; +import org.elasticsearch.action.admin.indices.alias.TransportIndicesAliasesAction; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.bulk.BulkItemRequest; import org.elasticsearch.action.bulk.BulkShardRequest; import org.elasticsearch.action.bulk.TransportShardBulkAction; import org.elasticsearch.action.datastreams.CreateDataStreamAction; import org.elasticsearch.action.datastreams.MigrateToDataStreamAction; -import org.elasticsearch.action.delete.DeleteAction; -import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.delete.TransportDeleteAction; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.support.GroupedActionListener; import org.elasticsearch.action.support.replication.TransportReplicationAction.ConcreteShardRequest; -import org.elasticsearch.action.update.UpdateAction; +import org.elasticsearch.action.update.TransportUpdateAction; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.service.ClusterService; @@ -115,8 +115,8 @@ public class AuthorizationService { PRINCIPAL_ROLES_FIELD_NAME, new String[] { SystemUser.ROLE_NAME } ); - private static final String IMPLIED_INDEX_ACTION = IndexAction.NAME + ":op_type/index"; - private static final String IMPLIED_CREATE_ACTION = IndexAction.NAME + ":op_type/create"; + private static final String IMPLIED_INDEX_ACTION = TransportIndexAction.NAME + ":op_type/index"; + private static final String IMPLIED_CREATE_ACTION = TransportIndexAction.NAME + ":op_type/create"; private static final Logger logger = LogManager.getLogger(AuthorizationService.class); @@ -557,7 +557,12 @@ private void handleIndexActionAuthorizationResult( runRequestInterceptors(requestInfo, authzInfo, authorizationEngine, listener); } else { Set aliases = ((CreateIndexRequest) request).aliases(); - final RequestInfo aliasesRequestInfo = new RequestInfo(authentication, request, IndicesAliasesAction.NAME, authzContext); + final RequestInfo aliasesRequestInfo = new RequestInfo( + authentication, + request, + TransportIndicesAliasesAction.NAME, + authzContext + ); authzEngine.authorizeIndexAction( aliasesRequestInfo, authzInfo, @@ -903,8 +908,8 @@ private static String getAction(BulkItemRequest item) { return switch (docWriteRequest.opType()) { case INDEX -> IMPLIED_INDEX_ACTION; case CREATE -> IMPLIED_CREATE_ACTION; - case UPDATE -> UpdateAction.NAME; - case DELETE -> DeleteAction.NAME; + case UPDATE -> TransportUpdateAction.NAME; + case DELETE -> TransportDeleteAction.NAME; }; } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/RBACEngine.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/RBACEngine.java index cdbb690098cbe..1c1fed5540248 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/RBACEngine.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/RBACEngine.java @@ -21,9 +21,9 @@ import org.elasticsearch.action.bulk.BulkAction; import org.elasticsearch.action.bulk.BulkShardRequest; import org.elasticsearch.action.bulk.SimulateBulkAction; -import org.elasticsearch.action.delete.DeleteAction; -import org.elasticsearch.action.get.MultiGetAction; -import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.delete.TransportDeleteAction; +import org.elasticsearch.action.get.TransportMultiGetAction; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.SearchScrollRequest; import org.elasticsearch.action.search.SearchTransportService; import org.elasticsearch.action.search.TransportClearScrollAction; @@ -118,10 +118,10 @@ public class RBACEngine implements AuthorizationEngine { GetUserPrivilegesAction.NAME, GetApiKeyAction.NAME ); - private static final String INDEX_SUB_REQUEST_PRIMARY = IndexAction.NAME + "[p]"; - private static final String INDEX_SUB_REQUEST_REPLICA = IndexAction.NAME + "[r]"; - private static final String DELETE_SUB_REQUEST_PRIMARY = DeleteAction.NAME + "[p]"; - private static final String DELETE_SUB_REQUEST_REPLICA = DeleteAction.NAME + "[r]"; + private static final String INDEX_SUB_REQUEST_PRIMARY = TransportIndexAction.NAME + "[p]"; + private static final String INDEX_SUB_REQUEST_REPLICA = TransportIndexAction.NAME + "[r]"; + private static final String DELETE_SUB_REQUEST_PRIMARY = TransportDeleteAction.NAME + "[p]"; + private static final String DELETE_SUB_REQUEST_REPLICA = TransportDeleteAction.NAME + "[r]"; private static final Logger logger = LogManager.getLogger(RBACEngine.class); private final Settings settings; @@ -253,13 +253,13 @@ private static boolean shouldAuthorizeIndexActionNameOnly(String action, Transpo switch (action) { case BulkAction.NAME: case SimulateBulkAction.NAME: - case IndexAction.NAME: - case DeleteAction.NAME: + case TransportIndexAction.NAME: + case TransportDeleteAction.NAME: case INDEX_SUB_REQUEST_PRIMARY: case INDEX_SUB_REQUEST_REPLICA: case DELETE_SUB_REQUEST_PRIMARY: case DELETE_SUB_REQUEST_REPLICA: - case MultiGetAction.NAME: + case TransportMultiGetAction.NAME: case MultiTermVectorsAction.NAME: case TransportMultiSearchAction.NAME: case "indices:data/read/mpercolate": diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/profile/ProfileService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/profile/ProfileService.java index d572932670f23..c7965872f8185 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/profile/ProfileService.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/profile/ProfileService.java @@ -20,9 +20,9 @@ import org.elasticsearch.action.bulk.BulkAction; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.TransportBulkAction; -import org.elasticsearch.action.get.GetAction; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.MultiGetItemResponse; +import org.elasticsearch.action.get.TransportGetAction; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.MultiSearchRequest; import org.elasticsearch.action.search.MultiSearchResponse; @@ -31,7 +31,7 @@ import org.elasticsearch.action.search.TransportSearchAction; import org.elasticsearch.action.support.WriteRequest.RefreshPolicy; import org.elasticsearch.action.support.master.AcknowledgedResponse; -import org.elasticsearch.action.update.UpdateAction; +import org.elasticsearch.action.update.TransportUpdateAction; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateRequestBuilder; import org.elasticsearch.action.update.UpdateResponse; @@ -451,20 +451,26 @@ private void getVersionedDocument(String uid, ActionListener final GetRequest getRequest = new GetRequest(SECURITY_PROFILE_ALIAS, uidToDocId(uid)); frozenProfileIndex.checkIndexVersionThenExecute( listener::onFailure, - () -> executeAsyncWithOrigin(client, getActionOrigin(), GetAction.INSTANCE, getRequest, ActionListener.wrap(response -> { - if (false == response.isExists()) { - logger.debug("profile with uid [{}] does not exist", uid); - listener.onResponse(null); - return; - } - listener.onResponse( - new VersionedDocument( - buildProfileDocument(response.getSourceAsBytesRef()), - response.getPrimaryTerm(), - response.getSeqNo() - ) - ); - }, listener::onFailure)) + () -> executeAsyncWithOrigin( + client, + getActionOrigin(), + TransportGetAction.TYPE, + getRequest, + ActionListener.wrap(response -> { + if (false == response.isExists()) { + logger.debug("profile with uid [{}] does not exist", uid); + listener.onResponse(null); + return; + } + listener.onResponse( + new VersionedDocument( + buildProfileDocument(response.getSourceAsBytesRef()), + response.getPrimaryTerm(), + response.getSeqNo() + ) + ); + }, listener::onFailure) + ) ); }); } @@ -943,7 +949,7 @@ void doUpdate(UpdateRequest updateRequest, ActionListener listen () -> executeAsyncWithOrigin( client, getActionOrigin(), - UpdateAction.INSTANCE, + TransportUpdateAction.TYPE, updateRequest, ActionListener.wrap(updateResponse -> { assert updateResponse.getResult() == DocWriteResponse.Result.UPDATED diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/ServerTransportFilter.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/ServerTransportFilter.java index bfd87326d4481..a7a0efbbf4aac 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/ServerTransportFilter.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/ServerTransportFilter.java @@ -11,7 +11,7 @@ import org.elasticsearch.TransportVersion; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.IndicesRequest; -import org.elasticsearch.action.admin.indices.close.CloseIndexAction; +import org.elasticsearch.action.admin.indices.close.TransportCloseIndexAction; import org.elasticsearch.action.admin.indices.delete.DeleteIndexAction; import org.elasticsearch.action.admin.indices.open.OpenIndexAction; import org.elasticsearch.action.support.DestructiveOperations; @@ -67,7 +67,7 @@ class ServerTransportFilter { * be sent back to the sender. */ void inbound(String action, TransportRequest request, TransportChannel transportChannel, ActionListener listener) { - if (CloseIndexAction.NAME.equals(action) || OpenIndexAction.NAME.equals(action) || DeleteIndexAction.NAME.equals(action)) { + if (TransportCloseIndexAction.NAME.equals(action) || OpenIndexAction.NAME.equals(action) || DeleteIndexAction.NAME.equals(action)) { IndicesRequest indicesRequest = (IndicesRequest) request; try { destructiveOperations.failDestructive(indicesRequest.indices()); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilterTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilterTests.java index fc56061a98883..721df8867c96a 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilterTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilterTests.java @@ -12,7 +12,7 @@ import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.MockIndicesRequest; -import org.elasticsearch.action.admin.indices.close.CloseIndexAction; +import org.elasticsearch.action.admin.indices.close.TransportCloseIndexAction; import org.elasticsearch.action.admin.indices.delete.DeleteIndexAction; import org.elasticsearch.action.admin.indices.open.OpenIndexAction; import org.elasticsearch.action.support.ActionFilterChain; @@ -229,7 +229,7 @@ public void testApplyDestructiveOperations() throws Exception { IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean()), randomFrom("*", "_all", "test*") ); - String action = randomFrom(CloseIndexAction.NAME, OpenIndexAction.NAME, DeleteIndexAction.NAME); + String action = randomFrom(TransportCloseIndexAction.NAME, OpenIndexAction.NAME, DeleteIndexAction.NAME); ActionListener listener = mock(ActionListener.class); Task task = mock(Task.class); User user = new User("username", "r1", "r2"); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/oidc/TransportOpenIdConnectLogoutActionTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/oidc/TransportOpenIdConnectLogoutActionTests.java index ac52ef6864f9f..95e818dc20c96 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/oidc/TransportOpenIdConnectLogoutActionTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/oidc/TransportOpenIdConnectLogoutActionTests.java @@ -14,10 +14,10 @@ import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.get.GetRequestBuilder; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.action.update.UpdateRequest; @@ -150,7 +150,7 @@ public void setup() throws Exception { final IndexResponse response = new IndexResponse(new ShardId("test", "test", 0), indexRequest.id(), 1, 1, 1, true); listener.onResponse(response); return Void.TYPE; - }).when(client).execute(eq(IndexAction.INSTANCE), any(IndexRequest.class), anyActionListener()); + }).when(client).execute(eq(TransportIndexAction.TYPE), any(IndexRequest.class), anyActionListener()); doAnswer(invocationOnMock -> { BulkRequest bulkRequest = (BulkRequest) invocationOnMock.getArguments()[0]; @SuppressWarnings("unchecked") diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/saml/TransportSamlInvalidateSessionActionTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/saml/TransportSamlInvalidateSessionActionTests.java index 28f8a77c422f7..eb702ed281014 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/saml/TransportSamlInvalidateSessionActionTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/saml/TransportSamlInvalidateSessionActionTests.java @@ -21,9 +21,9 @@ import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.ClearScrollRequest; import org.elasticsearch.action.search.ClearScrollResponse; import org.elasticsearch.action.search.SearchRequest; @@ -168,7 +168,7 @@ protected void Request request, ActionListener listener ) { - if (IndexAction.NAME.equals(action.name())) { + if (TransportIndexAction.NAME.equals(action.name())) { assertThat(request, instanceOf(IndexRequest.class)); IndexRequest indexRequest = (IndexRequest) request; indexRequests.add(indexRequest); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/saml/TransportSamlLogoutActionTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/saml/TransportSamlLogoutActionTests.java index fb3296d6dec7b..18cb0781b22a5 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/saml/TransportSamlLogoutActionTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/saml/TransportSamlLogoutActionTests.java @@ -17,10 +17,10 @@ import org.elasticsearch.action.get.MultiGetRequest; import org.elasticsearch.action.get.MultiGetRequestBuilder; import org.elasticsearch.action.get.MultiGetResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.action.update.UpdateRequest; @@ -181,7 +181,7 @@ public void setup() throws Exception { final IndexResponse response = new IndexResponse(new ShardId("test", "test", 0), indexRequest.id(), 1, 1, 1, true); listener.onResponse(response); return Void.TYPE; - }).when(client).execute(eq(IndexAction.INSTANCE), any(IndexRequest.class), any(ActionListener.class)); + }).when(client).execute(eq(TransportIndexAction.TYPE), any(IndexRequest.class), any(ActionListener.class)); doAnswer(invocationOnMock -> { BulkRequest bulkRequest = (BulkRequest) invocationOnMock.getArguments()[0]; ActionListener listener = (ActionListener) invocationOnMock.getArguments()[1]; diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/token/TransportCreateTokenActionTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/token/TransportCreateTokenActionTests.java index 08fd03d1ac115..8d85b5eb57797 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/token/TransportCreateTokenActionTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/token/TransportCreateTokenActionTests.java @@ -16,10 +16,10 @@ import org.elasticsearch.action.get.MultiGetRequest; import org.elasticsearch.action.get.MultiGetRequestBuilder; import org.elasticsearch.action.get.MultiGetResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.action.update.UpdateRequestBuilder; @@ -143,7 +143,7 @@ public void setupClient() { ) ); return null; - }).when(client).execute(eq(IndexAction.INSTANCE), any(IndexRequest.class), anyActionListener()); + }).when(client).execute(eq(TransportIndexAction.TYPE), any(IndexRequest.class), anyActionListener()); securityContext = new SecurityContext(Settings.EMPTY, threadPool.getThreadContext()); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/user/HasPrivilegesRequestBuilderTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/user/HasPrivilegesRequestBuilderTests.java index b5d728d4a3c09..86845a2c07a26 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/user/HasPrivilegesRequestBuilderTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/user/HasPrivilegesRequestBuilderTests.java @@ -7,7 +7,7 @@ package org.elasticsearch.xpack.security.action.user; import org.elasticsearch.ElasticsearchParseException; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.admin.cluster.stats.ClusterStatsAction; import org.elasticsearch.client.internal.Client; import org.elasticsearch.common.bytes.BytesArray; @@ -94,14 +94,14 @@ public void testParseValidJsonWithJustIndexPrivileges() throws Exception { public void testParseValidJsonWithJustClusterPrivileges() throws Exception { String json = Strings.format(""" - { "cluster": [ "manage","%s","%s"] }""", ClusterHealthAction.NAME, ClusterStatsAction.NAME); + { "cluster": [ "manage","%s","%s"] }""", TransportClusterHealthAction.NAME, ClusterStatsAction.NAME); final HasPrivilegesRequestBuilder builder = new HasPrivilegesRequestBuilder(mock(Client.class)); builder.source("elastic", new BytesArray(json.getBytes(StandardCharsets.UTF_8)), XContentType.JSON); final HasPrivilegesRequest request = builder.request(); assertThat(request.indexPrivileges().length, equalTo(0)); - assertThat(request.clusterPrivileges(), arrayContaining("manage", ClusterHealthAction.NAME, ClusterStatsAction.NAME)); + assertThat(request.clusterPrivileges(), arrayContaining("manage", TransportClusterHealthAction.NAME, ClusterStatsAction.NAME)); } public void testUseOfFieldLevelSecurityThrowsException() throws Exception { diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationServiceTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationServiceTests.java index e899102b2d363..6fb0d69175307 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationServiceTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationServiceTests.java @@ -18,10 +18,10 @@ import org.elasticsearch.action.get.GetRequestBuilder; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.get.MultiGetRequestBuilder; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.action.update.UpdateRequestBuilder; import org.elasticsearch.client.internal.Client; @@ -300,7 +300,7 @@ public void init() throws Exception { ) ); return null; - }).when(client).execute(eq(IndexAction.INSTANCE), any(IndexRequest.class), anyActionListener()); + }).when(client).execute(eq(TransportIndexAction.TYPE), any(IndexRequest.class), anyActionListener()); doAnswer(invocationOnMock -> { GetRequestBuilder builder = new GetRequestBuilder(client); builder.setIndex((String) invocationOnMock.getArguments()[0]).setId((String) invocationOnMock.getArguments()[1]); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/TokenServiceTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/TokenServiceTests.java index 5ef9749a5cd08..2f646631d14cd 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/TokenServiceTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/TokenServiceTests.java @@ -23,10 +23,10 @@ import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetRequestBuilder; import org.elasticsearch.action.get.GetResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; @@ -185,7 +185,7 @@ public void setupClient() { ) ); return null; - }).when(client).execute(eq(IndexAction.INSTANCE), any(IndexRequest.class), anyActionListener()); + }).when(client).execute(eq(TransportIndexAction.TYPE), any(IndexRequest.class), anyActionListener()); doAnswer(invocationOnMock -> { BulkRequest request = (BulkRequest) invocationOnMock.getArguments()[0]; @SuppressWarnings("unchecked") 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 fa37a2abee77f..71b91619c66b3 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 @@ -7,7 +7,7 @@ package org.elasticsearch.xpack.security.authc.service; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsAction; import org.elasticsearch.action.admin.indices.create.AutoCreateAction; import org.elasticsearch.action.admin.indices.create.CreateIndexAction; @@ -20,10 +20,10 @@ import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesAction; import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateAction; import org.elasticsearch.action.bulk.BulkAction; -import org.elasticsearch.action.delete.DeleteAction; -import org.elasticsearch.action.get.GetAction; -import org.elasticsearch.action.get.MultiGetAction; -import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.delete.TransportDeleteAction; +import org.elasticsearch.action.get.TransportGetAction; +import org.elasticsearch.action.get.TransportMultiGetAction; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.TransportMultiSearchAction; import org.elasticsearch.action.search.TransportSearchAction; import org.elasticsearch.cluster.metadata.IndexAbstraction; @@ -133,13 +133,13 @@ public void testElasticFleetServerPrivileges() { ).stream().map(this::mockIndexAbstraction).forEach(index -> { assertThat(role.indices().allowedIndicesMatcher(AutoPutMappingAction.NAME).test(index), is(true)); assertThat(role.indices().allowedIndicesMatcher(AutoCreateAction.NAME).test(index), is(true)); - assertThat(role.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(index), is(true)); assertThat(role.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(index), is(true)); - assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(index), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(index), is(true)); assertThat(role.indices().allowedIndicesMatcher(BulkAction.NAME).test(index), is(true)); assertThat(role.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(index), is(false)); - assertThat(role.indices().allowedIndicesMatcher(GetAction.NAME).test(index), is(false)); - assertThat(role.indices().allowedIndicesMatcher(MultiGetAction.NAME).test(index), is(false)); + assertThat(role.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(index), is(false)); + assertThat(role.indices().allowedIndicesMatcher(TransportMultiGetAction.NAME).test(index), is(false)); assertThat(role.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(index), is(false)); assertThat(role.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(index), is(false)); assertThat(role.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(index), is(false)); @@ -148,13 +148,13 @@ public void testElasticFleetServerPrivileges() { final IndexAbstraction profilingIndex = mockIndexAbstraction("profiling-" + randomAlphaOfLengthBetween(1, 20)); assertThat(role.indices().allowedIndicesMatcher(AutoPutMappingAction.NAME).test(profilingIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(AutoCreateAction.NAME).test(profilingIndex), is(false)); - assertThat(role.indices().allowedIndicesMatcher(DeleteAction.NAME).test(profilingIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(profilingIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(profilingIndex), is(false)); - assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(profilingIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(profilingIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(BulkAction.NAME).test(profilingIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(profilingIndex), is(false)); - assertThat(role.indices().allowedIndicesMatcher(GetAction.NAME).test(profilingIndex), is(true)); - assertThat(role.indices().allowedIndicesMatcher(MultiGetAction.NAME).test(profilingIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(profilingIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportMultiGetAction.NAME).test(profilingIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(profilingIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(profilingIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(profilingIndex), is(false)); @@ -162,13 +162,13 @@ public void testElasticFleetServerPrivileges() { List.of("synthetics-" + randomAlphaOfLengthBetween(1, 20)).stream().map(this::mockIndexAbstraction).forEach(index -> { assertThat(role.indices().allowedIndicesMatcher(AutoPutMappingAction.NAME).test(index), is(true)); assertThat(role.indices().allowedIndicesMatcher(AutoCreateAction.NAME).test(index), is(true)); - assertThat(role.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(index), is(true)); assertThat(role.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(index), is(true)); - assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(index), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(index), is(true)); assertThat(role.indices().allowedIndicesMatcher(BulkAction.NAME).test(index), is(true)); assertThat(role.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(index), is(false)); - assertThat(role.indices().allowedIndicesMatcher(GetAction.NAME).test(index), is(true)); - assertThat(role.indices().allowedIndicesMatcher(MultiGetAction.NAME).test(index), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(index), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportMultiGetAction.NAME).test(index), is(true)); assertThat(role.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(index), is(true)); assertThat(role.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(index), is(true)); assertThat(role.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(index), is(false)); @@ -186,12 +186,12 @@ public void testElasticFleetServerPrivileges() { ".fleet-fileds" + randomAlphaOfLengthBetween(1, 20) ).forEach(index -> { final IndexAbstraction dotFleetIndex = mockIndexAbstraction(index); - assertThat(role.indices().allowedIndicesMatcher(DeleteAction.NAME).test(dotFleetIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(dotFleetIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(dotFleetIndex), is(true)); - assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(dotFleetIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(dotFleetIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(BulkAction.NAME).test(dotFleetIndex), is(true)); - assertThat(role.indices().allowedIndicesMatcher(GetAction.NAME).test(dotFleetIndex), is(true)); - assertThat(role.indices().allowedIndicesMatcher(MultiGetAction.NAME).test(dotFleetIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(dotFleetIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportMultiGetAction.NAME).test(dotFleetIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(dotFleetIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(dotFleetIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(IndicesStatsAction.NAME).test(dotFleetIndex), is(true)); @@ -201,12 +201,12 @@ public void testElasticFleetServerPrivileges() { }); final IndexAbstraction dotFleetSecretsIndex = mockIndexAbstraction(".fleet-secrets" + randomAlphaOfLengthBetween(1, 20)); - assertThat(role.indices().allowedIndicesMatcher(DeleteAction.NAME).test(dotFleetSecretsIndex), is(false)); + assertThat(role.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(dotFleetSecretsIndex), is(false)); assertThat(role.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(dotFleetSecretsIndex), is(false)); - assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(dotFleetSecretsIndex), is(false)); + assertThat(role.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(dotFleetSecretsIndex), is(false)); assertThat(role.indices().allowedIndicesMatcher(BulkAction.NAME).test(dotFleetSecretsIndex), is(false)); - assertThat(role.indices().allowedIndicesMatcher(GetAction.NAME).test(dotFleetSecretsIndex), is(true)); - assertThat(role.indices().allowedIndicesMatcher(MultiGetAction.NAME).test(dotFleetSecretsIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(dotFleetSecretsIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportMultiGetAction.NAME).test(dotFleetSecretsIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(dotFleetSecretsIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(dotFleetSecretsIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(IndicesStatsAction.NAME).test(dotFleetSecretsIndex), is(false)); @@ -220,12 +220,12 @@ public void testElasticFleetServerPrivileges() { assertThat(role.cluster().check("cluster:admin/fleet/secrets/delete", request, authentication), is(false)); final IndexAbstraction apmSampledTracesIndex = mockIndexAbstraction("traces-apm.sampled-" + randomAlphaOfLengthBetween(1, 20)); - assertThat(role.indices().allowedIndicesMatcher(DeleteAction.NAME).test(apmSampledTracesIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(apmSampledTracesIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(apmSampledTracesIndex), is(true)); - assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(apmSampledTracesIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(apmSampledTracesIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(BulkAction.NAME).test(apmSampledTracesIndex), is(true)); - assertThat(role.indices().allowedIndicesMatcher(GetAction.NAME).test(apmSampledTracesIndex), is(true)); - assertThat(role.indices().allowedIndicesMatcher(MultiGetAction.NAME).test(apmSampledTracesIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(apmSampledTracesIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportMultiGetAction.NAME).test(apmSampledTracesIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(apmSampledTracesIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(apmSampledTracesIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(IndicesStatsAction.NAME).test(apmSampledTracesIndex), is(true)); @@ -338,7 +338,7 @@ public void testElasticEnterpriseSearchServerAccount() { // monitoring assertThat(role.cluster().check(MonitoringBulkAction.NAME, request, authentication), is(true)); - assertThat(role.cluster().check(ClusterHealthAction.NAME, request, authentication), is(true)); + assertThat(role.cluster().check(TransportClusterHealthAction.NAME, request, authentication), is(true)); // manage_ilm assertThat(role.cluster().check(GetLifecycleAction.NAME, request, authentication), is(true)); @@ -366,12 +366,12 @@ public void testElasticEnterpriseSearchServerAccount() { final IndexAbstraction enterpriseSearchIndex = mockIndexAbstraction(index); assertThat(role.indices().allowedIndicesMatcher(AutoCreateAction.NAME).test(enterpriseSearchIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(enterpriseSearchIndex), is(true)); - assertThat(role.indices().allowedIndicesMatcher(DeleteAction.NAME).test(enterpriseSearchIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(enterpriseSearchIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(enterpriseSearchIndex), is(true)); - assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(enterpriseSearchIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(enterpriseSearchIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(BulkAction.NAME).test(enterpriseSearchIndex), is(true)); - assertThat(role.indices().allowedIndicesMatcher(GetAction.NAME).test(enterpriseSearchIndex), is(true)); - assertThat(role.indices().allowedIndicesMatcher(MultiGetAction.NAME).test(enterpriseSearchIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(enterpriseSearchIndex), is(true)); + assertThat(role.indices().allowedIndicesMatcher(TransportMultiGetAction.NAME).test(enterpriseSearchIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(enterpriseSearchIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(TransportMultiSearchAction.TYPE.name()).test(enterpriseSearchIndex), is(true)); assertThat(role.indices().allowedIndicesMatcher(IndicesStatsAction.NAME).test(enterpriseSearchIndex), is(true)); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/AuthorizationServiceTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/AuthorizationServiceTests.java index bf358f03e16a5..f5f700c8dc7c2 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/AuthorizationServiceTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/AuthorizationServiceTests.java @@ -13,12 +13,12 @@ import org.elasticsearch.action.LatchedActionListener; import org.elasticsearch.action.MockIndicesRequest; import org.elasticsearch.action.OriginalIndices; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.admin.indices.alias.Alias; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions; +import org.elasticsearch.action.admin.indices.alias.TransportIndicesAliasesAction; import org.elasticsearch.action.admin.indices.create.CreateIndexAction; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.delete.DeleteIndexAction; @@ -48,14 +48,14 @@ import org.elasticsearch.action.bulk.BulkShardResponse; import org.elasticsearch.action.bulk.MappingUpdatePerformer; import org.elasticsearch.action.bulk.TransportShardBulkAction; -import org.elasticsearch.action.delete.DeleteAction; import org.elasticsearch.action.delete.DeleteRequest; -import org.elasticsearch.action.get.GetAction; +import org.elasticsearch.action.delete.TransportDeleteAction; import org.elasticsearch.action.get.GetRequest; -import org.elasticsearch.action.get.MultiGetAction; import org.elasticsearch.action.get.MultiGetRequest; -import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.get.TransportGetAction; +import org.elasticsearch.action.get.TransportMultiGetAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.ClearScrollRequest; import org.elasticsearch.action.search.ClosePointInTimeRequest; import org.elasticsearch.action.search.MultiSearchRequest; @@ -79,7 +79,7 @@ import org.elasticsearch.action.termvectors.MultiTermVectorsRequest; import org.elasticsearch.action.termvectors.TermVectorsAction; import org.elasticsearch.action.termvectors.TermVectorsRequest; -import org.elasticsearch.action.update.UpdateAction; +import org.elasticsearch.action.update.TransportUpdateAction; import org.elasticsearch.action.update.UpdateHelper; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.cluster.ClusterState; @@ -1355,7 +1355,7 @@ public void testCreateIndexWithAliasWithoutPermissions() { assertThrowsAuthorizationException( () -> authorize(authentication, CreateIndexAction.NAME, request), - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, "test user" ); verify(auditTrail).accessGranted( @@ -1368,7 +1368,7 @@ public void testCreateIndexWithAliasWithoutPermissions() { verify(auditTrail).accessDenied( eq(requestId), eq(authentication), - eq(IndicesAliasesAction.NAME), + eq(TransportIndicesAliasesAction.NAME), eq(request), authzInfoRoles(new String[] { role.getName() }) ); @@ -1539,11 +1539,13 @@ public void testDenialErrorMessagesForClusterHealthAction() { ElasticsearchSecurityException securityException = expectThrows( ElasticsearchSecurityException.class, - () -> authorize(authentication, ClusterHealthAction.NAME, request) + () -> authorize(authentication, TransportClusterHealthAction.NAME, request) ); assertThat( securityException, - throwableWithMessage(containsString("[" + ClusterHealthAction.NAME + "] is unauthorized for user [" + user.principal() + "]")) + throwableWithMessage( + containsString("[" + TransportClusterHealthAction.NAME + "] is unauthorized for user [" + user.principal() + "]") + ) ); assertThat( securityException, @@ -1977,7 +1979,10 @@ public void testGrantAllRestrictedUserCannotExecuteOperationAgainstSecurityIndic new Tuple<>(BulkAction.NAME + "[s]", new DeleteRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "id")) ); requests.add( - new Tuple<>(UpdateAction.NAME, new UpdateRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "id")) + new Tuple<>( + TransportUpdateAction.NAME, + new UpdateRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "id") + ) ); requests.add( new Tuple<>(BulkAction.NAME + "[s]", new IndexRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7))) @@ -1994,10 +1999,15 @@ public void testGrantAllRestrictedUserCannotExecuteOperationAgainstSecurityIndic new TermVectorsRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "id") ) ); - requests.add(new Tuple<>(GetAction.NAME, new GetRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "id"))); requests.add( new Tuple<>( - IndicesAliasesAction.NAME, + TransportGetAction.TYPE.name(), + new GetRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "id") + ) + ); + requests.add( + new Tuple<>( + TransportIndicesAliasesAction.NAME, new IndicesAliasesRequest().addAliasAction(AliasActions.add().alias("security_alias").index(INTERNAL_SECURITY_MAIN_INDEX_7)) ) ); @@ -2052,22 +2062,22 @@ public void testGrantAllRestrictedUserCannotExecuteOperationAgainstSecurityIndic // we should allow waiting for the health of the index or any index if the user has this permission ClusterHealthRequest request = new ClusterHealthRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7)); - authorize(authentication, ClusterHealthAction.NAME, request); + authorize(authentication, TransportClusterHealthAction.NAME, request); verify(auditTrail).accessGranted( eq(requestId), eq(authentication), - eq(ClusterHealthAction.NAME), + eq(TransportClusterHealthAction.NAME), eq(request), authzInfoRoles(new String[] { role.getName() }) ); // multiple indices request = new ClusterHealthRequest(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7, "foo", "bar"); - authorize(authentication, ClusterHealthAction.NAME, request); + authorize(authentication, TransportClusterHealthAction.NAME, request); verify(auditTrail).accessGranted( eq(requestId), eq(authentication), - eq(ClusterHealthAction.NAME), + eq(TransportClusterHealthAction.NAME), eq(request), authzInfoRoles(new String[] { role.getName() }) ); @@ -2180,13 +2190,21 @@ public void testSuperusersCanExecuteReadOperationAgainstSecurityIndex() { new TermVectorsRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "id") ) ); - requests.add(new Tuple<>(GetAction.NAME, new GetRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "id"))); requests.add( - new Tuple<>(ClusterHealthAction.NAME, new ClusterHealthRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7))) + new Tuple<>( + TransportGetAction.TYPE.name(), + new GetRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "id") + ) + ); + requests.add( + new Tuple<>( + TransportClusterHealthAction.NAME, + new ClusterHealthRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7)) + ) ); requests.add( new Tuple<>( - ClusterHealthAction.NAME, + TransportClusterHealthAction.NAME, new ClusterHealthRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "foo", "bar") ) ); @@ -2251,7 +2269,7 @@ public void testSuperusersCannotExecuteWriteOperationAgainstSecurityIndex() { ); requests.add( new Tuple<>( - IndicesAliasesAction.NAME, + TransportIndicesAliasesAction.NAME, new IndicesAliasesRequest().addAliasAction(AliasActions.add().alias("security_alias").index(INTERNAL_SECURITY_MAIN_INDEX_7)) ) ); @@ -2384,7 +2402,7 @@ public void testCompositeActionsIndicesAreCheckedAtTheShardLevel() { final String action; switch (randomIntBetween(0, 4)) { case 0 -> { - action = MultiGetAction.NAME + "[shard]"; + action = TransportMultiGetAction.NAME + "[shard]"; request = mockRequest; } case 1 -> { @@ -2625,10 +2643,10 @@ public void testAuthorizationOfSingleActionMultipleIndicesBulkItems() { ); // there's only one "access granted" record for all the bulk items verify(auditTrail).explicitIndexAccessEvent(eq(requestId), eq(AuditLevel.ACCESS_GRANTED), eq(authentication), eq(switch (opType) { - case INDEX -> IndexAction.NAME + ":op_type/index"; - case CREATE -> IndexAction.NAME + ":op_type/create"; - case UPDATE -> UpdateAction.NAME; - case DELETE -> DeleteAction.NAME; + case INDEX -> TransportIndexAction.NAME + ":op_type/index"; + case CREATE -> TransportIndexAction.NAME + ":op_type/create"; + case UPDATE -> TransportUpdateAction.NAME; + case DELETE -> TransportDeleteAction.NAME; }), argThat( indicesArrays -> indicesArrays.length == allIndexNames.size() && allIndexNames.containsAll(Arrays.asList(indicesArrays)) @@ -2665,10 +2683,10 @@ public void testAuthorizationOfSingleActionMultipleIndicesBulkItems() { eq(AuditLevel.ACCESS_DENIED), eq(badAuthentication), eq(switch (opType) { - case INDEX -> IndexAction.NAME + ":op_type/index"; - case CREATE -> IndexAction.NAME + ":op_type/create"; - case UPDATE -> UpdateAction.NAME; - case DELETE -> DeleteAction.NAME; + case INDEX -> TransportIndexAction.NAME + ":op_type/index"; + case CREATE -> TransportIndexAction.NAME + ":op_type/create"; + case UPDATE -> TransportUpdateAction.NAME; + case DELETE -> TransportDeleteAction.NAME; }), argThat( indicesArrays -> indicesArrays.length == allIndexNames.size() && allIndexNames.containsAll(Arrays.asList(indicesArrays)) @@ -2693,26 +2711,26 @@ public void testAuthorizationOfMultipleActionsSingleIndexBulkItems() { final BulkItemRequest[] items = randomArray(1, 8, BulkItemRequest[]::new, () -> { switch (randomFrom(DocWriteRequest.OpType.values())) { case INDEX -> { - actionTypes.add(IndexAction.NAME + ":op_type/index"); + actionTypes.add(TransportIndexAction.NAME + ":op_type/index"); return new BulkItemRequest( idCounter.get(), new IndexRequest(indexName).id("id" + idCounter.incrementAndGet()).opType(DocWriteRequest.OpType.INDEX) ); } case CREATE -> { - actionTypes.add(IndexAction.NAME + ":op_type/create"); + actionTypes.add(TransportIndexAction.NAME + ":op_type/create"); return new BulkItemRequest( idCounter.get(), new IndexRequest(indexName).id("id" + idCounter.incrementAndGet()).opType(DocWriteRequest.OpType.CREATE) ); } case DELETE -> { - actionTypes.add(DeleteAction.NAME); + actionTypes.add(TransportDeleteAction.NAME); deleteItems.add(idCounter.get()); return new BulkItemRequest(idCounter.get(), new DeleteRequest(indexName, "id" + idCounter.incrementAndGet())); } case UPDATE -> { - actionTypes.add(UpdateAction.NAME); + actionTypes.add(TransportUpdateAction.NAME); return new BulkItemRequest(idCounter.get(), new UpdateRequest(indexName, "id" + idCounter.incrementAndGet())); } default -> throw new IllegalStateException("Unexpected value"); @@ -2789,7 +2807,7 @@ public void testAuthorizationOfMultipleActionsSingleIndexBulkItems() { ); // there's a single granted audit entry for each action type, less the delete action (which is denied) actionTypes.forEach(actionType -> { - if (actionType.equals(DeleteAction.NAME) == false) { + if (actionType.equals(TransportDeleteAction.NAME) == false) { verify(auditTrail).explicitIndexAccessEvent( eq(indexRequestId), eq(AuditLevel.ACCESS_GRANTED), @@ -2808,7 +2826,7 @@ public void testAuthorizationOfMultipleActionsSingleIndexBulkItems() { eq(indexRequestId), eq(AuditLevel.ACCESS_DENIED), eq(indexAuthentication), - eq(DeleteAction.NAME), + eq(TransportDeleteAction.NAME), eq(new String[] { indexName }), eq(BulkItemRequest.class.getSimpleName()), eq(request.remoteAddress()), @@ -2857,7 +2875,7 @@ public void testAuthorizationOfIndividualIndexAndDeleteBulkItems() { eq(requestId), eq(AuditLevel.ACCESS_GRANTED), eq(authentication), - eq(DeleteAction.NAME), + eq(TransportDeleteAction.NAME), argThat(indicesArrays -> { Arrays.sort(indicesArrays); return Arrays.equals(indicesArrays, new String[] { "alias-2", "concrete-index" }); @@ -2870,7 +2888,7 @@ public void testAuthorizationOfIndividualIndexAndDeleteBulkItems() { eq(requestId), eq(AuditLevel.ACCESS_GRANTED), eq(authentication), - eq(IndexAction.NAME + ":op_type/index"), + eq(TransportIndexAction.NAME + ":op_type/index"), argThat(indicesArrays -> { Arrays.sort(indicesArrays); return Arrays.equals(indicesArrays, new String[] { "alias-1", "concrete-index" }); @@ -2883,7 +2901,7 @@ public void testAuthorizationOfIndividualIndexAndDeleteBulkItems() { eq(requestId), eq(AuditLevel.ACCESS_DENIED), eq(authentication), - eq(DeleteAction.NAME), + eq(TransportDeleteAction.NAME), eq(new String[] { "alias-1" }), eq(BulkItemRequest.class.getSimpleName()), eq(request.remoteAddress()), @@ -2893,7 +2911,7 @@ public void testAuthorizationOfIndividualIndexAndDeleteBulkItems() { eq(requestId), eq(AuditLevel.ACCESS_DENIED), eq(authentication), - eq(IndexAction.NAME + ":op_type/index"), + eq(TransportIndexAction.NAME + ":op_type/index"), eq(new String[] { "alias-2" }), eq(BulkItemRequest.class.getSimpleName()), eq(request.remoteAddress()), @@ -2944,7 +2962,7 @@ public void testAuthorizationOfIndividualBulkItemsWithDateMath() { eq(requestId), eq(AuditLevel.ACCESS_DENIED), eq(authentication), - eq(DeleteAction.NAME), + eq(TransportDeleteAction.NAME), argThat(indices -> indices.length == 2 && indices[0].startsWith("datemath-") && indices[1].startsWith("datemath-")), eq(BulkItemRequest.class.getSimpleName()), eq(request.remoteAddress()), @@ -2955,7 +2973,7 @@ public void testAuthorizationOfIndividualBulkItemsWithDateMath() { eq(requestId), eq(AuditLevel.ACCESS_GRANTED), eq(authentication), - eq(IndexAction.NAME + ":op_type/index"), + eq(TransportIndexAction.NAME + ":op_type/index"), argThat(indices -> indices.length == 2 && indices[0].startsWith("datemath-") && indices[1].startsWith("datemath-")), eq(BulkItemRequest.class.getSimpleName()), eq(request.remoteAddress()), @@ -2983,7 +3001,7 @@ private BulkShardRequest createBulkShardRequest(String indexName, BiFunction randomCompositeRequest() { return switch (randomIntBetween(0, 7)) { - case 0 -> Tuple.tuple(MultiGetAction.NAME, new MultiGetRequest().add("index", "id")); + case 0 -> Tuple.tuple(TransportMultiGetAction.NAME, new MultiGetRequest().add("index", "id")); case 1 -> Tuple.tuple(TransportMultiSearchAction.TYPE.name(), new MultiSearchRequest().add(new SearchRequest())); case 2 -> Tuple.tuple(MultiTermVectorsAction.NAME, new MultiTermVectorsRequest().add("index", "id")); case 3 -> Tuple.tuple(BulkAction.NAME, new BulkRequest().add(new DeleteRequest("index", "id"))); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/IndicesAndAliasesResolverTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/IndicesAndAliasesResolverTests.java index 0709e775776f1..7defd0f11bfac 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/IndicesAndAliasesResolverTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/IndicesAndAliasesResolverTests.java @@ -8,21 +8,21 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.IndicesRequest; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions; +import org.elasticsearch.action.admin.indices.alias.TransportIndicesAliasesAction; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesAction; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; -import org.elasticsearch.action.admin.indices.close.CloseIndexAction; import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; +import org.elasticsearch.action.admin.indices.close.TransportCloseIndexAction; import org.elasticsearch.action.admin.indices.delete.DeleteIndexAction; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingAction; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.bulk.BulkRequest; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest; +import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; import org.elasticsearch.action.get.MultiGetRequest; import org.elasticsearch.action.search.MultiSearchRequest; import org.elasticsearch.action.search.SearchRequest; @@ -838,7 +838,7 @@ public void testResolveIndicesAliasesRequest() { IndicesAliasesRequest request = new IndicesAliasesRequest(); request.addAliasAction(AliasActions.add().alias("alias1").indices("foo", "foofoo")); request.addAliasAction(AliasActions.add().alias("alias2").indices("foo", "foobar")); - List indices = resolveIndices(request, buildAuthorizedIndices(user, IndicesAliasesAction.NAME)).getLocal(); + List indices = resolveIndices(request, buildAuthorizedIndices(user, TransportIndicesAliasesAction.NAME)).getLocal(); // the union of all indices and aliases gets returned String[] expectedIndices = new String[] { "alias1", "alias2", "foo", "foofoo", "foobar" }; assertSameValues(indices, expectedIndices); @@ -852,7 +852,7 @@ public void testResolveIndicesAliasesRequestExistingAlias() { IndicesAliasesRequest request = new IndicesAliasesRequest(); request.addAliasAction(AliasActions.add().alias("alias1").indices("foo", "foofoo")); request.addAliasAction(AliasActions.add().alias("foofoobar").indices("foo", "foobar")); - List indices = resolveIndices(request, buildAuthorizedIndices(user, IndicesAliasesAction.NAME)).getLocal(); + List indices = resolveIndices(request, buildAuthorizedIndices(user, TransportIndicesAliasesAction.NAME)).getLocal(); // the union of all indices and aliases gets returned, foofoobar is an existing alias but that doesn't make any difference String[] expectedIndices = new String[] { "alias1", "foofoobar", "foo", "foofoo", "foobar" }; assertSameValues(indices, expectedIndices); @@ -866,7 +866,7 @@ public void testResolveIndicesAliasesRequestMissingIndex() { IndicesAliasesRequest request = new IndicesAliasesRequest(); request.addAliasAction(AliasActions.add().alias("alias1").indices("foo", "foofoo")); request.addAliasAction(AliasActions.add().alias("alias2").index("missing")); - List indices = resolveIndices(request, buildAuthorizedIndices(user, IndicesAliasesAction.NAME)).getLocal(); + List indices = resolveIndices(request, buildAuthorizedIndices(user, TransportIndicesAliasesAction.NAME)).getLocal(); // the union of all indices and aliases gets returned, missing is not an existing index/alias but that doesn't make any difference String[] expectedIndices = new String[] { "alias1", "alias2", "foo", "foofoo", "missing" }; assertThat(indices, hasSize(expectedIndices.length)); @@ -881,7 +881,7 @@ public void testResolveWildcardsIndicesAliasesRequest() { IndicesAliasesRequest request = new IndicesAliasesRequest(); request.addAliasAction(AliasActions.add().alias("foo-alias").index("foo*")); request.addAliasAction(AliasActions.add().alias("alias2").index("bar*")); - List indices = resolveIndices(request, buildAuthorizedIndices(user, IndicesAliasesAction.NAME)).getLocal(); + List indices = resolveIndices(request, buildAuthorizedIndices(user, TransportIndicesAliasesAction.NAME)).getLocal(); // the union of all resolved indices and aliases gets returned, based on indices and aliases that user is authorized for String[] expectedIndices = new String[] { "foo-alias", "alias2", "foofoo", "bar" }; assertThat(indices, hasSize(expectedIndices.length)); @@ -899,14 +899,17 @@ public void testResolveWildcardsIndicesAliasesRequestNoMatchingIndices() { request.addAliasAction(AliasActions.add().alias("alias2").index("bar*")); request.addAliasAction(AliasActions.add().alias("alias3").index("non_matching_*")); // if a single operation contains wildcards and ends up being resolved to no indices, it makes the whole request fail - expectThrows(IndexNotFoundException.class, () -> resolveIndices(request, buildAuthorizedIndices(user, IndicesAliasesAction.NAME))); + expectThrows( + IndexNotFoundException.class, + () -> resolveIndices(request, buildAuthorizedIndices(user, TransportIndicesAliasesAction.NAME)) + ); } public void testResolveAllIndicesAliasesRequest() { IndicesAliasesRequest request = new IndicesAliasesRequest(); request.addAliasAction(AliasActions.add().alias("alias1").index("_all")); request.addAliasAction(AliasActions.add().alias("alias2").index("_all")); - List indices = resolveIndices(request, buildAuthorizedIndices(user, IndicesAliasesAction.NAME)).getLocal(); + List indices = resolveIndices(request, buildAuthorizedIndices(user, TransportIndicesAliasesAction.NAME)).getLocal(); // the union of all resolved indices and aliases gets returned String[] expectedIndices = new String[] { "bar", "foofoo", "alias1", "alias2" }; assertSameValues(indices, expectedIndices); @@ -924,7 +927,7 @@ public void testResolveAllIndicesAliasesRequestNoAuthorizedIndices() { // current user is not authorized for any index, _all resolves to no indices, the request fails expectThrows( IndexNotFoundException.class, - () -> resolveIndices(request, buildAuthorizedIndices(userNoIndices, IndicesAliasesAction.NAME)) + () -> resolveIndices(request, buildAuthorizedIndices(userNoIndices, TransportIndicesAliasesAction.NAME)) ); } @@ -934,7 +937,7 @@ public void testResolveWildcardsIndicesAliasesRequestNoAuthorizedIndices() { // current user is not authorized for any index, foo* resolves to no indices, the request fails expectThrows( IndexNotFoundException.class, - () -> resolveIndices(request, buildAuthorizedIndices(userNoIndices, IndicesAliasesAction.NAME)) + () -> resolveIndices(request, buildAuthorizedIndices(userNoIndices, TransportIndicesAliasesAction.NAME)) ); } @@ -942,7 +945,7 @@ public void testResolveIndicesAliasesRequestDeleteActions() { IndicesAliasesRequest request = new IndicesAliasesRequest(); request.addAliasAction(AliasActions.remove().index("foo").alias("foofoobar")); request.addAliasAction(AliasActions.remove().index("foofoo").alias("barbaz")); - final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(user, IndicesAliasesAction.NAME); + final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(user, TransportIndicesAliasesAction.NAME); List indices = resolveIndices(request, authorizedIndices).getLocal(); // the union of all indices and aliases gets returned String[] expectedIndices = new String[] { "foo", "foofoobar", "foofoo", "barbaz" }; @@ -958,7 +961,7 @@ public void testResolveIndicesAliasesRequestDeleteActionsMissingIndex() { IndicesAliasesRequest request = new IndicesAliasesRequest(); request.addAliasAction(AliasActions.remove().index("foo").alias("foofoobar")); request.addAliasAction(AliasActions.remove().index("missing_index").alias("missing_alias")); - final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(user, IndicesAliasesAction.NAME); + final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(user, TransportIndicesAliasesAction.NAME); List indices = resolveIndices(request, authorizedIndices).getLocal(); // the union of all indices and aliases gets returned, doesn't matter is some of them don't exist String[] expectedIndices = new String[] { "foo", "foofoobar", "missing_index", "missing_alias" }; @@ -974,7 +977,7 @@ public void testResolveWildcardsIndicesAliasesRequestDeleteActions() { IndicesAliasesRequest request = new IndicesAliasesRequest(); request.addAliasAction(AliasActions.remove().index("foo*").alias("foofoobar")); request.addAliasAction(AliasActions.remove().index("bar*").alias("barbaz")); - final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(user, IndicesAliasesAction.NAME); + final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(user, TransportIndicesAliasesAction.NAME); List indices = resolveIndices(request, authorizedIndices).getLocal(); // union of all resolved indices and aliases gets returned, based on what user is authorized for String[] expectedIndices = new String[] { "foofoobar", "foofoo", "bar", "barbaz" }; @@ -991,7 +994,7 @@ public void testResolveAliasesWildcardsIndicesAliasesRequestDeleteActions() { IndicesAliasesRequest request = new IndicesAliasesRequest(); request.addAliasAction(AliasActions.remove().index("*").alias("foo*")); request.addAliasAction(AliasActions.remove().index("*bar").alias("foo*")); - final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(user, IndicesAliasesAction.NAME); + final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(user, TransportIndicesAliasesAction.NAME); List indices = resolveIndices(request, authorizedIndices).getLocal(); // union of all resolved indices and aliases gets returned, based on what user is authorized for // note that the index side will end up containing matching aliases too, which is fine, as es core would do @@ -1009,7 +1012,7 @@ public void testResolveAllAliasesWildcardsIndicesAliasesRequestDeleteActions() { IndicesAliasesRequest request = new IndicesAliasesRequest(); request.addAliasAction(AliasActions.remove().index("*").alias("_all")); request.addAliasAction(AliasActions.remove().index("_all").aliases("_all", "explicit")); - final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(user, IndicesAliasesAction.NAME); + final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(user, TransportIndicesAliasesAction.NAME); List indices = resolveIndices(request, authorizedIndices).getLocal(); // union of all resolved indices and aliases gets returned, based on what user is authorized for // note that the index side will end up containing matching aliases too, which is fine, as es core would do @@ -1027,7 +1030,7 @@ public void testResolveAliasesWildcardsIndicesAliasesRequestRemoveAliasActionsNo IndicesAliasesRequest request = new IndicesAliasesRequest(); request.addAliasAction(AliasActions.remove().index("foo*").alias("foo*")); request.addAliasAction(AliasActions.remove().index("*bar").alias("bar*")); - resolveIndices(request, buildAuthorizedIndices(user, IndicesAliasesAction.NAME)); + resolveIndices(request, buildAuthorizedIndices(user, TransportIndicesAliasesAction.NAME)); assertThat(request.getAliasActions().get(0).aliases(), arrayContainingInAnyOrder("foofoobar", "foobarfoo")); assertThat(request.getAliasActions().get(1).aliases(), arrayContaining("*", "-*")); } @@ -1036,7 +1039,7 @@ public void testResolveAliasesWildcardsIndicesAliasesRequestRemoveIndexActions() IndicesAliasesRequest request = new IndicesAliasesRequest(); request.addAliasAction(AliasActions.removeIndex().index("foo*")); request.addAliasAction(AliasActions.removeIndex().index("*bar")); - resolveIndices(request, buildAuthorizedIndices(user, IndicesAliasesAction.NAME)); + resolveIndices(request, buildAuthorizedIndices(user, TransportIndicesAliasesAction.NAME)); assertThat(request.getAliasActions().get(0).indices(), arrayContainingInAnyOrder("foofoo")); assertThat(request.getAliasActions().get(0).aliases(), emptyArray()); assertThat(request.getAliasActions().get(1).indices(), arrayContainingInAnyOrder("bar")); @@ -1047,7 +1050,7 @@ public void testResolveWildcardsIndicesAliasesRequestAddAndDeleteActions() { IndicesAliasesRequest request = new IndicesAliasesRequest(); request.addAliasAction(AliasActions.remove().index("foo*").alias("foofoobar")); request.addAliasAction(AliasActions.add().index("bar*").alias("foofoobar")); - final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(user, IndicesAliasesAction.NAME); + final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(user, TransportIndicesAliasesAction.NAME); List indices = resolveIndices(request, authorizedIndices).getLocal(); // union of all resolved indices and aliases gets returned, based on what user is authorized for String[] expectedIndices = new String[] { "foofoobar", "foofoo", "bar" }; @@ -1514,7 +1517,7 @@ public void testRemotableRequestsAllowRemoteIndices() { new Tuple(new SearchRequest("remote:foo").indicesOptions(options), TransportSearchAction.TYPE.name()), new Tuple( new FieldCapabilitiesRequest().indices("remote:foo").indicesOptions(options), - FieldCapabilitiesAction.NAME + TransportFieldCapabilitiesAction.NAME ), new Tuple( new GraphExploreRequest().indices("remote:foo").indicesOptions(options), @@ -1534,7 +1537,10 @@ public void testRemotableRequestsAllowRemoteIndices() { public void testNonRemotableRequestDoesNotAllowRemoteIndices() { IndicesOptions options = IndicesOptions.fromOptions(true, false, false, false); Tuple tuple = randomFrom( - new Tuple(new CloseIndexRequest("remote:foo").indicesOptions(options), CloseIndexAction.NAME), + new Tuple( + new CloseIndexRequest("remote:foo").indicesOptions(options), + TransportCloseIndexAction.NAME + ), new Tuple(new DeleteIndexRequest("remote:foo").indicesOptions(options), DeleteIndexAction.NAME), new Tuple(new PutMappingRequest("remote:foo").indicesOptions(options), PutMappingAction.NAME) ); @@ -1548,7 +1554,7 @@ public void testNonRemotableRequestDoesNotAllowRemoteIndices() { public void testNonRemotableRequestDoesNotAllowRemoteWildcardIndices() { IndicesOptions options = IndicesOptions.fromOptions(randomBoolean(), true, true, true); Tuple tuple = randomFrom( - new Tuple(new CloseIndexRequest("*:*").indicesOptions(options), CloseIndexAction.NAME), + new Tuple(new CloseIndexRequest("*:*").indicesOptions(options), TransportCloseIndexAction.NAME), new Tuple(new DeleteIndexRequest("*:*").indicesOptions(options), DeleteIndexAction.NAME), new Tuple(new PutMappingRequest("*:*").indicesOptions(options), PutMappingAction.NAME) ); @@ -1604,7 +1610,7 @@ public void testXPackSecurityUserHasAccessToSecurityIndex() { aliasesRequest.addAliasAction(AliasActions.add().alias("security_alias").index(SECURITY_MAIN_ALIAS)); final AuthorizedIndices authorizedIndices = buildAuthorizedIndices( InternalUsers.XPACK_SECURITY_USER, - IndicesAliasesAction.NAME + TransportIndicesAliasesAction.NAME ); List indices = resolveIndices(aliasesRequest, authorizedIndices).getLocal(); assertThat(indices, hasItem(SECURITY_MAIN_ALIAS)); @@ -1640,7 +1646,7 @@ public void testNonXPackUserAccessingSecurityIndex() { { IndicesAliasesRequest aliasesRequest = new IndicesAliasesRequest(); aliasesRequest.addAliasAction(AliasActions.add().alias("security_alias1").index("*")); - final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(allAccessUser, IndicesAliasesAction.NAME); + final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(allAccessUser, TransportIndicesAliasesAction.NAME); List indices = resolveIndices(aliasesRequest, authorizedIndices).getLocal(); assertThat(indices, not(hasItem(SECURITY_MAIN_ALIAS))); } diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/RBACEngineTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/RBACEngineTests.java index 251b692f42827..3540f0bd6a753 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/RBACEngineTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/RBACEngineTests.java @@ -9,13 +9,13 @@ import org.elasticsearch.ElasticsearchRoleRestrictionException; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; +import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.admin.cluster.state.ClusterStateAction; import org.elasticsearch.action.admin.cluster.stats.ClusterStatsAction; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingAction; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; -import org.elasticsearch.action.delete.DeleteAction; -import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.delete.TransportDeleteAction; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.TransportSearchAction; import org.elasticsearch.action.support.PlainActionFuture; @@ -312,7 +312,7 @@ public void testSameUserPermissionDoesNotAllowOtherActions() { final String action = randomFrom( PutUserAction.NAME, DeleteUserAction.NAME, - ClusterHealthAction.NAME, + TransportClusterHealthAction.NAME, ClusterStateAction.NAME, ClusterStatsAction.NAME, GetLicenseAction.NAME @@ -473,7 +473,7 @@ public void testSameUserPermissionForCrossClusterAccess() { /** * This tests that action names in the request are considered "matched" by the relevant named privilege - * (in this case that {@link DeleteAction} and {@link IndexAction} are satisfied by {@link IndexPrivilege#WRITE}). + * (in this case that {@link TransportDeleteAction} and {@link TransportIndexAction} are satisfied by {@link IndexPrivilege#WRITE}). */ public void testNamedIndexPrivilegesMatchApplicableActions() throws Exception { Role role = Role.builder(RESTRICTED_INDICES, "test1") @@ -483,24 +483,24 @@ public void testNamedIndexPrivilegesMatchApplicableActions() throws Exception { RBACAuthorizationInfo authzInfo = new RBACAuthorizationInfo(role, null); final PrivilegesCheckResult result = hasPrivileges( - IndicesPrivileges.builder().indices("academy").privileges(DeleteAction.NAME, IndexAction.NAME).build(), + IndicesPrivileges.builder().indices("academy").privileges(TransportDeleteAction.NAME, TransportIndexAction.NAME).build(), authzInfo, List.of(), - new String[] { ClusterHealthAction.NAME } + new String[] { TransportClusterHealthAction.NAME } ); assertThat(result, notNullValue()); assertThat(result.allChecksSuccess(), is(true)); assertThat(result.getDetails().cluster(), aMapWithSize(1)); - assertThat(result.getDetails().cluster().get(ClusterHealthAction.NAME), equalTo(true)); + assertThat(result.getDetails().cluster().get(TransportClusterHealthAction.NAME), equalTo(true)); assertThat(result.getDetails().index().values(), Matchers.iterableWithSize(1)); final ResourcePrivileges resourcePrivileges = result.getDetails().index().values().iterator().next(); assertThat(resourcePrivileges.getResource(), equalTo("academy")); assertThat(resourcePrivileges.getPrivileges(), aMapWithSize(2)); - assertThat(resourcePrivileges.getPrivileges().get(DeleteAction.NAME), equalTo(true)); - assertThat(resourcePrivileges.getPrivileges().get(IndexAction.NAME), equalTo(true)); + assertThat(resourcePrivileges.getPrivileges().get(TransportDeleteAction.NAME), equalTo(true)); + assertThat(resourcePrivileges.getPrivileges().get(TransportIndexAction.NAME), equalTo(true)); } /** diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/interceptor/IndicesAliasesRequestInterceptorTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/interceptor/IndicesAliasesRequestInterceptorTests.java index 9c3426d48c003..15b187edd1cea 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/interceptor/IndicesAliasesRequestInterceptorTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/interceptor/IndicesAliasesRequestInterceptorTests.java @@ -8,8 +8,8 @@ import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.TransportIndicesAliasesAction; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; @@ -77,7 +77,7 @@ public void testInterceptorThrowsWhenFLSDLSEnabled() { } else { queries = null; } - final String action = IndicesAliasesAction.NAME; + final String action = TransportIndicesAliasesAction.NAME; IndicesAccessControl accessControl = new IndicesAccessControl( true, Collections.singletonMap( @@ -133,7 +133,7 @@ public void testInterceptorThrowsWhenTargetHasGreaterPermissions() throws Except .user(new User("john", "role")) .realmRef(new RealmRef("look_name", "look_type", "node")) .build(); - final String action = IndicesAliasesAction.NAME; + final String action = TransportIndicesAliasesAction.NAME; IndicesAccessControl accessControl = new IndicesAccessControl(true, Collections.emptyMap()); new SecurityContext(Settings.EMPTY, threadContext).putIndicesAccessControl(accessControl); IndicesAliasesRequestInterceptor interceptor = new IndicesAliasesRequestInterceptor(threadContext, licenseState, auditTrailService); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/permission/PermissionTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/permission/PermissionTests.java index 1decbf2746ebf..c52409d6e6797 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/permission/PermissionTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/permission/PermissionTests.java @@ -8,7 +8,7 @@ import org.elasticsearch.action.admin.indices.mapping.put.AutoPutMappingAction; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingAction; -import org.elasticsearch.action.get.GetAction; +import org.elasticsearch.action.get.TransportGetAction; import org.elasticsearch.cluster.metadata.DataStreamTestHelper; import org.elasticsearch.cluster.metadata.IndexAbstraction; import org.elasticsearch.common.UUIDs; @@ -46,7 +46,7 @@ public void init() { } public void testAllowedIndicesMatcherAction() throws Exception { - testAllowedIndicesMatcher(permission.indices().allowedIndicesMatcher(GetAction.NAME)); + testAllowedIndicesMatcher(permission.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name())); } public void testAllowedIndicesMatcherForMappingUpdates() throws Exception { @@ -71,8 +71,8 @@ public void testAllowedIndicesMatcherForMappingUpdates() throws Exception { } public void testAllowedIndicesMatcherActionCaching() throws Exception { - IsResourceAuthorizedPredicate matcher1 = permission.indices().allowedIndicesMatcher(GetAction.NAME); - IsResourceAuthorizedPredicate matcher2 = permission.indices().allowedIndicesMatcher(GetAction.NAME); + IsResourceAuthorizedPredicate matcher1 = permission.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()); + IsResourceAuthorizedPredicate matcher2 = permission.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()); assertThat(matcher1, is(matcher2)); } diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java index 7bf9508ab451a..c0df3a0947c71 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java @@ -18,9 +18,9 @@ import org.elasticsearch.action.admin.cluster.state.ClusterStateAction; import org.elasticsearch.action.admin.cluster.stats.ClusterStatsAction; import org.elasticsearch.action.admin.indices.create.CreateIndexAction; -import org.elasticsearch.action.delete.DeleteAction; -import org.elasticsearch.action.get.GetAction; -import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.delete.TransportDeleteAction; +import org.elasticsearch.action.get.TransportGetAction; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.TransportSearchAction; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.client.internal.Client; @@ -543,17 +543,17 @@ private void trySuccessfullyLoadSuperuserRole(CompositeRolesStore compositeRoles assertThat(role.cluster().privileges(), containsInAnyOrder(ClusterPrivilegeResolver.ALL)); assertThat(role.indices().check(TransportSearchAction.TYPE.name()), Matchers.is(true)); - assertThat(role.indices().check(IndexAction.NAME), Matchers.is(true)); + assertThat(role.indices().check(TransportIndexAction.NAME), Matchers.is(true)); final Predicate indexActionPredicate = Automatons.predicate( role.indices().allowedActionsMatcher("index-" + randomAlphaOfLengthBetween(1, 12)) ); assertThat(indexActionPredicate.test(TransportSearchAction.TYPE.name()), is(true)); - assertThat(indexActionPredicate.test(IndexAction.NAME), is(true)); + assertThat(indexActionPredicate.test(TransportIndexAction.NAME), is(true)); final Predicate securityActionPredicate = Automatons.predicate(role.indices().allowedActionsMatcher(".security")); assertThat(securityActionPredicate.test(TransportSearchAction.TYPE.name()), is(true)); - assertThat(securityActionPredicate.test(IndexAction.NAME), is(false)); + assertThat(securityActionPredicate.test(TransportIndexAction.NAME), is(false)); } private void tryFailOnNonSuperuserRole(CompositeRolesStore compositeRolesStore, Matcher exceptionMatcher) { @@ -1037,7 +1037,7 @@ public ClusterPermission.Builder buildPermission(ClusterPermission.Builder build assertThat(role.cluster().check(PutUserAction.NAME, randomFrom(request1, request2), authentication), equalTo(true)); assertThat(role.cluster().check(PutUserAction.NAME, request3, authentication), equalTo(false)); - final IsResourceAuthorizedPredicate allowedRead = role.indices().allowedIndicesMatcher(GetAction.NAME); + final IsResourceAuthorizedPredicate allowedRead = role.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()); assertThat(allowedRead.test(mockIndexAbstraction("abc-123")), equalTo(true)); assertThat(allowedRead.test(mockIndexAbstraction("xyz-000")), equalTo(true)); assertThat(allowedRead.test(mockIndexAbstraction("ind-1-a")), equalTo(true)); @@ -1050,7 +1050,7 @@ public ClusterPermission.Builder buildPermission(ClusterPermission.Builder build assertThat(allowedRead.test(mockIndexAbstraction("remote-idx-2-1")), equalTo(false)); assertThat(allowedRead.test(mockIndexAbstraction("remote-idx-3-1")), equalTo(false)); - final IsResourceAuthorizedPredicate allowedWrite = role.indices().allowedIndicesMatcher(IndexAction.NAME); + final IsResourceAuthorizedPredicate allowedWrite = role.indices().allowedIndicesMatcher(TransportIndexAction.NAME); assertThat(allowedWrite.test(mockIndexAbstraction("abc-123")), equalTo(true)); assertThat(allowedWrite.test(mockIndexAbstraction("xyz-000")), equalTo(false)); assertThat(allowedWrite.test(mockIndexAbstraction("ind-1-a")), equalTo(true)); @@ -1233,7 +1233,7 @@ public void testBuildRoleWithRemoteIndicesDoesNotMergeWhenNothingToMerge() { assertHasRemoteGroupsForClusters(role.remoteIndices(), Set.of("remote-1"), Set.of("*")); assertHasIndexGroupsForClusters(role.remoteIndices(), Set.of("*"), indexGroup("index-1")); assertHasIndexGroupsForClusters(role.remoteIndices(), Set.of("remote-1"), indexGroup("index-1")); - final IsResourceAuthorizedPredicate allowedRead = role.indices().allowedIndicesMatcher(GetAction.NAME); + final IsResourceAuthorizedPredicate allowedRead = role.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()); assertThat(allowedRead.test(mockIndexAbstraction("index-1")), equalTo(true)); assertThat(allowedRead.test(mockIndexAbstraction("foo")), equalTo(false)); } @@ -1252,9 +1252,9 @@ public void testBuildRoleWithRemoteIndicesDoesNotCombineRemotesAndLocals() { ); assertHasRemoteGroupsForClusters(role.remoteIndices(), Set.of("*")); assertHasIndexGroupsForClusters(role.remoteIndices(), Set.of("*"), indexGroup("index-1")); - final IsResourceAuthorizedPredicate allowedRead = role.indices().allowedIndicesMatcher(GetAction.NAME); + final IsResourceAuthorizedPredicate allowedRead = role.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()); assertThat(allowedRead.test(mockIndexAbstraction("index-1")), equalTo(true)); - final IsResourceAuthorizedPredicate allowedWrite = role.indices().allowedIndicesMatcher(IndexAction.NAME); + final IsResourceAuthorizedPredicate allowedWrite = role.indices().allowedIndicesMatcher(TransportIndexAction.NAME); assertThat(allowedWrite.test(mockIndexAbstraction("index-1")), equalTo(true)); } @@ -2592,7 +2592,12 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() { } public void testXPackSecurityUserCanAccessAnyIndex() { - for (String action : Arrays.asList(GetAction.NAME, DeleteAction.NAME, TransportSearchAction.TYPE.name(), IndexAction.NAME)) { + for (String action : Arrays.asList( + TransportGetAction.TYPE.name(), + TransportDeleteAction.NAME, + TransportSearchAction.TYPE.name(), + TransportIndexAction.NAME + )) { IsResourceAuthorizedPredicate predicate = getXPackSecurityRole().indices().allowedIndicesMatcher(action); IndexAbstraction index = mockIndexAbstraction(randomAlphaOfLengthBetween(3, 12)); @@ -2607,7 +2612,12 @@ public void testXPackSecurityUserCanAccessAnyIndex() { } public void testSecurityProfileUserHasAccessForOnlyProfileIndex() { - for (String action : Arrays.asList(GetAction.NAME, DeleteAction.NAME, TransportSearchAction.TYPE.name(), IndexAction.NAME)) { + for (String action : Arrays.asList( + TransportGetAction.TYPE.name(), + TransportDeleteAction.NAME, + TransportSearchAction.TYPE.name(), + TransportIndexAction.NAME + )) { IsResourceAuthorizedPredicate predicate = getSecurityProfileRole().indices().allowedIndicesMatcher(action); List.of( @@ -2631,7 +2641,12 @@ public void testSecurityProfileUserHasAccessForOnlyProfileIndex() { } public void testXPackUserCanAccessNonRestrictedIndices() { - for (String action : Arrays.asList(GetAction.NAME, DeleteAction.NAME, TransportSearchAction.TYPE.name(), IndexAction.NAME)) { + for (String action : Arrays.asList( + TransportGetAction.TYPE.name(), + TransportDeleteAction.NAME, + TransportSearchAction.TYPE.name(), + TransportIndexAction.NAME + )) { IsResourceAuthorizedPredicate predicate = getXPackUserRole().indices().allowedIndicesMatcher(action); IndexAbstraction index = mockIndexAbstraction(randomAlphaOfLengthBetween(3, 12)); if (false == TestRestrictedIndices.RESTRICTED_INDICES.isRestricted(index.getName())) { @@ -2645,7 +2660,12 @@ public void testXPackUserCanAccessNonRestrictedIndices() { } public void testXPackUserCannotAccessSecurityOrAsyncSearch() { - for (String action : Arrays.asList(GetAction.NAME, DeleteAction.NAME, TransportSearchAction.TYPE.name(), IndexAction.NAME)) { + for (String action : Arrays.asList( + TransportGetAction.TYPE.name(), + TransportDeleteAction.NAME, + TransportSearchAction.TYPE.name(), + TransportIndexAction.NAME + )) { IsResourceAuthorizedPredicate predicate = getXPackUserRole().indices().allowedIndicesMatcher(action); for (String index : TestRestrictedIndices.SAMPLE_RESTRICTED_NAMES) { assertThat(predicate.test(mockIndexAbstraction(index)), Matchers.is(false)); @@ -2658,7 +2678,12 @@ public void testXPackUserCannotAccessSecurityOrAsyncSearch() { } public void testAsyncSearchUserCannotAccessNonRestrictedIndices() { - for (String action : Arrays.asList(GetAction.NAME, DeleteAction.NAME, TransportSearchAction.TYPE.name(), IndexAction.NAME)) { + for (String action : Arrays.asList( + TransportGetAction.TYPE.name(), + TransportDeleteAction.NAME, + TransportSearchAction.TYPE.name(), + TransportIndexAction.NAME + )) { IsResourceAuthorizedPredicate predicate = getAsyncSearchUserRole().indices().allowedIndicesMatcher(action); IndexAbstraction index = mockIndexAbstraction(randomAlphaOfLengthBetween(3, 12)); if (false == TestRestrictedIndices.RESTRICTED_INDICES.isRestricted(index.getName())) { @@ -2672,7 +2697,12 @@ public void testAsyncSearchUserCannotAccessNonRestrictedIndices() { } public void testAsyncSearchUserCanAccessOnlyAsyncSearchRestrictedIndices() { - for (String action : Arrays.asList(GetAction.NAME, DeleteAction.NAME, TransportSearchAction.TYPE.name(), IndexAction.NAME)) { + for (String action : Arrays.asList( + TransportGetAction.TYPE.name(), + TransportDeleteAction.NAME, + TransportSearchAction.TYPE.name(), + TransportIndexAction.NAME + )) { final IsResourceAuthorizedPredicate predicate = getAsyncSearchUserRole().indices().allowedIndicesMatcher(action); for (String index : TestRestrictedIndices.SAMPLE_RESTRICTED_NAMES) { assertThat(predicate.test(mockIndexAbstraction(index)), Matchers.is(false)); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/profile/ProfileServiceTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/profile/ProfileServiceTests.java index 496b2245ad80b..3512ac4b613d5 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/profile/ProfileServiceTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/profile/ProfileServiceTests.java @@ -13,13 +13,13 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.bulk.BulkAction; import org.elasticsearch.action.bulk.BulkRequest; -import org.elasticsearch.action.get.GetAction; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; -import org.elasticsearch.action.get.MultiGetAction; import org.elasticsearch.action.get.MultiGetItemResponse; import org.elasticsearch.action.get.MultiGetRequest; import org.elasticsearch.action.get.MultiGetResponse; +import org.elasticsearch.action.get.TransportGetAction; +import org.elasticsearch.action.get.TransportMultiGetAction; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.search.MultiSearchRequest; import org.elasticsearch.action.search.MultiSearchRequestBuilder; @@ -30,7 +30,7 @@ import org.elasticsearch.action.search.TransportMultiSearchAction; import org.elasticsearch.action.search.TransportSearchAction; import org.elasticsearch.action.support.PlainActionFuture; -import org.elasticsearch.action.update.UpdateAction; +import org.elasticsearch.action.update.TransportUpdateAction; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateRequestBuilder; import org.elasticsearch.action.update.UpdateResponse; @@ -355,7 +355,7 @@ public void testGetProfileSubjectsWithMissingUids() throws Exception { final ActionListener listener = (ActionListener) invocation.getArguments()[2]; listener.onResponse(new MultiGetResponse(responses.toArray(MultiGetItemResponse[]::new))); return null; - }).when(client).execute(eq(MultiGetAction.INSTANCE), any(MultiGetRequest.class), anyActionListener()); + }).when(client).execute(eq(TransportMultiGetAction.TYPE), any(MultiGetRequest.class), anyActionListener()); final PlainActionFuture>> future = new PlainActionFuture<>(); profileService.getProfileSubjects(allProfileUids, future); @@ -389,7 +389,7 @@ public void testGetProfileSubjectWithFailures() throws Exception { final ActionListener listener = (ActionListener) invocation.getArguments()[2]; listener.onFailure(mGetException); return null; - }).when(client).execute(eq(MultiGetAction.INSTANCE), any(MultiGetRequest.class), anyActionListener()); + }).when(client).execute(eq(TransportMultiGetAction.TYPE), any(MultiGetRequest.class), anyActionListener()); final PlainActionFuture>> future = new PlainActionFuture<>(); profileService.getProfileSubjects(randomList(1, 5, () -> randomAlphaOfLength(20)), future); ExecutionException e = expectThrows(ExecutionException.class, () -> future.get()); @@ -422,7 +422,7 @@ public void testGetProfileSubjectWithFailures() throws Exception { final ActionListener listener = (ActionListener) invocation.getArguments()[2]; listener.onResponse(new MultiGetResponse(responses.toArray(MultiGetItemResponse[]::new))); return null; - }).when(client).execute(eq(MultiGetAction.INSTANCE), any(MultiGetRequest.class), anyActionListener()); + }).when(client).execute(eq(TransportMultiGetAction.TYPE), any(MultiGetRequest.class), anyActionListener()); final PlainActionFuture>> future2 = new PlainActionFuture<>(); profileService.getProfileSubjects(allProfileUids, future2); @@ -622,7 +622,7 @@ public void testSecurityProfileOrigin() { final ActionListener listener = (ActionListener) invocation.getArguments()[2]; listener.onFailure(expectedException); return null; - }).when(client).execute(eq(UpdateAction.INSTANCE), any(UpdateRequest.class), anyActionListener()); + }).when(client).execute(eq(TransportUpdateAction.TYPE), any(UpdateRequest.class), anyActionListener()); final PlainActionFuture future2 = new PlainActionFuture<>(); profileService.doUpdate(mock(UpdateRequest.class), future2); final RuntimeException e2 = expectThrows(RuntimeException.class, future2::actionGet); @@ -956,7 +956,7 @@ public void testActivateWhenShouldSkipUpdateForActivateReturnsFalseFirst() throw final var listener = (ActionListener) invocation.getArguments()[2]; client.get(getRequest, listener); return null; - }).when(client).execute(eq(GetAction.INSTANCE), any(GetRequest.class), anyActionListener()); + }).when(client).execute(eq(TransportGetAction.TYPE), any(GetRequest.class), anyActionListener()); // First check returns false, second check return true or false randomly final boolean secondCheckResult = randomBoolean(); @@ -999,7 +999,7 @@ public void testActivateWhenGetRequestErrors() throws IOException { final var listener = (ActionListener) invocation.getArguments()[2]; client.get(getRequest, listener); return null; - }).when(client).execute(eq(GetAction.INSTANCE), any(GetRequest.class), anyActionListener()); + }).when(client).execute(eq(TransportGetAction.TYPE), any(GetRequest.class), anyActionListener()); // First check returns false doAnswer(invocation -> false).when(service).shouldSkipUpdateForActivate(any(), any()); @@ -1079,7 +1079,7 @@ private void mockMultiGetRequest(List sampleDocumentPar final ActionListener listener = (ActionListener) invocation.getArguments()[2]; client.multiGet(multiGetRequest, listener); return null; - }).when(client).execute(eq(MultiGetAction.INSTANCE), any(MultiGetRequest.class), anyActionListener()); + }).when(client).execute(eq(TransportMultiGetAction.TYPE), any(MultiGetRequest.class), anyActionListener()); final Map results = sampleDocumentParameters.stream() .collect( diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/test/SecurityMocks.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/test/SecurityMocks.java index 2f8666501f523..24d3fcb058f30 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/test/SecurityMocks.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/test/SecurityMocks.java @@ -16,10 +16,10 @@ import org.elasticsearch.action.get.MultiGetItemResponse; import org.elasticsearch.action.get.MultiGetRequest; import org.elasticsearch.action.get.MultiGetResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.client.internal.Client; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; @@ -221,7 +221,7 @@ public static void mockIndexRequest(Client client, String indexAliasName, Consum final ShardId shardId = new ShardId(request.index(), ESTestCase.randomAlphaOfLength(12), 0); listener.onResponse(new IndexResponse(shardId, request.id(), 1, 1, 1, true)); return null; - }).when(client).execute(eq(IndexAction.INSTANCE), any(IndexRequest.class), anyActionListener()); + }).when(client).execute(eq(TransportIndexAction.TYPE), any(IndexRequest.class), anyActionListener()); } @SuppressWarnings("unchecked") diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/ServerTransportFilterTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/ServerTransportFilterTests.java index c22892df2ce52..1ecd85cadab46 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/ServerTransportFilterTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/ServerTransportFilterTests.java @@ -10,7 +10,7 @@ import org.elasticsearch.TransportVersion; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.MockIndicesRequest; -import org.elasticsearch.action.admin.indices.close.CloseIndexAction; +import org.elasticsearch.action.admin.indices.close.TransportCloseIndexAction; import org.elasticsearch.action.admin.indices.delete.DeleteIndexAction; import org.elasticsearch.action.admin.indices.open.OpenIndexAction; import org.elasticsearch.action.search.TransportSearchAction; @@ -188,7 +188,7 @@ public void testCrossClusterAccessInboundMissingHeadersFail() { } public void testInboundDestructiveOperations() { - String action = randomFrom(CloseIndexAction.NAME, OpenIndexAction.NAME, DeleteIndexAction.NAME); + String action = randomFrom(TransportCloseIndexAction.NAME, OpenIndexAction.NAME, DeleteIndexAction.NAME); TransportRequest request = new MockIndicesRequest( IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean()), randomFrom("*", "_all", "test*") diff --git a/x-pack/plugin/slm/src/test/java/org/elasticsearch/xpack/slm/history/SnapshotHistoryStoreTests.java b/x-pack/plugin/slm/src/test/java/org/elasticsearch/xpack/slm/history/SnapshotHistoryStoreTests.java index 6b2e23594ec3f..082b097df684b 100644 --- a/x-pack/plugin/slm/src/test/java/org/elasticsearch/xpack/slm/history/SnapshotHistoryStoreTests.java +++ b/x-pack/plugin/slm/src/test/java/org/elasticsearch/xpack/slm/history/SnapshotHistoryStoreTests.java @@ -10,9 +10,9 @@ import org.elasticsearch.action.admin.indices.create.CreateIndexAction; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.service.ClusterService; @@ -38,6 +38,7 @@ import static org.elasticsearch.xpack.slm.history.SnapshotHistoryStore.SLM_HISTORY_DATA_STREAM; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.sameInstance; import static org.hamcrest.core.IsEqual.equalTo; public class SnapshotHistoryStoreTests extends ESTestCase { @@ -102,7 +103,7 @@ public void testPut() throws Exception { AtomicInteger calledTimes = new AtomicInteger(0); client.setVerifier((action, request, listener) -> { calledTimes.incrementAndGet(); - assertThat(action, instanceOf(IndexAction.class)); + assertThat(action, sameInstance(TransportIndexAction.TYPE)); assertThat(request, instanceOf(IndexRequest.class)); IndexRequest indexRequest = (IndexRequest) request; assertEquals(SLM_HISTORY_DATA_STREAM, indexRequest.index()); @@ -140,7 +141,7 @@ public void testPut() throws Exception { return new CreateIndexResponse(true, true, ((CreateIndexRequest) request).index()); } calledTimes.incrementAndGet(); - assertThat(action, instanceOf(IndexAction.class)); + assertThat(action, sameInstance(TransportIndexAction.TYPE)); assertThat(request, instanceOf(IndexRequest.class)); IndexRequest indexRequest = (IndexRequest) request; assertEquals(SLM_HISTORY_DATA_STREAM, indexRequest.index()); diff --git a/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/SqlSecurityTestCase.java b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/SqlSecurityTestCase.java index 0ab942fcff39f..e30934050bfb9 100644 --- a/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/SqlSecurityTestCase.java +++ b/x-pack/plugin/sql/qa/server/security/src/test/java/org/elasticsearch/xpack/sql/qa/security/SqlSecurityTestCase.java @@ -11,8 +11,8 @@ import org.elasticsearch.SpecialPermission; import org.elasticsearch.action.admin.indices.get.GetIndexAction; import org.elasticsearch.action.admin.indices.get.GetIndexRequest; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest; +import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; import org.elasticsearch.client.Request; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; @@ -281,7 +281,7 @@ public void testQueryWrongAccess() throws Exception { // This user has permission to run sql queries so they are given preliminary authorization .expect(true, SQL_ACTION_NAME, "wrong_access", empty()) // the following get index is granted too but against the no indices placeholder, as ignore_unavailable=true - .expect(true, FieldCapabilitiesAction.NAME, "wrong_access", hasItems("*", "-*")) + .expect(true, TransportFieldCapabilitiesAction.NAME, "wrong_access", hasItems("*", "-*")) .assertLogs(); } @@ -442,7 +442,7 @@ public void testDescribeWithWrongAccess() throws Exception { // This user has permission to run sql queries so they are given preliminary authorization .expect(true, SQL_ACTION_NAME, "wrong_access", empty()) // the following get index is granted too but against the no indices placeholder, as ignore_unavailable=true - .expect(true, FieldCapabilitiesAction.NAME, "wrong_access", hasItems("*", "-*")) + .expect(true, TransportFieldCapabilitiesAction.NAME, "wrong_access", hasItems("*", "-*")) .assertLogs(); } @@ -518,7 +518,7 @@ public AuditLogAsserter expectSqlCompositeActionGetIndex(String user, String... public AuditLogAsserter expectSqlCompositeActionFieldCaps(String user, String... indices) { expect(true, SQL_ACTION_NAME, user, empty()); - expect(true, FieldCapabilitiesAction.NAME, user, hasItems(indices)); + expect(true, TransportFieldCapabilitiesAction.NAME, user, hasItems(indices)); return this; } @@ -531,7 +531,7 @@ public AuditLogAsserter expect( String request = switch (action) { case SQL_ACTION_NAME -> "SqlQueryRequest"; case GetIndexAction.NAME -> GetIndexRequest.class.getSimpleName(); - case FieldCapabilitiesAction.NAME -> FieldCapabilitiesRequest.class.getSimpleName(); + case TransportFieldCapabilitiesAction.NAME -> FieldCapabilitiesRequest.class.getSimpleName(); default -> throw new IllegalArgumentException("Unknown action [" + action + "]"); }; final String eventAction = granted ? "access_granted" : "access_denied"; @@ -631,7 +631,7 @@ public void assertLogs() throws Exception { assertThat(log.containsKey("action"), is(true)); if (false == (SQL_ACTION_NAME.equals(log.get("action")) || GetIndexAction.NAME.equals(log.get("action")) - || FieldCapabilitiesAction.NAME.equals(log.get("action")))) { + || TransportFieldCapabilitiesAction.NAME.equals(log.get("action")))) { // TODO we may want to extend this and the assertions to SearchAction.NAME as well continue; } diff --git a/x-pack/plugin/sql/src/internalClusterTest/java/org/elasticsearch/xpack/sql/action/AbstractSqlBlockingIntegTestCase.java b/x-pack/plugin/sql/src/internalClusterTest/java/org/elasticsearch/xpack/sql/action/AbstractSqlBlockingIntegTestCase.java index f6aa45fd9c312..f667ae4b80d03 100644 --- a/x-pack/plugin/sql/src/internalClusterTest/java/org/elasticsearch/xpack/sql/action/AbstractSqlBlockingIntegTestCase.java +++ b/x-pack/plugin/sql/src/internalClusterTest/java/org/elasticsearch/xpack/sql/action/AbstractSqlBlockingIntegTestCase.java @@ -14,7 +14,7 @@ import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.admin.cluster.node.tasks.cancel.CancelTasksResponse; import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksResponse; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; +import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; import org.elasticsearch.action.support.ActionFilter; import org.elasticsearch.action.support.ActionFilterChain; import org.elasticsearch.common.settings.Settings; @@ -213,7 +213,7 @@ public void app ActionFilterChain chain ) { - if (action.equals(FieldCapabilitiesAction.NAME)) { + if (action.equals(TransportFieldCapabilitiesAction.NAME)) { final Consumer actionWrapper = resp -> { try { fieldCaps.incrementAndGet(); diff --git a/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/persistence/IndexBasedTransformConfigManager.java b/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/persistence/IndexBasedTransformConfigManager.java index 5d9a3971ad082..e87cf1ca7fc8d 100644 --- a/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/persistence/IndexBasedTransformConfigManager.java +++ b/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/persistence/IndexBasedTransformConfigManager.java @@ -20,8 +20,8 @@ import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshResponse; import org.elasticsearch.action.bulk.BulkItemResponse; -import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.TransportIndexAction; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.TransportSearchAction; @@ -135,13 +135,9 @@ public void putTransformCheckpoint(TransformCheckpoint checkpoint, ActionListene .id(TransformCheckpoint.documentId(checkpoint.getTransformId(), checkpoint.getCheckpoint())) .source(source); - executeAsyncWithOrigin( - client, - TRANSFORM_ORIGIN, - IndexAction.INSTANCE, - indexRequest, - ActionListener.wrap(r -> { listener.onResponse(true); }, listener::onFailure) - ); + executeAsyncWithOrigin(client, TRANSFORM_ORIGIN, TransportIndexAction.TYPE, indexRequest, ActionListener.wrap(r -> { + listener.onResponse(true); + }, listener::onFailure)); } catch (IOException e) { // not expected to happen but for the sake of completeness listener.onFailure(e); @@ -335,32 +331,28 @@ private void putTransformConfiguration( if (seqNoPrimaryTermAndIndex != null) { indexRequest.setIfSeqNo(seqNoPrimaryTermAndIndex.getSeqNo()).setIfPrimaryTerm(seqNoPrimaryTermAndIndex.getPrimaryTerm()); } - executeAsyncWithOrigin( - client, - TRANSFORM_ORIGIN, - IndexAction.INSTANCE, - indexRequest, - ActionListener.wrap(r -> { listener.onResponse(true); }, e -> { - if (e instanceof VersionConflictEngineException) { - if (DocWriteRequest.OpType.CREATE.equals(opType)) { // we want to create the transform but it already exists - listener.onFailure( - new ResourceAlreadyExistsException( - TransformMessages.getMessage(TransformMessages.REST_PUT_TRANSFORM_EXISTS, transformConfig.getId()) - ) - ); - } else { // we want to update the transform but it got updated in the meantime, report version conflict - listener.onFailure( - new ElasticsearchStatusException( - TransformMessages.getMessage(TransformMessages.REST_UPDATE_TRANSFORM_CONFLICT, transformConfig.getId()), - RestStatus.CONFLICT - ) - ); - } - } else { - listener.onFailure(new RuntimeException(TransformMessages.REST_PUT_FAILED_PERSIST_TRANSFORM_CONFIGURATION, e)); + executeAsyncWithOrigin(client, TRANSFORM_ORIGIN, TransportIndexAction.TYPE, indexRequest, ActionListener.wrap(r -> { + listener.onResponse(true); + }, e -> { + if (e instanceof VersionConflictEngineException) { + if (DocWriteRequest.OpType.CREATE.equals(opType)) { // we want to create the transform but it already exists + listener.onFailure( + new ResourceAlreadyExistsException( + TransformMessages.getMessage(TransformMessages.REST_PUT_TRANSFORM_EXISTS, transformConfig.getId()) + ) + ); + } else { // we want to update the transform but it got updated in the meantime, report version conflict + listener.onFailure( + new ElasticsearchStatusException( + TransformMessages.getMessage(TransformMessages.REST_UPDATE_TRANSFORM_CONFLICT, transformConfig.getId()), + RestStatus.CONFLICT + ) + ); } - }) - ); + } else { + listener.onFailure(new RuntimeException(TransformMessages.REST_PUT_FAILED_PERSIST_TRANSFORM_CONFIGURATION, e)); + } + })); } catch (IOException e) { // not expected to happen but for the sake of completeness listener.onFailure( @@ -717,7 +709,7 @@ public void putOrUpdateTransformStoredDoc( executeAsyncWithOrigin( client, TRANSFORM_ORIGIN, - IndexAction.INSTANCE, + TransportIndexAction.TYPE, indexRequest, ActionListener.wrap( r -> listener.onResponse(SeqNoPrimaryTermAndIndex.fromIndexResponse(r)), diff --git a/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/persistence/TransformIndex.java b/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/persistence/TransformIndex.java index 86d03ca37fc57..a08612fa4be72 100644 --- a/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/persistence/TransformIndex.java +++ b/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/persistence/TransformIndex.java @@ -12,8 +12,8 @@ import org.elasticsearch.ResourceAlreadyExistsException; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.admin.indices.alias.Alias; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.TransportIndicesAliasesAction; import org.elasticsearch.action.admin.indices.create.CreateIndexAction; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.get.GetIndexAction; @@ -233,7 +233,7 @@ static void setUpDestinationAliases(Client client, TransformConfig config, Actio config.getHeaders(), TRANSFORM_ORIGIN, client, - IndicesAliasesAction.INSTANCE, + TransportIndicesAliasesAction.TYPE, request, ActionListener.wrap(aliasesResponse -> { listener.onResponse(true); diff --git a/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/transforms/pivot/SchemaUtil.java b/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/transforms/pivot/SchemaUtil.java index 3b6ea7758947a..a07f5c987c30c 100644 --- a/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/transforms/pivot/SchemaUtil.java +++ b/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/transforms/pivot/SchemaUtil.java @@ -10,8 +10,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest; +import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.client.internal.Client; import org.elasticsearch.core.Tuple; @@ -196,7 +196,7 @@ public static void getDestinationFieldMappings( ClientHelper.executeAsyncWithOrigin( client, ClientHelper.TRANSFORM_ORIGIN, - FieldCapabilitiesAction.INSTANCE, + TransportFieldCapabilitiesAction.TYPE, fieldCapabilitiesRequest, ActionListener.wrap(r -> listener.onResponse(extractFieldMappings(r)), listener::onFailure) ); @@ -281,7 +281,7 @@ static void getSourceFieldMappings( headers, ClientHelper.TRANSFORM_ORIGIN, client, - FieldCapabilitiesAction.INSTANCE, + TransportFieldCapabilitiesAction.TYPE, fieldCapabilitiesRequest, ActionListener.wrap(response -> listener.onResponse(extractFieldMappings(response)), listener::onFailure) ); diff --git a/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/persistence/TransformIndexTests.java b/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/persistence/TransformIndexTests.java index 5afb6db1856fe..9db4ba1fc73b6 100644 --- a/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/persistence/TransformIndexTests.java +++ b/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/persistence/TransformIndexTests.java @@ -8,8 +8,8 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.LatchedActionListener; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.TransportIndicesAliasesAction; import org.elasticsearch.action.admin.indices.create.CreateIndexAction; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.get.GetIndexAction; @@ -203,7 +203,7 @@ public void testSetUpDestinationAliases() { TransformIndex.setUpDestinationAliases(client, config, ActionTestUtils.assertNoFailureListener(Assert::assertTrue)); ArgumentCaptor indicesAliasesRequestCaptor = ArgumentCaptor.forClass(IndicesAliasesRequest.class); - verify(client).execute(eq(IndicesAliasesAction.INSTANCE), indicesAliasesRequestCaptor.capture(), any()); + verify(client).execute(eq(TransportIndicesAliasesAction.TYPE), indicesAliasesRequestCaptor.capture(), any()); verify(client, atLeastOnce()).threadPool(); verifyNoMoreInteractions(client); From b9c29807ecc831838c398aace29157d24e51fdea Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Fri, 8 Dec 2023 10:26:17 +1100 Subject: [PATCH 05/22] Extract repositories metrics into its own class (#103034) This PR is a follow up of https://github.com/elastic/elasticsearch/pull/102505#discussion_r1402957598 that move the repositories metrics management into its own class which is then passed around instead of relying on the raw meterRegistry and string metric names. --- .../repositories/azure/AzureRepository.java | 4 +- .../azure/AzureRepositoryPlugin.java | 4 +- ...eCloudStorageBlobStoreRepositoryTests.java | 4 +- .../gcs/GoogleCloudStoragePlugin.java | 4 +- .../gcs/GoogleCloudStorageRepository.java | 4 +- .../s3/S3BlobStoreRepositoryMetricsTests.java | 16 +++--- .../s3/S3BlobStoreRepositoryTests.java | 8 +-- .../s3/S3RepositoryThirdPartyTests.java | 4 +- .../repositories/s3/S3BlobStore.java | 50 +++++------------ .../repositories/s3/S3Repository.java | 8 +-- .../repositories/s3/S3RepositoryPlugin.java | 18 +++---- .../s3/RepositoryCredentialsTests.java | 7 +-- .../s3/S3BlobContainerRetriesTests.java | 4 +- .../repositories/s3/S3RepositoryTests.java | 4 +- .../repository/url/URLRepositoryPlugin.java | 4 +- .../repositories/hdfs/HdfsPlugin.java | 4 +- .../plan/ShardSnapshotsServiceIT.java | 4 +- .../repositories/InvalidRepositoryIT.java | 3 +- ...BlobStoreRepositoryOperationPurposeIT.java | 4 +- ...etadataLoadingDuringSnapshotRestoreIT.java | 4 +- .../SnapshotsServiceDoubleFinalizationIT.java | 4 +- .../plugins/RepositoryPlugin.java | 4 +- .../repositories/RepositoriesMetrics.java | 53 +++++++++++++++++++ .../repositories/RepositoriesModule.java | 31 ++--------- .../blobstore/MeteredBlobStoreRepository.java | 8 +-- .../repositories/RepositoriesModuleTests.java | 22 ++++++-- .../RepositoriesServiceTests.java | 5 +- ...bStoreRepositoryDeleteThrottlingTests.java | 4 +- ...ncySimulatingBlobStoreRepositoryTests.java | 4 +- .../LatencySimulatingRepositoryPlugin.java | 4 +- .../snapshots/mockstore/MockRepository.java | 4 +- .../sourceonly/SourceOnlySnapshotIT.java | 4 +- .../elasticsearch/xpack/core/XPackPlugin.java | 4 +- .../core/LocalStateCompositeXPackPlugin.java | 10 ++-- .../lucene/bwc/AbstractArchiveTestCase.java | 4 +- ...chableSnapshotDiskThresholdIntegTests.java | 4 +- ...archableSnapshotsPrewarmingIntegTests.java | 4 +- ...SnapshotRecoveryStateIntegrationTests.java | 4 +- .../SnapshotBasedIndexRecoveryIT.java | 4 +- .../testkit/RepositoryAnalysisFailureIT.java | 4 +- .../testkit/RepositoryAnalysisSuccessIT.java | 4 +- .../votingonly/VotingOnlyNodePluginTests.java | 4 +- 42 files changed, 210 insertions(+), 145 deletions(-) create mode 100644 server/src/main/java/org/elasticsearch/repositories/RepositoriesMetrics.java diff --git a/modules/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java b/modules/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java index c71bbf02782ca..f58611cb0567a 100644 --- a/modules/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java +++ b/modules/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.indices.recovery.RecoverySettings; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.blobstore.MeteredBlobStoreRepository; -import org.elasticsearch.telemetry.metric.MeterRegistry; import org.elasticsearch.xcontent.NamedXContentRegistry; import java.util.Locale; @@ -109,7 +109,7 @@ public AzureRepository( recoverySettings, buildBasePath(metadata), buildLocation(metadata), - MeterRegistry.NOOP + RepositoriesMetrics.NOOP ); this.chunkSize = Repository.CHUNK_SIZE_SETTING.get(metadata.settings()); this.storageService = storageService; diff --git a/modules/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepositoryPlugin.java b/modules/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepositoryPlugin.java index 6ff9a40940e8c..73d969ee31b19 100644 --- a/modules/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepositoryPlugin.java +++ b/modules/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepositoryPlugin.java @@ -21,6 +21,7 @@ import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.ReloadablePlugin; import org.elasticsearch.plugins.RepositoryPlugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; import org.elasticsearch.threadpool.ExecutorBuilder; import org.elasticsearch.threadpool.ScalingExecutorBuilder; @@ -62,7 +63,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap(AzureRepository.TYPE, metadata -> { AzureStorageService storageService = azureStoreService.get(); diff --git a/modules/repository-gcs/src/internalClusterTest/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageBlobStoreRepositoryTests.java b/modules/repository-gcs/src/internalClusterTest/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageBlobStoreRepositoryTests.java index 87449d7153057..6d2c015d7d922 100644 --- a/modules/repository-gcs/src/internalClusterTest/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageBlobStoreRepositoryTests.java +++ b/modules/repository-gcs/src/internalClusterTest/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageBlobStoreRepositoryTests.java @@ -42,6 +42,7 @@ import org.elasticsearch.env.Environment; import org.elasticsearch.indices.recovery.RecoverySettings; import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.RepositoriesService; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.blobstore.BlobStoreRepository; @@ -256,7 +257,8 @@ public Map getRepositories( NamedXContentRegistry registry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap( GoogleCloudStorageRepository.TYPE, diff --git a/modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStoragePlugin.java b/modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStoragePlugin.java index 6acaff1801ffc..4f05289899a7f 100644 --- a/modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStoragePlugin.java +++ b/modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStoragePlugin.java @@ -17,6 +17,7 @@ import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.ReloadablePlugin; import org.elasticsearch.plugins.RepositoryPlugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; import org.elasticsearch.xcontent.NamedXContentRegistry; @@ -48,7 +49,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap( GoogleCloudStorageRepository.TYPE, diff --git a/modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageRepository.java b/modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageRepository.java index 21dd7529afaca..94d0abe17909f 100644 --- a/modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageRepository.java +++ b/modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageRepository.java @@ -19,9 +19,9 @@ import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.indices.recovery.RecoverySettings; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.RepositoryException; import org.elasticsearch.repositories.blobstore.MeteredBlobStoreRepository; -import org.elasticsearch.telemetry.metric.MeterRegistry; import org.elasticsearch.xcontent.NamedXContentRegistry; import java.util.Map; @@ -78,7 +78,7 @@ class GoogleCloudStorageRepository extends MeteredBlobStoreRepository { recoverySettings, buildBasePath(metadata), buildLocation(metadata), - MeterRegistry.NOOP + RepositoriesMetrics.NOOP ); this.storageService = storageService; diff --git a/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryMetricsTests.java b/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryMetricsTests.java index a7c1d25195028..59f65032272df 100644 --- a/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryMetricsTests.java +++ b/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryMetricsTests.java @@ -37,14 +37,14 @@ import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; -import static org.elasticsearch.repositories.RepositoriesModule.HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM; -import static org.elasticsearch.repositories.RepositoriesModule.METRIC_EXCEPTIONS_COUNT; -import static org.elasticsearch.repositories.RepositoriesModule.METRIC_EXCEPTIONS_HISTOGRAM; -import static org.elasticsearch.repositories.RepositoriesModule.METRIC_OPERATIONS_COUNT; -import static org.elasticsearch.repositories.RepositoriesModule.METRIC_REQUESTS_COUNT; -import static org.elasticsearch.repositories.RepositoriesModule.METRIC_THROTTLES_COUNT; -import static org.elasticsearch.repositories.RepositoriesModule.METRIC_THROTTLES_HISTOGRAM; -import static org.elasticsearch.repositories.RepositoriesModule.METRIC_UNSUCCESSFUL_OPERATIONS_COUNT; +import static org.elasticsearch.repositories.RepositoriesMetrics.HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM; +import static org.elasticsearch.repositories.RepositoriesMetrics.METRIC_EXCEPTIONS_COUNT; +import static org.elasticsearch.repositories.RepositoriesMetrics.METRIC_EXCEPTIONS_HISTOGRAM; +import static org.elasticsearch.repositories.RepositoriesMetrics.METRIC_OPERATIONS_COUNT; +import static org.elasticsearch.repositories.RepositoriesMetrics.METRIC_REQUESTS_COUNT; +import static org.elasticsearch.repositories.RepositoriesMetrics.METRIC_THROTTLES_COUNT; +import static org.elasticsearch.repositories.RepositoriesMetrics.METRIC_THROTTLES_HISTOGRAM; +import static org.elasticsearch.repositories.RepositoriesMetrics.METRIC_UNSUCCESSFUL_OPERATIONS_COUNT; import static org.elasticsearch.rest.RestStatus.INTERNAL_SERVER_ERROR; import static org.elasticsearch.rest.RestStatus.NOT_FOUND; import static org.elasticsearch.rest.RestStatus.TOO_MANY_REQUESTS; diff --git a/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java b/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java index c76364f48c081..29342a7f5ea92 100644 --- a/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java +++ b/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java @@ -37,6 +37,7 @@ import org.elasticsearch.indices.recovery.RecoverySettings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.PluginsService; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.RepositoriesService; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.RepositoryData; @@ -74,7 +75,7 @@ import java.util.stream.Collectors; import java.util.stream.StreamSupport; -import static org.elasticsearch.repositories.RepositoriesModule.METRIC_REQUESTS_COUNT; +import static org.elasticsearch.repositories.RepositoriesMetrics.METRIC_REQUESTS_COUNT; import static org.elasticsearch.repositories.blobstore.BlobStoreTestUtil.randomNonDataPurpose; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; @@ -444,9 +445,10 @@ protected S3Repository createRepository( NamedXContentRegistry registry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { - return new S3Repository(metadata, registry, getService(), clusterService, bigArrays, recoverySettings, getMeterRegistry()) { + return new S3Repository(metadata, registry, getService(), clusterService, bigArrays, recoverySettings, repositoriesMetrics) { @Override public BlobStore blobStore() { diff --git a/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3RepositoryThirdPartyTests.java b/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3RepositoryThirdPartyTests.java index 1e2ff831b8e49..f182b54b0c696 100644 --- a/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3RepositoryThirdPartyTests.java +++ b/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3RepositoryThirdPartyTests.java @@ -30,8 +30,8 @@ import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.PluginsService; import org.elasticsearch.repositories.AbstractThirdPartyRepositoryTestCase; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.RepositoriesService; -import org.elasticsearch.telemetry.metric.MeterRegistry; import org.elasticsearch.test.ClusterServiceUtils; import org.elasticsearch.test.fixtures.minio.MinioTestContainer; import org.elasticsearch.test.fixtures.testcontainers.TestContainersThreadFilter; @@ -145,7 +145,7 @@ public long absoluteTimeInMillis() { ClusterServiceUtils.createClusterService(threadpool), BigArrays.NON_RECYCLING_INSTANCE, new RecoverySettings(node().settings(), node().injector().getInstance(ClusterService.class).getClusterSettings()), - MeterRegistry.NOOP + RepositoriesMetrics.NOOP ) ) { repository.start(); diff --git a/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobStore.java b/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobStore.java index 99fe3d5cc31ad..c045e05a6f8e0 100644 --- a/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobStore.java +++ b/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobStore.java @@ -32,9 +32,7 @@ import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.core.TimeValue; -import org.elasticsearch.telemetry.metric.LongCounter; -import org.elasticsearch.telemetry.metric.LongHistogram; -import org.elasticsearch.telemetry.metric.MeterRegistry; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.threadpool.ThreadPool; import java.io.IOException; @@ -54,14 +52,6 @@ import java.util.stream.Collectors; import static org.elasticsearch.core.Strings.format; -import static org.elasticsearch.repositories.RepositoriesModule.HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM; -import static org.elasticsearch.repositories.RepositoriesModule.METRIC_EXCEPTIONS_COUNT; -import static org.elasticsearch.repositories.RepositoriesModule.METRIC_EXCEPTIONS_HISTOGRAM; -import static org.elasticsearch.repositories.RepositoriesModule.METRIC_OPERATIONS_COUNT; -import static org.elasticsearch.repositories.RepositoriesModule.METRIC_REQUESTS_COUNT; -import static org.elasticsearch.repositories.RepositoriesModule.METRIC_THROTTLES_COUNT; -import static org.elasticsearch.repositories.RepositoriesModule.METRIC_THROTTLES_HISTOGRAM; -import static org.elasticsearch.repositories.RepositoriesModule.METRIC_UNSUCCESSFUL_OPERATIONS_COUNT; class S3BlobStore implements BlobStore { @@ -91,15 +81,7 @@ class S3BlobStore implements BlobStore { private final ThreadPool threadPool; private final Executor snapshotExecutor; - private final MeterRegistry meterRegistry; - private final LongCounter requestCounter; - private final LongCounter exceptionCounter; - private final LongCounter throttleCounter; - private final LongCounter operationCounter; - private final LongCounter unsuccessfulOperationCounter; - private final LongHistogram exceptionHistogram; - private final LongHistogram throttleHistogram; - private final LongHistogram httpRequestTimeInMicroHistogram; + private final RepositoriesMetrics repositoriesMetrics; private final StatsCollectors statsCollectors = new StatsCollectors(); @@ -117,7 +99,7 @@ class S3BlobStore implements BlobStore { RepositoryMetadata repositoryMetadata, BigArrays bigArrays, ThreadPool threadPool, - MeterRegistry meterRegistry + RepositoriesMetrics repositoriesMetrics ) { this.service = service; this.bigArrays = bigArrays; @@ -129,15 +111,7 @@ class S3BlobStore implements BlobStore { this.repositoryMetadata = repositoryMetadata; this.threadPool = threadPool; this.snapshotExecutor = threadPool.executor(ThreadPool.Names.SNAPSHOT); - this.meterRegistry = meterRegistry; - this.requestCounter = this.meterRegistry.getLongCounter(METRIC_REQUESTS_COUNT); - this.exceptionCounter = this.meterRegistry.getLongCounter(METRIC_EXCEPTIONS_COUNT); - this.throttleCounter = this.meterRegistry.getLongCounter(METRIC_THROTTLES_COUNT); - this.operationCounter = this.meterRegistry.getLongCounter(METRIC_OPERATIONS_COUNT); - this.unsuccessfulOperationCounter = this.meterRegistry.getLongCounter(METRIC_UNSUCCESSFUL_OPERATIONS_COUNT); - this.exceptionHistogram = this.meterRegistry.getLongHistogram(METRIC_EXCEPTIONS_HISTOGRAM); - this.throttleHistogram = this.meterRegistry.getLongHistogram(METRIC_THROTTLES_HISTOGRAM); - this.httpRequestTimeInMicroHistogram = this.meterRegistry.getLongHistogram(HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM); + this.repositoriesMetrics = repositoriesMetrics; s3RequestRetryStats = new S3RequestRetryStats(getMaxRetries()); threadPool.scheduleWithFixedDelay(() -> { var priorRetryStats = s3RequestRetryStats; @@ -214,21 +188,21 @@ public final void collectMetrics(Request request, Response response) { .map(List::size) .orElse(0); - operationCounter.incrementBy(1, attributes); + repositoriesMetrics.operationCounter().incrementBy(1, attributes); if (numberOfAwsErrors == requestCount) { - unsuccessfulOperationCounter.incrementBy(1, attributes); + repositoriesMetrics.unsuccessfulOperationCounter().incrementBy(1, attributes); } - requestCounter.incrementBy(requestCount, attributes); + repositoriesMetrics.requestCounter().incrementBy(requestCount, attributes); if (exceptionCount > 0) { - exceptionCounter.incrementBy(exceptionCount, attributes); - exceptionHistogram.record(exceptionCount, attributes); + repositoriesMetrics.exceptionCounter().incrementBy(exceptionCount, attributes); + repositoriesMetrics.exceptionHistogram().record(exceptionCount, attributes); } if (throttleCount > 0) { - throttleCounter.incrementBy(throttleCount, attributes); - throttleHistogram.record(throttleCount, attributes); + repositoriesMetrics.throttleCounter().incrementBy(throttleCount, attributes); + repositoriesMetrics.throttleHistogram().record(throttleCount, attributes); } - httpRequestTimeInMicroHistogram.record(getHttpRequestTimeInMicros(request), attributes); + repositoriesMetrics.httpRequestTimeInMicroHistogram().record(getHttpRequestTimeInMicros(request), attributes); } private boolean assertConsistencyBetweenHttpRequestAndOperation(Request request, Operation operation) { diff --git a/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java b/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java index ddab811fcb078..624867a2f0c41 100644 --- a/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java +++ b/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java @@ -31,12 +31,12 @@ import org.elasticsearch.indices.recovery.RecoverySettings; import org.elasticsearch.monitor.jvm.JvmInfo; import org.elasticsearch.repositories.FinalizeSnapshotContext; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.RepositoryData; import org.elasticsearch.repositories.RepositoryException; import org.elasticsearch.repositories.blobstore.MeteredBlobStoreRepository; import org.elasticsearch.snapshots.SnapshotDeleteListener; import org.elasticsearch.snapshots.SnapshotsService; -import org.elasticsearch.telemetry.metric.MeterRegistry; import org.elasticsearch.threadpool.Scheduler; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.xcontent.NamedXContentRegistry; @@ -205,7 +205,7 @@ class S3Repository extends MeteredBlobStoreRepository { final ClusterService clusterService, final BigArrays bigArrays, final RecoverySettings recoverySettings, - final MeterRegistry meterRegistry + final RepositoriesMetrics repositoriesMetrics ) { super( metadata, @@ -215,7 +215,7 @@ class S3Repository extends MeteredBlobStoreRepository { recoverySettings, buildBasePath(metadata), buildLocation(metadata), - meterRegistry + repositoriesMetrics ); this.service = service; this.snapshotExecutor = threadPool().executor(ThreadPool.Names.SNAPSHOT); @@ -408,7 +408,7 @@ protected S3BlobStore createBlobStore() { metadata, bigArrays, threadPool, - meterRegistry + repositoriesMetrics ); } diff --git a/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3RepositoryPlugin.java b/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3RepositoryPlugin.java index f85a66c5eb367..ba762537537e3 100644 --- a/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3RepositoryPlugin.java +++ b/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3RepositoryPlugin.java @@ -23,8 +23,8 @@ import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.ReloadablePlugin; import org.elasticsearch.plugins.RepositoryPlugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; -import org.elasticsearch.telemetry.metric.MeterRegistry; import org.elasticsearch.xcontent.NamedXContentRegistry; import java.io.IOException; @@ -60,7 +60,6 @@ public class S3RepositoryPlugin extends Plugin implements RepositoryPlugin, Relo } private final SetOnce service = new SetOnce<>(); - private final SetOnce meterRegistry = new SetOnce<>(); private final Settings settings; public S3RepositoryPlugin(Settings settings) { @@ -77,16 +76,16 @@ protected S3Repository createRepository( final NamedXContentRegistry registry, final ClusterService clusterService, final BigArrays bigArrays, - final RecoverySettings recoverySettings + final RecoverySettings recoverySettings, + final RepositoriesMetrics repositoriesMetrics ) { - return new S3Repository(metadata, registry, service.get(), clusterService, bigArrays, recoverySettings, meterRegistry.get()); + return new S3Repository(metadata, registry, service.get(), clusterService, bigArrays, recoverySettings, repositoriesMetrics); } @Override public Collection createComponents(PluginServices services) { service.set(s3Service(services.environment(), services.clusterService().getSettings())); this.service.get().refreshAndClearCache(S3ClientSettings.load(settings)); - meterRegistry.set(services.telemetryProvider().getMeterRegistry()); return List.of(service); } @@ -100,11 +99,12 @@ public Map getRepositories( final NamedXContentRegistry registry, final ClusterService clusterService, final BigArrays bigArrays, - final RecoverySettings recoverySettings + final RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap( S3Repository.TYPE, - metadata -> createRepository(metadata, registry, clusterService, bigArrays, recoverySettings) + metadata -> createRepository(metadata, registry, clusterService, bigArrays, recoverySettings, repositoriesMetrics) ); } @@ -146,8 +146,4 @@ public void reload(Settings settings) { public void close() throws IOException { getService().close(); } - - protected MeterRegistry getMeterRegistry() { - return meterRegistry.get(); - } } diff --git a/modules/repository-s3/src/test/java/org/elasticsearch/repositories/s3/RepositoryCredentialsTests.java b/modules/repository-s3/src/test/java/org/elasticsearch/repositories/s3/RepositoryCredentialsTests.java index a966e70fd960c..085d438618a19 100644 --- a/modules/repository-s3/src/test/java/org/elasticsearch/repositories/s3/RepositoryCredentialsTests.java +++ b/modules/repository-s3/src/test/java/org/elasticsearch/repositories/s3/RepositoryCredentialsTests.java @@ -26,12 +26,12 @@ import org.elasticsearch.indices.recovery.RecoverySettings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.PluginsService; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.RepositoriesService; import org.elasticsearch.rest.AbstractRestChannel; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.RestResponse; import org.elasticsearch.rest.action.admin.cluster.RestGetRepositoriesAction; -import org.elasticsearch.telemetry.metric.MeterRegistry; import org.elasticsearch.test.ESSingleNodeTestCase; import org.elasticsearch.test.rest.FakeRestRequest; import org.elasticsearch.xcontent.NamedXContentRegistry; @@ -262,9 +262,10 @@ protected S3Repository createRepository( NamedXContentRegistry registry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { - return new S3Repository(metadata, registry, getService(), clusterService, bigArrays, recoverySettings, MeterRegistry.NOOP) { + return new S3Repository(metadata, registry, getService(), clusterService, bigArrays, recoverySettings, repositoriesMetrics) { @Override protected void assertSnapshotOrGenericThread() { // eliminate thread name check as we create repo manually on test/main threads diff --git a/modules/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobContainerRetriesTests.java b/modules/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobContainerRetriesTests.java index b4b136338923f..8f273bcad3cf5 100644 --- a/modules/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobContainerRetriesTests.java +++ b/modules/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobContainerRetriesTests.java @@ -36,9 +36,9 @@ import org.elasticsearch.core.SuppressForbidden; import org.elasticsearch.core.TimeValue; import org.elasticsearch.env.Environment; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.blobstore.AbstractBlobContainerRetriesTestCase; import org.elasticsearch.repositories.blobstore.BlobStoreTestUtil; -import org.elasticsearch.telemetry.metric.MeterRegistry; import org.hamcrest.Matcher; import org.junit.After; import org.junit.Before; @@ -162,7 +162,7 @@ protected BlobContainer createBlobContainer( repositoryMetadata, BigArrays.NON_RECYCLING_INSTANCE, new DeterministicTaskQueue().getThreadPool(), - MeterRegistry.NOOP + RepositoriesMetrics.NOOP ) ) { @Override diff --git a/modules/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3RepositoryTests.java b/modules/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3RepositoryTests.java index db477c16a57e7..ab5edc4608bfd 100644 --- a/modules/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3RepositoryTests.java +++ b/modules/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3RepositoryTests.java @@ -18,9 +18,9 @@ import org.elasticsearch.common.util.MockBigArrays; import org.elasticsearch.env.Environment; import org.elasticsearch.indices.recovery.RecoverySettings; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.RepositoryException; import org.elasticsearch.repositories.blobstore.BlobStoreTestUtil; -import org.elasticsearch.telemetry.metric.MeterRegistry; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xcontent.NamedXContentRegistry; import org.hamcrest.Matchers; @@ -129,7 +129,7 @@ private S3Repository createS3Repo(RepositoryMetadata metadata) { BlobStoreTestUtil.mockClusterService(), MockBigArrays.NON_RECYCLING_INSTANCE, new RecoverySettings(Settings.EMPTY, new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS)), - MeterRegistry.NOOP + RepositoriesMetrics.NOOP ) { @Override protected void assertSnapshotOrGenericThread() { diff --git a/modules/repository-url/src/main/java/org/elasticsearch/plugin/repository/url/URLRepositoryPlugin.java b/modules/repository-url/src/main/java/org/elasticsearch/plugin/repository/url/URLRepositoryPlugin.java index fe33051df342e..0bd3ad462ef70 100644 --- a/modules/repository-url/src/main/java/org/elasticsearch/plugin/repository/url/URLRepositoryPlugin.java +++ b/modules/repository-url/src/main/java/org/elasticsearch/plugin/repository/url/URLRepositoryPlugin.java @@ -18,6 +18,7 @@ import org.elasticsearch.indices.recovery.RecoverySettings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.RepositoryPlugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.url.URLRepository; import org.elasticsearch.xcontent.NamedXContentRegistry; @@ -47,7 +48,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap(URLRepository.TYPE, metadata -> { assert httpClientFactory.get() != null : "Expected to get a configured http client factory"; diff --git a/plugins/repository-hdfs/src/main/java/org/elasticsearch/repositories/hdfs/HdfsPlugin.java b/plugins/repository-hdfs/src/main/java/org/elasticsearch/repositories/hdfs/HdfsPlugin.java index 957622fe66247..426899643859b 100644 --- a/plugins/repository-hdfs/src/main/java/org/elasticsearch/repositories/hdfs/HdfsPlugin.java +++ b/plugins/repository-hdfs/src/main/java/org/elasticsearch/repositories/hdfs/HdfsPlugin.java @@ -18,6 +18,7 @@ import org.elasticsearch.indices.recovery.RecoverySettings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.RepositoryPlugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; import org.elasticsearch.xcontent.NamedXContentRegistry; @@ -108,7 +109,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap( "hdfs", diff --git a/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/plan/ShardSnapshotsServiceIT.java b/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/plan/ShardSnapshotsServiceIT.java index 30c57873fc6b1..212cf7510d349 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/plan/ShardSnapshotsServiceIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/plan/ShardSnapshotsServiceIT.java @@ -27,6 +27,7 @@ import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.RepositoryPlugin; import org.elasticsearch.repositories.IndexId; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.RepositoriesService; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.RepositoryData; @@ -72,7 +73,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap( TYPE, diff --git a/server/src/internalClusterTest/java/org/elasticsearch/repositories/InvalidRepositoryIT.java b/server/src/internalClusterTest/java/org/elasticsearch/repositories/InvalidRepositoryIT.java index 1c096120a7649..730cdba059a69 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/repositories/InvalidRepositoryIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/repositories/InvalidRepositoryIT.java @@ -70,7 +70,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap( TYPE, diff --git a/server/src/internalClusterTest/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryOperationPurposeIT.java b/server/src/internalClusterTest/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryOperationPurposeIT.java index 91eb1dc6eb01b..6c8f4c04e2a75 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryOperationPurposeIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryOperationPurposeIT.java @@ -25,6 +25,7 @@ import org.elasticsearch.indices.recovery.RecoverySettings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.RepositoryPlugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.fs.FsRepository; import org.elasticsearch.snapshots.AbstractSnapshotIntegTestCase; @@ -94,7 +95,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Map.of( ASSERTING_REPO_TYPE, diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java index 3b129455d4eef..0aa3475de7be1 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java @@ -20,6 +20,7 @@ import org.elasticsearch.indices.recovery.RecoverySettings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.repositories.IndexId; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.RepositoriesService; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.RepositoryData; @@ -207,7 +208,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap( TYPE, diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SnapshotsServiceDoubleFinalizationIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SnapshotsServiceDoubleFinalizationIT.java index d9e6a8eff5ad1..4c9de6cb5369f 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SnapshotsServiceDoubleFinalizationIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SnapshotsServiceDoubleFinalizationIT.java @@ -31,6 +31,7 @@ import org.elasticsearch.indices.recovery.RecoverySettings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.RepositoryPlugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.fs.FsRepository; import org.elasticsearch.snapshots.mockstore.BlobStoreWrapper; @@ -204,7 +205,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Map.of( REPO_TYPE, diff --git a/server/src/main/java/org/elasticsearch/plugins/RepositoryPlugin.java b/server/src/main/java/org/elasticsearch/plugins/RepositoryPlugin.java index ff6d21f3039a8..86f2fb3feeab4 100644 --- a/server/src/main/java/org/elasticsearch/plugins/RepositoryPlugin.java +++ b/server/src/main/java/org/elasticsearch/plugins/RepositoryPlugin.java @@ -13,6 +13,7 @@ import org.elasticsearch.env.Environment; import org.elasticsearch.index.IndexVersion; import org.elasticsearch.indices.recovery.RecoverySettings; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; import org.elasticsearch.snapshots.Snapshot; import org.elasticsearch.xcontent.NamedXContentRegistry; @@ -39,7 +40,8 @@ default Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.emptyMap(); } diff --git a/server/src/main/java/org/elasticsearch/repositories/RepositoriesMetrics.java b/server/src/main/java/org/elasticsearch/repositories/RepositoriesMetrics.java new file mode 100644 index 0000000000000..8442cf8c4a341 --- /dev/null +++ b/server/src/main/java/org/elasticsearch/repositories/RepositoriesMetrics.java @@ -0,0 +1,53 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.repositories; + +import org.elasticsearch.telemetry.metric.LongCounter; +import org.elasticsearch.telemetry.metric.LongHistogram; +import org.elasticsearch.telemetry.metric.MeterRegistry; + +public record RepositoriesMetrics( + LongCounter requestCounter, + LongCounter exceptionCounter, + LongCounter throttleCounter, + LongCounter operationCounter, + LongCounter unsuccessfulOperationCounter, + LongHistogram exceptionHistogram, + LongHistogram throttleHistogram, + LongHistogram httpRequestTimeInMicroHistogram +) { + + public static RepositoriesMetrics NOOP = new RepositoriesMetrics(MeterRegistry.NOOP); + + public static final String METRIC_REQUESTS_COUNT = "es.repositories.requests.count"; + public static final String METRIC_EXCEPTIONS_COUNT = "es.repositories.exceptions.count"; + public static final String METRIC_THROTTLES_COUNT = "es.repositories.throttles.count"; + public static final String METRIC_OPERATIONS_COUNT = "es.repositories.operations.count"; + public static final String METRIC_UNSUCCESSFUL_OPERATIONS_COUNT = "es.repositories.operations.unsuccessful.count"; + public static final String METRIC_EXCEPTIONS_HISTOGRAM = "es.repositories.exceptions.histogram"; + public static final String METRIC_THROTTLES_HISTOGRAM = "es.repositories.throttles.histogram"; + public static final String HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM = "es.repositories.requests.http_request_time.histogram"; + + public RepositoriesMetrics(MeterRegistry meterRegistry) { + this( + meterRegistry.registerLongCounter(METRIC_REQUESTS_COUNT, "repository request counter", "unit"), + meterRegistry.registerLongCounter(METRIC_EXCEPTIONS_COUNT, "repository request exception counter", "unit"), + meterRegistry.registerLongCounter(METRIC_THROTTLES_COUNT, "repository request throttle counter", "unit"), + meterRegistry.registerLongCounter(METRIC_OPERATIONS_COUNT, "repository operation counter", "unit"), + meterRegistry.registerLongCounter(METRIC_UNSUCCESSFUL_OPERATIONS_COUNT, "repository unsuccessful operation counter", "unit"), + meterRegistry.registerLongHistogram(METRIC_EXCEPTIONS_HISTOGRAM, "repository request exception histogram", "unit"), + meterRegistry.registerLongHistogram(METRIC_THROTTLES_HISTOGRAM, "repository request throttle histogram", "unit"), + meterRegistry.registerLongHistogram( + HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM, + "HttpRequestTime in microseconds expressed as as a histogram", + "micros" + ) + ); + } +} diff --git a/server/src/main/java/org/elasticsearch/repositories/RepositoriesModule.java b/server/src/main/java/org/elasticsearch/repositories/RepositoriesModule.java index a60ab48597de3..902dcd6078e7f 100644 --- a/server/src/main/java/org/elasticsearch/repositories/RepositoriesModule.java +++ b/server/src/main/java/org/elasticsearch/repositories/RepositoriesModule.java @@ -35,14 +35,6 @@ */ public final class RepositoriesModule { - public static final String METRIC_REQUESTS_COUNT = "es.repositories.requests.count"; - public static final String METRIC_EXCEPTIONS_COUNT = "es.repositories.exceptions.count"; - public static final String METRIC_THROTTLES_COUNT = "es.repositories.throttles.count"; - public static final String METRIC_OPERATIONS_COUNT = "es.repositories.operations.count"; - public static final String METRIC_UNSUCCESSFUL_OPERATIONS_COUNT = "es.repositories.operations.unsuccessful.count"; - public static final String METRIC_EXCEPTIONS_HISTOGRAM = "es.repositories.exceptions.histogram"; - public static final String METRIC_THROTTLES_HISTOGRAM = "es.repositories.throttles.histogram"; - public static final String HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM = "es.repositories.requests.http_request_time.histogram"; private final RepositoriesService repositoriesService; public RepositoriesModule( @@ -55,25 +47,7 @@ public RepositoriesModule( RecoverySettings recoverySettings, TelemetryProvider telemetryProvider ) { - // TODO: refactor APM metrics into their own class, passed in as a dependency (e.g. see BlobCacheMetrics as an example). - telemetryProvider.getMeterRegistry().registerLongCounter(METRIC_REQUESTS_COUNT, "repository request counter", "unit"); - telemetryProvider.getMeterRegistry().registerLongCounter(METRIC_EXCEPTIONS_COUNT, "repository request exception counter", "unit"); - telemetryProvider.getMeterRegistry().registerLongCounter(METRIC_THROTTLES_COUNT, "repository operation counter", "unit"); - telemetryProvider.getMeterRegistry() - .registerLongCounter(METRIC_OPERATIONS_COUNT, "repository unsuccessful operation counter", "unit"); - telemetryProvider.getMeterRegistry() - .registerLongCounter(METRIC_UNSUCCESSFUL_OPERATIONS_COUNT, "repository request throttle counter", "unit"); - telemetryProvider.getMeterRegistry() - .registerLongHistogram(METRIC_EXCEPTIONS_HISTOGRAM, "repository request exception histogram", "unit"); - telemetryProvider.getMeterRegistry() - .registerLongHistogram(METRIC_THROTTLES_HISTOGRAM, "repository request throttle histogram", "unit"); - telemetryProvider.getMeterRegistry() - .registerLongHistogram( - HTTP_REQUEST_TIME_IN_MICROS_HISTOGRAM, - "HttpRequestTime in microseconds expressed as as a histogram", - "micros" - ); - + final RepositoriesMetrics repositoriesMetrics = new RepositoriesMetrics(telemetryProvider.getMeterRegistry()); Map factories = new HashMap<>(); factories.put( FsRepository.TYPE, @@ -86,7 +60,8 @@ public RepositoriesModule( namedXContentRegistry, clusterService, bigArrays, - recoverySettings + recoverySettings, + repositoriesMetrics ); for (Map.Entry entry : newRepoTypes.entrySet()) { if (factories.put(entry.getKey(), entry.getValue()) != null) { diff --git a/server/src/main/java/org/elasticsearch/repositories/blobstore/MeteredBlobStoreRepository.java b/server/src/main/java/org/elasticsearch/repositories/blobstore/MeteredBlobStoreRepository.java index 4029938c6fc5f..6ecab2f8c77f2 100644 --- a/server/src/main/java/org/elasticsearch/repositories/blobstore/MeteredBlobStoreRepository.java +++ b/server/src/main/java/org/elasticsearch/repositories/blobstore/MeteredBlobStoreRepository.java @@ -14,9 +14,9 @@ import org.elasticsearch.common.blobstore.BlobPath; import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.indices.recovery.RecoverySettings; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.RepositoryInfo; import org.elasticsearch.repositories.RepositoryStatsSnapshot; -import org.elasticsearch.telemetry.metric.MeterRegistry; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.xcontent.NamedXContentRegistry; @@ -24,7 +24,7 @@ public abstract class MeteredBlobStoreRepository extends BlobStoreRepository { private final RepositoryInfo repositoryInfo; - protected final MeterRegistry meterRegistry; + protected final RepositoriesMetrics repositoriesMetrics; public MeteredBlobStoreRepository( RepositoryMetadata metadata, @@ -34,10 +34,10 @@ public MeteredBlobStoreRepository( RecoverySettings recoverySettings, BlobPath basePath, Map location, - MeterRegistry meterRegistry + RepositoriesMetrics repositoriesMetrics ) { super(metadata, namedXContentRegistry, clusterService, bigArrays, recoverySettings, basePath); - this.meterRegistry = meterRegistry; + this.repositoriesMetrics = repositoriesMetrics; ThreadPool threadPool = clusterService.getClusterApplierService().threadPool(); this.repositoryInfo = new RepositoryInfo( UUIDs.randomBase64UUID(), diff --git a/server/src/test/java/org/elasticsearch/repositories/RepositoriesModuleTests.java b/server/src/test/java/org/elasticsearch/repositories/RepositoriesModuleTests.java index e99dcb9dae561..c3cdfe3b8981f 100644 --- a/server/src/test/java/org/elasticsearch/repositories/RepositoriesModuleTests.java +++ b/server/src/test/java/org/elasticsearch/repositories/RepositoriesModuleTests.java @@ -24,6 +24,8 @@ import java.util.Collections; import java.util.List; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -58,9 +60,13 @@ public void setUp() throws Exception { } public void testCanRegisterTwoRepositoriesWithDifferentTypes() { - when(plugin1.getRepositories(environment, contentRegistry, clusterService, MockBigArrays.NON_RECYCLING_INSTANCE, recoverySettings)) + when(plugin1.getRepositories(eq(environment), eq(contentRegistry), eq(clusterService), + eq(MockBigArrays.NON_RECYCLING_INSTANCE), eq(recoverySettings), + any(RepositoriesMetrics.class))) .thenReturn(Collections.singletonMap("type1", factory)); - when(plugin2.getRepositories(environment, contentRegistry, clusterService, MockBigArrays.NON_RECYCLING_INSTANCE, recoverySettings)) + when(plugin2.getRepositories(eq(environment), eq(contentRegistry), eq(clusterService), + eq(MockBigArrays.NON_RECYCLING_INSTANCE), eq(recoverySettings), + any(RepositoriesMetrics.class))) .thenReturn(Collections.singletonMap("type2", factory)); // Would throw @@ -75,9 +81,13 @@ public void testCanRegisterTwoRepositoriesWithDifferentTypes() { } public void testCannotRegisterTwoRepositoriesWithSameTypes() { - when(plugin1.getRepositories(environment, contentRegistry, clusterService, MockBigArrays.NON_RECYCLING_INSTANCE, recoverySettings)) + when(plugin1.getRepositories(eq(environment), eq(contentRegistry), eq(clusterService), + eq(MockBigArrays.NON_RECYCLING_INSTANCE), eq(recoverySettings), + any(RepositoriesMetrics.class))) .thenReturn(Collections.singletonMap("type1", factory)); - when(plugin2.getRepositories(environment, contentRegistry, clusterService, MockBigArrays.NON_RECYCLING_INSTANCE, recoverySettings)) + when(plugin2.getRepositories(eq(environment), eq(contentRegistry), eq(clusterService), + eq(MockBigArrays.NON_RECYCLING_INSTANCE), eq(recoverySettings), + any(RepositoriesMetrics.class))) .thenReturn(Collections.singletonMap("type1", factory)); IllegalArgumentException ex = expectThrows( @@ -119,7 +129,9 @@ public void testCannotRegisterTwoInternalRepositoriesWithSameTypes() { } public void testCannotRegisterNormalAndInternalRepositoriesWithSameTypes() { - when(plugin1.getRepositories(environment, contentRegistry, clusterService, MockBigArrays.NON_RECYCLING_INSTANCE, recoverySettings)) + when(plugin1.getRepositories(eq(environment), eq(contentRegistry), eq(clusterService), + eq(MockBigArrays.NON_RECYCLING_INSTANCE), eq(recoverySettings), + any(RepositoriesMetrics.class))) .thenReturn(Collections.singletonMap("type1", factory)); when(plugin2.getInternalRepositories(environment, contentRegistry, clusterService, recoverySettings)).thenReturn( Collections.singletonMap("type1", factory) diff --git a/server/src/test/java/org/elasticsearch/repositories/RepositoriesServiceTests.java b/server/src/test/java/org/elasticsearch/repositories/RepositoriesServiceTests.java index e30a67c166b5d..4f7001f00e6a7 100644 --- a/server/src/test/java/org/elasticsearch/repositories/RepositoriesServiceTests.java +++ b/server/src/test/java/org/elasticsearch/repositories/RepositoriesServiceTests.java @@ -39,7 +39,6 @@ import org.elasticsearch.repositories.blobstore.MeteredBlobStoreRepository; import org.elasticsearch.snapshots.SnapshotDeleteListener; import org.elasticsearch.snapshots.SnapshotId; -import org.elasticsearch.telemetry.metric.MeterRegistry; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.Transport; @@ -484,7 +483,7 @@ private MeteredRepositoryTypeA(RepositoryMetadata metadata, ClusterService clust mock(RecoverySettings.class), BlobPath.EMPTY, Map.of("bucket", "bucket-a"), - MeterRegistry.NOOP + RepositoriesMetrics.NOOP ); } @@ -512,7 +511,7 @@ private MeteredRepositoryTypeB(RepositoryMetadata metadata, ClusterService clust mock(RecoverySettings.class), BlobPath.EMPTY, Map.of("bucket", "bucket-b"), - MeterRegistry.NOOP + RepositoriesMetrics.NOOP ); } diff --git a/server/src/test/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryDeleteThrottlingTests.java b/server/src/test/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryDeleteThrottlingTests.java index 0d322cf2542a1..0d94c027f8c46 100644 --- a/server/src/test/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryDeleteThrottlingTests.java +++ b/server/src/test/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryDeleteThrottlingTests.java @@ -22,6 +22,7 @@ import org.elasticsearch.indices.recovery.RecoverySettings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.RepositoryPlugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.fs.FsRepository; import org.elasticsearch.test.ESIntegTestCase; @@ -69,7 +70,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap( TEST_REPO_TYPE, diff --git a/test/external-modules/latency-simulating-directory/src/internalClusterTest/java/org/elasticsearch/test/simulatedlatencyrepo/LatencySimulatingBlobStoreRepositoryTests.java b/test/external-modules/latency-simulating-directory/src/internalClusterTest/java/org/elasticsearch/test/simulatedlatencyrepo/LatencySimulatingBlobStoreRepositoryTests.java index 7e1d1ac376cf0..77e151ed22f32 100644 --- a/test/external-modules/latency-simulating-directory/src/internalClusterTest/java/org/elasticsearch/test/simulatedlatencyrepo/LatencySimulatingBlobStoreRepositoryTests.java +++ b/test/external-modules/latency-simulating-directory/src/internalClusterTest/java/org/elasticsearch/test/simulatedlatencyrepo/LatencySimulatingBlobStoreRepositoryTests.java @@ -20,6 +20,7 @@ import org.elasticsearch.license.LicenseSettings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.RepositoryPlugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; import org.elasticsearch.snapshots.AbstractSnapshotIntegTestCase; import org.elasticsearch.snapshots.SnapshotInfo; @@ -57,7 +58,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Map.of( REPO_TYPE, diff --git a/test/external-modules/latency-simulating-directory/src/main/java/org/elasticsearch/test/simulatedlatencyrepo/LatencySimulatingRepositoryPlugin.java b/test/external-modules/latency-simulating-directory/src/main/java/org/elasticsearch/test/simulatedlatencyrepo/LatencySimulatingRepositoryPlugin.java index e59da871a95bc..51e5234bb7b75 100644 --- a/test/external-modules/latency-simulating-directory/src/main/java/org/elasticsearch/test/simulatedlatencyrepo/LatencySimulatingRepositoryPlugin.java +++ b/test/external-modules/latency-simulating-directory/src/main/java/org/elasticsearch/test/simulatedlatencyrepo/LatencySimulatingRepositoryPlugin.java @@ -15,6 +15,7 @@ import org.elasticsearch.indices.recovery.RecoverySettings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.RepositoryPlugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; import org.elasticsearch.xcontent.NamedXContentRegistry; @@ -34,7 +35,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Map.of( TYPE, diff --git a/test/framework/src/main/java/org/elasticsearch/snapshots/mockstore/MockRepository.java b/test/framework/src/main/java/org/elasticsearch/snapshots/mockstore/MockRepository.java index 1e4c328e9b1ac..b1381e408a75d 100644 --- a/test/framework/src/main/java/org/elasticsearch/snapshots/mockstore/MockRepository.java +++ b/test/framework/src/main/java/org/elasticsearch/snapshots/mockstore/MockRepository.java @@ -36,6 +36,7 @@ import org.elasticsearch.env.Environment; import org.elasticsearch.indices.recovery.RecoverySettings; import org.elasticsearch.plugins.RepositoryPlugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.blobstore.BlobStoreRepository; import org.elasticsearch.repositories.fs.FsRepository; @@ -82,7 +83,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap( "mock", diff --git a/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/snapshots/sourceonly/SourceOnlySnapshotIT.java b/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/snapshots/sourceonly/SourceOnlySnapshotIT.java index eca3bdea374b4..90a525c2df45c 100644 --- a/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/snapshots/sourceonly/SourceOnlySnapshotIT.java +++ b/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/snapshots/sourceonly/SourceOnlySnapshotIT.java @@ -32,6 +32,7 @@ import org.elasticsearch.plugins.EnginePlugin; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.RepositoryPlugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; @@ -86,7 +87,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap("source", SourceOnlySnapshotRepository.newRepositoryFactory()); } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackPlugin.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackPlugin.java index 66534cccff064..761390266231e 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackPlugin.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackPlugin.java @@ -78,6 +78,7 @@ import org.elasticsearch.protocol.xpack.XPackInfoRequest; import org.elasticsearch.protocol.xpack.XPackInfoResponse; import org.elasticsearch.protocol.xpack.XPackUsageRequest; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestHandler; @@ -431,7 +432,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap("source", SourceOnlySnapshotRepository.newRepositoryFactory()); } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/LocalStateCompositeXPackPlugin.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/LocalStateCompositeXPackPlugin.java index 26436e497a644..7747461a6f93a 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/LocalStateCompositeXPackPlugin.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/LocalStateCompositeXPackPlugin.java @@ -78,6 +78,7 @@ import org.elasticsearch.plugins.ShutdownAwarePlugin; import org.elasticsearch.plugins.SystemIndexPlugin; import org.elasticsearch.plugins.interceptor.RestServerActionPlugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestHandler; @@ -493,13 +494,16 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { HashMap repositories = new HashMap<>( - super.getRepositories(env, namedXContentRegistry, clusterService, bigArrays, recoverySettings) + super.getRepositories(env, namedXContentRegistry, clusterService, bigArrays, recoverySettings, repositoriesMetrics) ); filterPlugins(RepositoryPlugin.class).forEach( - r -> repositories.putAll(r.getRepositories(env, namedXContentRegistry, clusterService, bigArrays, recoverySettings)) + r -> repositories.putAll( + r.getRepositories(env, namedXContentRegistry, clusterService, bigArrays, recoverySettings, RepositoriesMetrics.NOOP) + ) ); return repositories; } diff --git a/x-pack/plugin/old-lucene-versions/src/internalClusterTest/java/org/elasticsearch/xpack/lucene/bwc/AbstractArchiveTestCase.java b/x-pack/plugin/old-lucene-versions/src/internalClusterTest/java/org/elasticsearch/xpack/lucene/bwc/AbstractArchiveTestCase.java index 095185241c4dc..206dfbe6729d6 100644 --- a/x-pack/plugin/old-lucene-versions/src/internalClusterTest/java/org/elasticsearch/xpack/lucene/bwc/AbstractArchiveTestCase.java +++ b/x-pack/plugin/old-lucene-versions/src/internalClusterTest/java/org/elasticsearch/xpack/lucene/bwc/AbstractArchiveTestCase.java @@ -21,6 +21,7 @@ import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.RepositoryPlugin; import org.elasticsearch.repositories.IndexId; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.RepositoryData; import org.elasticsearch.repositories.fs.FsRepository; @@ -60,7 +61,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Map.of( FAKE_VERSIONS_TYPE, diff --git a/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/allocation/SearchableSnapshotDiskThresholdIntegTests.java b/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/allocation/SearchableSnapshotDiskThresholdIntegTests.java index 91ddb112feee6..8d115d0f19580 100644 --- a/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/allocation/SearchableSnapshotDiskThresholdIntegTests.java +++ b/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/allocation/SearchableSnapshotDiskThresholdIntegTests.java @@ -34,6 +34,7 @@ import org.elasticsearch.node.NodeRoleSettings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.repositories.IndexId; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.RepositoriesService; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.fs.FsRepository; @@ -376,7 +377,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap( TYPE, diff --git a/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/cache/full/SearchableSnapshotsPrewarmingIntegTests.java b/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/cache/full/SearchableSnapshotsPrewarmingIntegTests.java index 7e6981a4594e5..0cf6cb93c865b 100644 --- a/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/cache/full/SearchableSnapshotsPrewarmingIntegTests.java +++ b/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/cache/full/SearchableSnapshotsPrewarmingIntegTests.java @@ -41,6 +41,7 @@ import org.elasticsearch.plugins.PluginsService; import org.elasticsearch.plugins.RepositoryPlugin; import org.elasticsearch.repositories.IndexId; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.RepositoriesService; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.RepositoryData; @@ -440,7 +441,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap( "tracking", diff --git a/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/recovery/SearchableSnapshotRecoveryStateIntegrationTests.java b/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/recovery/SearchableSnapshotRecoveryStateIntegrationTests.java index 5b31549dbd42f..6800dea01863a 100644 --- a/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/recovery/SearchableSnapshotRecoveryStateIntegrationTests.java +++ b/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/recovery/SearchableSnapshotRecoveryStateIntegrationTests.java @@ -25,6 +25,7 @@ import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.RepositoryPlugin; import org.elasticsearch.repositories.IndexId; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.RepositoriesService; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.RepositoryData; @@ -240,7 +241,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap( "test-fs", diff --git a/x-pack/plugin/snapshot-based-recoveries/src/internalClusterTest/java/org/elasticsearch/xpack/snapshotbasedrecoveries/recovery/SnapshotBasedIndexRecoveryIT.java b/x-pack/plugin/snapshot-based-recoveries/src/internalClusterTest/java/org/elasticsearch/xpack/snapshotbasedrecoveries/recovery/SnapshotBasedIndexRecoveryIT.java index 4670f0fd0b9b1..d19747578b537 100644 --- a/x-pack/plugin/snapshot-based-recoveries/src/internalClusterTest/java/org/elasticsearch/xpack/snapshotbasedrecoveries/recovery/SnapshotBasedIndexRecoveryIT.java +++ b/x-pack/plugin/snapshot-based-recoveries/src/internalClusterTest/java/org/elasticsearch/xpack/snapshotbasedrecoveries/recovery/SnapshotBasedIndexRecoveryIT.java @@ -57,6 +57,7 @@ import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.RepositoryPlugin; import org.elasticsearch.repositories.IndexId; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.RepositoriesService; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.blobstore.BlobStoreRepository; @@ -148,7 +149,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Map.of( FAULTY_TYPE, diff --git a/x-pack/plugin/snapshot-repo-test-kit/src/internalClusterTest/java/org/elasticsearch/repositories/blobstore/testkit/RepositoryAnalysisFailureIT.java b/x-pack/plugin/snapshot-repo-test-kit/src/internalClusterTest/java/org/elasticsearch/repositories/blobstore/testkit/RepositoryAnalysisFailureIT.java index 2f55e55b2f0cf..adf5aec6a72ce 100644 --- a/x-pack/plugin/snapshot-repo-test-kit/src/internalClusterTest/java/org/elasticsearch/repositories/blobstore/testkit/RepositoryAnalysisFailureIT.java +++ b/x-pack/plugin/snapshot-repo-test-kit/src/internalClusterTest/java/org/elasticsearch/repositories/blobstore/testkit/RepositoryAnalysisFailureIT.java @@ -32,6 +32,7 @@ import org.elasticsearch.indices.recovery.RecoverySettings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.RepositoryPlugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.RepositoriesService; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.RepositoryMissingException; @@ -430,7 +431,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Map.of( DISRUPTABLE_REPO_TYPE, diff --git a/x-pack/plugin/snapshot-repo-test-kit/src/internalClusterTest/java/org/elasticsearch/repositories/blobstore/testkit/RepositoryAnalysisSuccessIT.java b/x-pack/plugin/snapshot-repo-test-kit/src/internalClusterTest/java/org/elasticsearch/repositories/blobstore/testkit/RepositoryAnalysisSuccessIT.java index 77095fc770908..45e63eb9ff31f 100644 --- a/x-pack/plugin/snapshot-repo-test-kit/src/internalClusterTest/java/org/elasticsearch/repositories/blobstore/testkit/RepositoryAnalysisSuccessIT.java +++ b/x-pack/plugin/snapshot-repo-test-kit/src/internalClusterTest/java/org/elasticsearch/repositories/blobstore/testkit/RepositoryAnalysisSuccessIT.java @@ -31,6 +31,7 @@ import org.elasticsearch.indices.recovery.RecoverySettings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.RepositoryPlugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.RepositoriesService; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.RepositoryMissingException; @@ -149,7 +150,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Map.of( ASSERTING_REPO_TYPE, diff --git a/x-pack/plugin/voting-only-node/src/internalClusterTest/java/org/elasticsearch/cluster/coordination/votingonly/VotingOnlyNodePluginTests.java b/x-pack/plugin/voting-only-node/src/internalClusterTest/java/org/elasticsearch/cluster/coordination/votingonly/VotingOnlyNodePluginTests.java index 9fa7d10581353..983ca4e741d83 100644 --- a/x-pack/plugin/voting-only-node/src/internalClusterTest/java/org/elasticsearch/cluster/coordination/votingonly/VotingOnlyNodePluginTests.java +++ b/x-pack/plugin/voting-only-node/src/internalClusterTest/java/org/elasticsearch/cluster/coordination/votingonly/VotingOnlyNodePluginTests.java @@ -25,6 +25,7 @@ import org.elasticsearch.node.Node; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.RepositoryPlugin; +import org.elasticsearch.repositories.RepositoriesMetrics; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.fs.FsRepository; import org.elasticsearch.snapshots.SnapshotInfo; @@ -243,7 +244,8 @@ public Map getRepositories( NamedXContentRegistry namedXContentRegistry, ClusterService clusterService, BigArrays bigArrays, - RecoverySettings recoverySettings + RecoverySettings recoverySettings, + RepositoriesMetrics repositoriesMetrics ) { return Collections.singletonMap( "verifyaccess-fs", From 47a640fc9e1ffcc1b8202ee6a07864ea7d5708cd Mon Sep 17 00:00:00 2001 From: Tim Grein Date: Fri, 8 Dec 2023 10:45:13 +0100 Subject: [PATCH 06/22] [Connectors API] Check the created sync job in the post connector sync job integration tests (#103136) Add verifications of the values of a created sync job to the integration tests. --- .../entsearch/400_connector_sync_job_post.yml | 59 ++++++++++++++++++- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/400_connector_sync_job_post.yml b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/400_connector_sync_job_post.yml index 055221b917cb1..0403842cb0728 100644 --- a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/400_connector_sync_job_post.yml +++ b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/400_connector_sync_job_post.yml @@ -20,28 +20,83 @@ setup: id: test-connector job_type: full trigger_method: on_demand + - set: { id: id } + + - match: { id: $id } + + - do: + connector_sync_job.get: + connector_sync_job_id: $id + + - match: { connector.id: test-connector} + - match: { job_type: full } + - match: { trigger_method: on_demand } + - match: { status: pending } + - match: { total_document_count: 0 } + - match: { indexed_document_count: 0 } + - match: { indexed_document_volume: 0 } + - match: { deleted_document_count: 0 } - match: { id: $id } + - exists: created_at + - exists: last_seen + --- -'Create connector sync job with missing job type': +'Create connector sync job with missing job type - expect job type full as default': - do: connector_sync_job.post: body: id: test-connector trigger_method: on_demand + - set: { id: id } + - match: { id: $id } + - do: + connector_sync_job.get: + connector_sync_job_id: $id + + - match: { connector.id: test-connector } + - match: { job_type: full } + - match: { trigger_method: on_demand } + - match: { status: pending } + - match: { total_document_count: 0 } + - match: { indexed_document_count: 0 } + - match: { indexed_document_volume: 0 } + - match: { deleted_document_count: 0 } + - match: { id: $id } + - exists: created_at + - exists: last_seen + --- -'Create connector sync job with missing trigger method': +'Create connector sync job with missing trigger method - expect trigger method on_demand as default': - do: connector_sync_job.post: body: id: test-connector job_type: full + - set: { id: id } + + - match: { id: $id } + + - do: + connector_sync_job.get: + connector_sync_job_id: $id + + - match: { connector.id: test-connector } + - match: { job_type: full } + - match: { trigger_method: on_demand } + - match: { status: pending } + - match: { total_document_count: 0 } + - match: { indexed_document_count: 0 } + - match: { indexed_document_volume: 0 } + - match: { deleted_document_count: 0 } - match: { id: $id } + - exists: created_at + - exists: last_seen --- 'Create connector sync job with non-existing connector id': From 39d9ce8f897edaf7da89dda3e43d6b2707f07eff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Fred=C3=A9n?= <109296772+jfreden@users.noreply.github.com> Date: Fri, 8 Dec 2023 11:11:11 +0100 Subject: [PATCH 07/22] [DOCS] Update SAML guide to reference attribute_delimiters.group (#103102) This is a follow up PR from https://github.com/elastic/elasticsearch/pull/102769. The SAML realm can now be configured to split the `groups` attribute by delimiter, this updates the docs to mention that. --- .../authentication/saml-guide.asciidoc | 27 +++++++------------ .../settings/security-settings.asciidoc | 12 ++++----- 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/docs/reference/security/authentication/saml-guide.asciidoc b/docs/reference/security/authentication/saml-guide.asciidoc index c0cdd6bc01dc3..cf91e11b7f18f 100644 --- a/docs/reference/security/authentication/saml-guide.asciidoc +++ b/docs/reference/security/authentication/saml-guide.asciidoc @@ -328,24 +328,15 @@ groups:: _(Recommended)_ + [NOTE] ==== -Some IdPs are configured to send the `groups` list as a comma-separated string, -but {es} can't parse this string into an array of groups. To map this SAML -attribute to the `attributes.groups` setting in the {es} realm, a cluster -security administrator can use a wildcard when -<>. While flexible, wildcards are -less accurate and can match on unwanted patterns. Instead, a cluster security -administrator can use a regular expression to create a role mapping rule that -matches only a single group. For example, the following regular expression -matches only on the `elasticsearch-admins` group: - -[source,sh] ----- -/^(.*,)?elasticsearch-admins(,.*)?$/ ----- - -These regular expressions are based on Lucene’s -{ref}/regexp-syntax.html[regular expression syntax], and can match more complex -patterns. All regular expressions must start and end with a forward slash. +Some IdPs are configured to send the `groups` list as a single value, comma-separated +string. To map this SAML attribute to the `attributes.groups` setting in the {es} +realm, you can configure a string delimiter using the `attribute_delimiters.group` +setting. + +For example, splitting the SAML attribute value +`engineering,elasticsearch-admins,employees` on a delimiter value of `,` will +result in `engineering`, `elasticsearch-admins`, and `employees` as the list of +groups for the user. ==== name:: _(Optional)_ The user's full name. diff --git a/docs/reference/settings/security-settings.asciidoc b/docs/reference/settings/security-settings.asciidoc index 5729a31b6c728..f4875fd096b00 100644 --- a/docs/reference/settings/security-settings.asciidoc +++ b/docs/reference/settings/security-settings.asciidoc @@ -1222,7 +1222,7 @@ _Distinguished Name_. `attribute_patterns.principal` {ess-icon}:: (<>) A Java regular expression that is matched against the SAML attribute specified -by `attributes.pattern` before it is applied to the user's _principal_ property. +by `attributes.principal` before it is applied to the user's _principal_ property. The attribute value must match the pattern and the value of the first _capturing group_ is used as the principal. For example, `^([^@]+)@example\\.com$` matches email addresses from the "example.com" domain and uses the local-part as @@ -1257,13 +1257,13 @@ As per `attribute_patterns.principal`, but for the _dn_ property. `attribute_delimiters.groups` {ess-icon}:: (<>) A plain string that is used as a delimiter to split a single-valued SAML -attribute specified by attributes.groups before it is applied to the user's -groups property. For example, splitting the SAML attribute value -engineering,elasticsearch-admins,employees on a delimiter value of , will -result in engineering, elasticsearch-admins, and employees as the list of +attribute specified by `attributes.groups` before it is applied to the user's +_groups_ property. For example, splitting the SAML attribute value +`engineering,elasticsearch-admins,employees` on a delimiter value of `,` will +result in `engineering`, `elasticsearch-admins`, and `employees` as the list of groups for the user. The delimiter will always be split on, regardless of escaping in the input string. This setting does not support multi-valued SAML -attributes. It cannot be used together with the attribute_patterns setting. +attributes. It cannot be used together with the `attribute_patterns` setting. You can only configure this setting for the groups attribute. // end::saml-attributes-delimiters-groups-tag[] From c6f7e2d8689926e5c8743d88943cc55182af7bb1 Mon Sep 17 00:00:00 2001 From: Tim Grein Date: Fri, 8 Dec 2023 11:56:46 +0100 Subject: [PATCH 08/22] Add new IsAfterAssertion for yaml rest tests (#103122) Adds a new assertion "is_after", which can be used in the yaml based rest tests to check, whether one instant comes after the other. --- .../rest-api-spec/test/README.asciidoc | 9 +++ .../test/rest/yaml/Features.java | 3 +- .../yaml/section/ClientYamlTestSuite.java | 11 +++ .../rest/yaml/section/ExecutableSection.java | 1 + .../rest/yaml/section/IsAfterAssertion.java | 69 +++++++++++++++++++ .../rest/yaml/section/AssertionTests.java | 11 +++ .../section/ClientYamlTestSuiteTests.java | 12 ++++ .../yaml/section/IsAfterAssertionTests.java | 63 +++++++++++++++++ 8 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/section/IsAfterAssertion.java create mode 100644 test/yaml-rest-runner/src/test/java/org/elasticsearch/test/rest/yaml/section/IsAfterAssertionTests.java diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/README.asciidoc b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/README.asciidoc index 96a1d5d25f0fd..c2baa6746afdb 100644 --- a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/README.asciidoc +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/README.asciidoc @@ -526,6 +526,15 @@ For instance, when testing you may want to base64 encode username and password f Stashed values can be used as described in the `set` section +=== `is_after` + +Used to compare two variables (both need to be of type String, which can be parsed to an Instant) and check, whether +the first one is after the other one. + +.... + - is_after: { result.some_field: 2023-05-25T12:30:00.000Z } +.... + === `is_true` The specified key exists and has a true value (ie not `0`, `false`, `undefined`, `null` diff --git a/test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/Features.java b/test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/Features.java index e11e22488c834..8b9aafff5bded 100644 --- a/test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/Features.java +++ b/test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/Features.java @@ -39,7 +39,8 @@ public final class Features { "arbitrary_key", "allowed_warnings", "allowed_warnings_regex", - "close_to" + "close_to", + "is_after" ); private Features() { diff --git a/test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/section/ClientYamlTestSuite.java b/test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/section/ClientYamlTestSuite.java index 225bb3a94d7ca..4fee01e71d881 100644 --- a/test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/section/ClientYamlTestSuite.java +++ b/test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/section/ClientYamlTestSuite.java @@ -272,6 +272,17 @@ private static Stream validateExecutableSections( """, section.getLocation().lineNumber())) ); + errors = Stream.concat( + errors, + sections.stream() + .filter(section -> section instanceof IsAfterAssertion) + .filter(section -> false == hasSkipFeature("is_after", testSection, setupSection, teardownSection)) + .map(section -> String.format(Locale.ROOT, """ + attempted to add an [is_after] assertion without a corresponding ["skip": "features": "is_after"] \ + so runners that do not support the [is_after] assertion can skip the test at line [%d]\ + """, section.getLocation().lineNumber())) + ); + return errors; } diff --git a/test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/section/ExecutableSection.java b/test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/section/ExecutableSection.java index 64832d47cc7b3..a3fb9870a6ba8 100644 --- a/test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/section/ExecutableSection.java +++ b/test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/section/ExecutableSection.java @@ -28,6 +28,7 @@ public interface ExecutableSection { new NamedXContentRegistry.Entry(ExecutableSection.class, new ParseField("set"), SetSection::parse), new NamedXContentRegistry.Entry(ExecutableSection.class, new ParseField("transform_and_set"), TransformAndSetSection::parse), new NamedXContentRegistry.Entry(ExecutableSection.class, new ParseField("match"), MatchAssertion::parse), + new NamedXContentRegistry.Entry(ExecutableSection.class, new ParseField("is_after"), IsAfterAssertion::parse), new NamedXContentRegistry.Entry(ExecutableSection.class, new ParseField("is_true"), IsTrueAssertion::parse), new NamedXContentRegistry.Entry(ExecutableSection.class, new ParseField("is_false"), IsFalseAssertion::parse), new NamedXContentRegistry.Entry(ExecutableSection.class, new ParseField("gt"), GreaterThanAssertion::parse), diff --git a/test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/section/IsAfterAssertion.java b/test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/section/IsAfterAssertion.java new file mode 100644 index 0000000000000..986cae4b28b5e --- /dev/null +++ b/test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/section/IsAfterAssertion.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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.test.rest.yaml.section; + +import org.elasticsearch.core.Tuple; +import org.elasticsearch.logging.LogManager; +import org.elasticsearch.logging.Logger; +import org.elasticsearch.xcontent.XContentLocation; +import org.elasticsearch.xcontent.XContentParser; + +import java.io.IOException; +import java.time.Instant; +import java.time.format.DateTimeParseException; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * Represents an is after assert section: + * + * - is_after: { result.some_instant: "2023-05-25T12:30:00.000Z" } + * + */ +public class IsAfterAssertion extends Assertion { + + public static IsAfterAssertion parse(XContentParser parser) throws IOException { + XContentLocation location = parser.getTokenLocation(); + Tuple stringObjectTuple = ParserUtils.parseTuple(parser); + return new IsAfterAssertion(location, stringObjectTuple.v1(), stringObjectTuple.v2()); + } + + private static final Logger logger = LogManager.getLogger(IsAfterAssertion.class); + + public IsAfterAssertion(XContentLocation location, String field, Object expectedValue) { + super(location, field, expectedValue); + } + + @Override + protected void doAssert(Object actualValue, Object expectedValue) { + assertNotNull("field [" + getField() + "] is null", actualValue); + assertNotNull("value to test against cannot be null", expectedValue); + + Instant fieldInstant = parseToInstant( + actualValue.toString(), + "field [" + getField() + "] cannot be parsed to " + Instant.class.getSimpleName() + ", got [" + actualValue + "]" + ); + Instant valueInstant = parseToInstant( + expectedValue.toString(), + "value to test against [" + expectedValue + "] cannot be parsed to " + Instant.class.getSimpleName() + ); + + logger.trace("assert that [{}] is after [{}] (field [{}])", fieldInstant, valueInstant); + assertTrue("field [" + getField() + "] should be after [" + actualValue + "], but was not", fieldInstant.isAfter(valueInstant)); + } + + private Instant parseToInstant(String string, String onErrorMessage) { + try { + return Instant.parse(string); + } catch (DateTimeParseException e) { + throw new AssertionError(onErrorMessage, e); + } + } +} diff --git a/test/yaml-rest-runner/src/test/java/org/elasticsearch/test/rest/yaml/section/AssertionTests.java b/test/yaml-rest-runner/src/test/java/org/elasticsearch/test/rest/yaml/section/AssertionTests.java index 953b5f261485d..2513a7f1e94c1 100644 --- a/test/yaml-rest-runner/src/test/java/org/elasticsearch/test/rest/yaml/section/AssertionTests.java +++ b/test/yaml-rest-runner/src/test/java/org/elasticsearch/test/rest/yaml/section/AssertionTests.java @@ -69,6 +69,17 @@ public void testParseLength() throws Exception { assertThat((Integer) lengthAssertion.getExpectedValue(), equalTo(22)); } + public void testParseIsAfter() throws Exception { + parser = createParser(YamlXContent.yamlXContent, "{ field: 2021-05-25T12:30:00.000Z}"); + + IsAfterAssertion isAfterAssertion = IsAfterAssertion.parse(parser); + + assertThat(isAfterAssertion, notNullValue()); + assertThat(isAfterAssertion.getField(), equalTo("field")); + assertThat(isAfterAssertion.getExpectedValue(), instanceOf(String.class)); + assertThat(isAfterAssertion.getExpectedValue(), equalTo("2021-05-25T12:30:00.000Z")); + } + public void testParseMatchSimpleIntegerValue() throws Exception { parser = createParser(YamlXContent.yamlXContent, "{ field: 10 }"); diff --git a/test/yaml-rest-runner/src/test/java/org/elasticsearch/test/rest/yaml/section/ClientYamlTestSuiteTests.java b/test/yaml-rest-runner/src/test/java/org/elasticsearch/test/rest/yaml/section/ClientYamlTestSuiteTests.java index 5a9de8de37549..3f8cc298c5c36 100644 --- a/test/yaml-rest-runner/src/test/java/org/elasticsearch/test/rest/yaml/section/ClientYamlTestSuiteTests.java +++ b/test/yaml-rest-runner/src/test/java/org/elasticsearch/test/rest/yaml/section/ClientYamlTestSuiteTests.java @@ -17,6 +17,7 @@ import java.nio.file.Files; import java.nio.file.Path; +import java.time.Instant; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -715,6 +716,17 @@ public void testAddingCloseToWithSkip() { createTestSuite(skipSection, closeToAssertion).validate(); } + public void testAddingIsAfterWithSkip() { + int lineNumber = between(1, 10000); + SkipSection skipSection = new SkipSection(null, singletonList("is_after"), emptyList(), null); + IsAfterAssertion isAfterAssertion = new IsAfterAssertion( + new XContentLocation(lineNumber, 0), + randomAlphaOfLength(randomIntBetween(3, 30)), + randomInstantBetween(Instant.ofEpochSecond(0L), Instant.ofEpochSecond(3000000000L)) + ); + createTestSuite(skipSection, isAfterAssertion).validate(); + } + private static ClientYamlTestSuite createTestSuite(SkipSection skipSection, ExecutableSection executableSection) { final SetupSection setupSection; final TeardownSection teardownSection; diff --git a/test/yaml-rest-runner/src/test/java/org/elasticsearch/test/rest/yaml/section/IsAfterAssertionTests.java b/test/yaml-rest-runner/src/test/java/org/elasticsearch/test/rest/yaml/section/IsAfterAssertionTests.java new file mode 100644 index 0000000000000..d810fdc8b66ad --- /dev/null +++ b/test/yaml-rest-runner/src/test/java/org/elasticsearch/test/rest/yaml/section/IsAfterAssertionTests.java @@ -0,0 +1,63 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.test.rest.yaml.section; + +import org.elasticsearch.xcontent.XContentLocation; + +import java.io.IOException; + +public class IsAfterAssertionTests extends AbstractClientYamlTestFragmentParserTestCase { + + public void testParseIsAfterAssertionWithNonInstantValue() { + XContentLocation xContentLocation = new XContentLocation(0, 0); + IsAfterAssertion isAfterAssertion = new IsAfterAssertion(xContentLocation, "some_field", "non instant value"); + + expectThrows(AssertionError.class, () -> isAfterAssertion.doAssert("2022-05-25T12:30:00.000Z", "non instant value")); + } + + public void testIsAfter() { + String field = "some_field"; + + // actual value one year after value to test against + String actualValue = "2022-05-25T12:30:00.000Z"; + String expectedValue = "2021-05-25T12:30:00.000Z"; + + XContentLocation xContentLocation = new XContentLocation(0, 0); + IsAfterAssertion isAfterAssertion = new IsAfterAssertion(xContentLocation, field, expectedValue); + + isAfterAssertion.doAssert(actualValue, expectedValue); + } + + public void testIsNotAfter() { + String field = "some_field"; + + // actual value one year before value to test against + String actualValue = "2020-05-25T12:30:00.000Z"; + String expectedValue = "2021-05-25T12:30:00.000Z"; + + XContentLocation xContentLocation = new XContentLocation(0, 0); + IsAfterAssertion isAfterAssertion = new IsAfterAssertion(xContentLocation, field, expectedValue); + + expectThrows(AssertionError.class, () -> isAfterAssertion.doAssert(actualValue, expectedValue)); + } + + public void testActualValueIsNull() { + XContentLocation xContentLocation = new XContentLocation(0, 0); + IsAfterAssertion isAfterAssertion = new IsAfterAssertion(xContentLocation, "field", "2021-05-25T12:30:00.000Z"); + + expectThrows(AssertionError.class, () -> isAfterAssertion.doAssert(null, "2021-05-25T12:30:00.000Z")); + } + + public void testExpectedValueIsNull() throws IOException { + XContentLocation xContentLocation = new XContentLocation(0, 0); + IsAfterAssertion isAfterAssertion = new IsAfterAssertion(xContentLocation, "field", "2021-05-25T12:30:00.000Z"); + + expectThrows(AssertionError.class, () -> isAfterAssertion.doAssert("2021-05-25T12:30:00.000Z", null)); + } +} From 17811280c20ca51b67400d32dc813d91bcee6ed3 Mon Sep 17 00:00:00 2001 From: Andrei Dan Date: Fri, 8 Dec 2023 13:52:18 +0200 Subject: [PATCH 09/22] [DOCS] DSL downsampling docs (#103148) --- .../lifecycle/apis/put-lifecycle.asciidoc | 36 +++++++++++++++++++ .../data-streams/lifecycle/index.asciidoc | 8 ++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/docs/reference/data-streams/lifecycle/apis/put-lifecycle.asciidoc b/docs/reference/data-streams/lifecycle/apis/put-lifecycle.asciidoc index 89b8bbeb880c3..53bd3c2b96f0b 100644 --- a/docs/reference/data-streams/lifecycle/apis/put-lifecycle.asciidoc +++ b/docs/reference/data-streams/lifecycle/apis/put-lifecycle.asciidoc @@ -59,6 +59,16 @@ duration the document could be deleted. When empty, every document in this data If defined, it turns data streqm lifecycle on/off (`true`/`false`) for this data stream. A data stream lifecycle that's disabled (`enabled: false`) will have no effect on the data stream. Defaults to `true`. + +`downsampling`:: +(Optional, array) +An optional array of downsampling configuration objects, each defining an `after` +interval representing when the backing index is meant to be downsampled (the time +frame is calculated since the index was rolled over, i.e. generation time) and +a `fixed_interval` representing the downsampling interval (the minimum `fixed_interval` +value is `5m`). A maximum number of 10 downsampling rounds can be configured. +See <> below. + ==== [[data-streams-put-lifecycle-example]] @@ -84,3 +94,29 @@ When the lifecycle is successfully updated in all data streams, you receive the "acknowledged": true } -------------------------------------------------- + +[[data-streams-put-lifecycle-downsampling-example]] +==== {api-examples-title} + +The following example configures two downsampling rounds, the first one starting +one day after the backing index is rolled over (or later, if the index is still +within its write-accepting <>) with an interval +of `10m`, and a second round starting 7 days after rollover at an interval of `1d`: + +[source,console] +-------------------------------------------------------------------- +PUT _data_stream/my-weather-sensor-data-stream/_lifecycle +{ + "downsampling": [ + { + "after": "1d", + "fixed_interval": "10m" + }, + { + "after": "7d", + "fixed_interval": "1d" + } + ] +} +-------------------------------------------------------------------- +//TEST[skip:downsampling requires waiting for indices to be out of time bounds] diff --git a/docs/reference/data-streams/lifecycle/index.asciidoc b/docs/reference/data-streams/lifecycle/index.asciidoc index 6c0220ef0a80f..ef5558817885e 100644 --- a/docs/reference/data-streams/lifecycle/index.asciidoc +++ b/docs/reference/data-streams/lifecycle/index.asciidoc @@ -18,6 +18,10 @@ and backwards incompatible mapping changes. * Configurable retention, which allows you to configure the time period for which your data is guaranteed to be stored. {es} is allowed at a later time to delete data older than this time period. +A data stream lifecycle also supports downsampling the data stream backing indices. +See <> for +more details. + [discrete] [[data-streams-lifecycle-how-it-works]] === How does it work? @@ -35,7 +39,9 @@ into tiers of exponential sizes, merging the long tail of small segments is only fraction of the cost of force mergeing to a single segment. The small segments would usually hold the most recent data so tail mergeing will focus the merging resources on the higher-value data that is most likely to keep being queried. -4. Applies retention to the remaining backing indices. This means deleting the backing indices whose +4. If <> is configured it will execute +all the configured downsampling rounds. +5. Applies retention to the remaining backing indices. This means deleting the backing indices whose `generation_time` is longer than the configured retention period. The `generation_time` is only applicable to rolled over backing indices and it is either the time since the backing index got rolled over, or the time optionally configured in the <> setting. From 5cf8b94f30037f7f4719be2bcd2bce45e513373d Mon Sep 17 00:00:00 2001 From: David Turner Date: Fri, 8 Dec 2023 12:56:05 +0000 Subject: [PATCH 10/22] Simplify CompositeRolesStore#getRoleDescriptors (#103126) This method has only one production caller, which asserts that the response always has length 1 and (if assertions are disabled) discards all but the first set of role descriptors in the response. We can push that behaviour down into the implementation simplifying things quite considerably and eliminating the allocation and copying needed to support other sizes of response. --- .../ApiKeyUserRoleDescriptorResolver.java | 10 ++---- .../authz/store/CompositeRolesStore.java | 35 ++++++------------- ...ApiKeyUserRoleDescriptorResolverTests.java | 11 +++--- .../authz/store/CompositeRolesStoreTests.java | 14 ++++---- 4 files changed, 24 insertions(+), 46 deletions(-) diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/ApiKeyUserRoleDescriptorResolver.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/ApiKeyUserRoleDescriptorResolver.java index 17c35ecca5f13..9c54f6decb0c8 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/ApiKeyUserRoleDescriptorResolver.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/ApiKeyUserRoleDescriptorResolver.java @@ -15,7 +15,6 @@ import org.elasticsearch.xpack.core.security.authz.support.DLSRoleQueryValidator; import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore; -import java.util.Collection; import java.util.Set; public class ApiKeyUserRoleDescriptorResolver { @@ -37,15 +36,10 @@ public void resolveUserRoleDescriptors(final Authentication authentication, fina return; } - rolesStore.getRoleDescriptorsList(effectiveSubject, listener.delegateFailureAndWrap(this::handleRoleDescriptorsList)); + rolesStore.getRoleDescriptors(effectiveSubject, listener.delegateFailureAndWrap(this::handleRoleDescriptors)); } - private void handleRoleDescriptorsList( - ActionListener> listener, - Collection> roleDescriptorsList - ) { - assert roleDescriptorsList.size() == 1; - final var roleDescriptors = roleDescriptorsList.iterator().next(); + private void handleRoleDescriptors(ActionListener> listener, Set roleDescriptors) { for (RoleDescriptor rd : roleDescriptors) { DLSRoleQueryValidator.validateQueryField(rd.getIndicesPrivileges(), xContentRegistry); } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStore.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStore.java index ab9ea8f772054..631a988b0f325 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStore.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStore.java @@ -10,7 +10,6 @@ import org.apache.logging.log4j.Logger; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.support.GroupedActionListener; import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.cache.Cache; @@ -349,30 +348,18 @@ private void buildThenMaybeCacheRole( ); } - public void getRoleDescriptorsList(Subject subject, ActionListener>> listener) { - tryGetRoleDescriptorForInternalUser(subject).ifPresentOrElse( - roleDescriptor -> listener.onResponse(List.of(Set.of(roleDescriptor))), - () -> { - final List roleReferences = subject.getRoleReferenceIntersection(anonymousUser).getRoleReferences(); - final GroupedActionListener> groupedActionListener = new GroupedActionListener<>( - roleReferences.size(), - listener - ); + public void getRoleDescriptors(Subject subject, ActionListener> listener) { + tryGetRoleDescriptorForInternalUser(subject).ifPresentOrElse(roleDescriptor -> listener.onResponse(Set.of(roleDescriptor)), () -> { + final List roleReferences = subject.getRoleReferenceIntersection(anonymousUser).getRoleReferences(); + assert roleReferences.size() == 1; // we only handle the singleton case today, but that may change with derived API keys - roleReferences.forEach( - roleReference -> roleReference.resolve( - roleReferenceResolver, - groupedActionListener.delegateFailureAndWrap((delegate, rolesRetrievalResult) -> { - if (rolesRetrievalResult.isSuccess()) { - delegate.onResponse(rolesRetrievalResult.getRoleDescriptors()); - } else { - delegate.onFailure(new ElasticsearchException("role retrieval had one or more failures")); - } - }) - ) - ); - } - ); + ActionListener.run(listener.map(rolesRetrievalResult -> { + if (rolesRetrievalResult.isSuccess() == false) { + throw new ElasticsearchException("role retrieval had one or more failures"); + } + return rolesRetrievalResult.getRoleDescriptors(); + }), l -> roleReferences.iterator().next().resolve(roleReferenceResolver, l)); + }); } // Package private for testing diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/ApiKeyUserRoleDescriptorResolverTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/ApiKeyUserRoleDescriptorResolverTests.java index 2af18f5dca7dc..502d2b7ce0dda 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/ApiKeyUserRoleDescriptorResolverTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/ApiKeyUserRoleDescriptorResolverTests.java @@ -19,8 +19,6 @@ import org.elasticsearch.xpack.core.security.user.User; import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore; -import java.util.Collection; -import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -56,11 +54,10 @@ public void testGetRoleDescriptors() { assertThat(subject.getType(), is(Subject.Type.USER)); assertThat(Set.of(subject.getUser().roles()), equalTo(userRoleNames)); - ActionListener>> listener = (ActionListener>>) args[args.length - - 1]; - listener.onResponse(List.of(roleDescriptors)); + ActionListener> listener = (ActionListener>) args[args.length - 1]; + listener.onResponse(roleDescriptors); return null; - }).when(rolesStore).getRoleDescriptorsList(any(Subject.class), any(ActionListener.class)); + }).when(rolesStore).getRoleDescriptors(any(Subject.class), any(ActionListener.class)); final PlainActionFuture> future = new PlainActionFuture<>(); resolver.resolveUserRoleDescriptors(authentication, future); @@ -77,6 +74,6 @@ public void testGetRoleDescriptorsEmptyForApiKey() { resolver.resolveUserRoleDescriptors(authentication, future); assertThat(future.actionGet(), equalTo(Set.of())); - verify(rolesStore, never()).getRoleDescriptorsList(any(), any()); + verify(rolesStore, never()).getRoleDescriptors(any(), any()); } } diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java index c0df3a0947c71..4ad7c61d45d63 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java @@ -2760,15 +2760,15 @@ public void testGetRoleDescriptorsListForInternalUsers() { when(subject.getUser()).thenReturn(InternalUsers.SYSTEM_USER); final IllegalArgumentException e1 = expectThrows( IllegalArgumentException.class, - () -> compositeRolesStore.getRoleDescriptorsList(subject, new PlainActionFuture<>()) + () -> compositeRolesStore.getRoleDescriptors(subject, ActionListener.noop()) ); assertThat(e1.getMessage(), equalTo("should never try to get the roles for internal user [" + SystemUser.NAME + "]")); for (var internalUser : AuthenticationTestHelper.internalUsersWithLocalRoleDescriptor()) { when(subject.getUser()).thenReturn(internalUser); - final PlainActionFuture>> future = new PlainActionFuture<>(); - compositeRolesStore.getRoleDescriptorsList(subject, future); - assertThat(future.actionGet(), equalTo(List.of(Set.of(internalUser.getLocalClusterRoleDescriptor().get())))); + final PlainActionFuture> future = new PlainActionFuture<>(); + compositeRolesStore.getRoleDescriptors(subject, future); + assertThat(future.actionGet(), equalTo(Set.of(internalUser.getLocalClusterRoleDescriptor().get()))); } } @@ -2787,9 +2787,9 @@ public void testGetRoleDescriptorsListUsesRoleStoreToResolveRoleWithInternalRole when(subject.getRoleReferenceIntersection(any())).thenReturn( new RoleReferenceIntersection(new RoleReference.NamedRoleReference(new String[] { roleName })) ); - final PlainActionFuture>> future = new PlainActionFuture<>(); - compositeRolesStore.getRoleDescriptorsList(subject, future); - assertThat(future.actionGet(), equalTo(List.of(Set.of(expectedRoleDescriptor)))); + final PlainActionFuture> future = new PlainActionFuture<>(); + compositeRolesStore.getRoleDescriptors(subject, future); + assertThat(future.actionGet(), equalTo(Set.of(expectedRoleDescriptor))); } private void getRoleForRoleNames(CompositeRolesStore rolesStore, Collection roleNames, ActionListener listener) { From 722853e2530e5c8b052cab77298955c959cfe00f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Witek?= Date: Fri, 8 Dec 2023 14:20:15 +0100 Subject: [PATCH 11/22] [Transform] Unmute TransformSchedulerTests.testScheduleNowWithSystemClock (#103191) --- .../transforms/scheduling/TransformSchedulerTests.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/transforms/scheduling/TransformSchedulerTests.java b/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/transforms/scheduling/TransformSchedulerTests.java index c6c6c2febfdad..7125b4074bc4a 100644 --- a/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/transforms/scheduling/TransformSchedulerTests.java +++ b/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/transforms/scheduling/TransformSchedulerTests.java @@ -327,7 +327,6 @@ public void testSchedulingWithSystemClock() throws Exception { transformScheduler.stop(); } - @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/95445") public void testScheduleNowWithSystemClock() throws Exception { String transformId = "test-schedule-now-with-system-clock"; TimeValue frequency = TimeValue.timeValueHours(1); // Very long pause between checkpoints @@ -343,7 +342,11 @@ public void testScheduleNowWithSystemClock() throws Exception { Thread.sleep(5 * 1000L); transformScheduler.scheduleNow(transformId); - assertThat(events, hasSize(2)); + // If we are unlucky, the scheduleNow call will trigger processing **exactly** in this small window of time in which processing is + // temporarily disallowed (as two concurrent invocations of the "TransformScheduler.processScheduledTasks" method are not allowed). + // Hence, we need to wait for the next processing cycle to happen (it will be TEST_SCHEDULER_FREQUENCY from now). + assertBusy(() -> assertThat(events, hasSize(2)), TEST_SCHEDULER_FREQUENCY.seconds() + 1, TimeUnit.SECONDS); + assertThat(events.get(0).transformId(), is(equalTo(transformId))); assertThat(events.get(1).transformId(), is(equalTo(transformId))); assertThat(events.get(1).scheduledTime() - events.get(0).triggeredTime(), is(allOf(greaterThan(4 * 1000L), lessThan(6 * 1000L)))); From 2e592a3416c23e841d530d789b4d5bddbb47814f Mon Sep 17 00:00:00 2001 From: David Turner Date: Fri, 8 Dec 2023 13:48:52 +0000 Subject: [PATCH 12/22] More logging for ClusterHealthRestCancellationIT (#103193) Relates #100062 --- .../org/elasticsearch/http/ClusterHealthRestCancellationIT.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/ClusterHealthRestCancellationIT.java b/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/ClusterHealthRestCancellationIT.java index f165f00c5cc2f..64dd20f1fdfc4 100644 --- a/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/ClusterHealthRestCancellationIT.java +++ b/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/ClusterHealthRestCancellationIT.java @@ -33,6 +33,8 @@ public class ClusterHealthRestCancellationIT extends HttpSmokeTestCase { @TestIssueLogging( issueUrl = "https://github.com/elastic/elasticsearch/issues/100062", value = "org.elasticsearch.test.TaskAssertions:TRACE" + + ",org.elasticsearch.cluster.service.MasterService:TRACE" + + ",org.elasticsearch.tasks.TaskManager:TRACE" ) public void testClusterHealthRestCancellation() throws Exception { From 6e0c031342e8e0c7f57eaa5d0baca0d601b3c9b5 Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Fri, 8 Dec 2023 09:24:34 -0500 Subject: [PATCH 13/22] ESQL: Generate railroad diagrams for operators (#103143) This enables the generation of railroad diagrams for unary minus and a bunch of binary operators like `+`, `-`, `%`, and `>=`. Relates to #100558 --- docs/reference/esql/functions/binary.asciidoc | 10 +- .../esql/functions/operators.asciidoc | 2 + .../esql/functions/signature/add.svg | 1 + .../esql/functions/signature/div.svg | 1 + .../esql/functions/signature/equals.svg | 1 + .../esql/functions/signature/greater_than.svg | 1 + .../esql/functions/signature/less_than.svg | 1 + .../esql/functions/signature/mod.svg | 1 + .../esql/functions/signature/mul.svg | 1 + .../esql/functions/signature/neg.svg | 1 + .../esql/functions/signature/not_equals.svg | 1 + .../esql/functions/signature/sub.svg | 1 + docs/reference/esql/functions/unary.asciidoc | 8 ++ .../function/AbstractFunctionTestCase.java | 129 ++++++++++++------ .../expression/function/RailRoadDiagram.java | 85 +++++++++--- 15 files changed, 186 insertions(+), 58 deletions(-) create mode 100644 docs/reference/esql/functions/signature/add.svg create mode 100644 docs/reference/esql/functions/signature/div.svg create mode 100644 docs/reference/esql/functions/signature/equals.svg create mode 100644 docs/reference/esql/functions/signature/greater_than.svg create mode 100644 docs/reference/esql/functions/signature/less_than.svg create mode 100644 docs/reference/esql/functions/signature/mod.svg create mode 100644 docs/reference/esql/functions/signature/mul.svg create mode 100644 docs/reference/esql/functions/signature/neg.svg create mode 100644 docs/reference/esql/functions/signature/not_equals.svg create mode 100644 docs/reference/esql/functions/signature/sub.svg create mode 100644 docs/reference/esql/functions/unary.asciidoc diff --git a/docs/reference/esql/functions/binary.asciidoc b/docs/reference/esql/functions/binary.asciidoc index ba93f57af7ad6..32e97b7316d84 100644 --- a/docs/reference/esql/functions/binary.asciidoc +++ b/docs/reference/esql/functions/binary.asciidoc @@ -9,4 +9,12 @@ These binary comparison operators are supported: * less than: `<` * less than or equal: `<=` * larger than: `>` -* larger than or equal: `>=` \ No newline at end of file +* larger than or equal: `>=` + +And these mathematical operators are supported: + +[.text-center] +image::esql/functions/signature/add.svg[Embedded,opts=inline] + +[.text-center] +image::esql/functions/signature/sub.svg[Embedded,opts=inline] diff --git a/docs/reference/esql/functions/operators.asciidoc b/docs/reference/esql/functions/operators.asciidoc index c236413b5dd7e..1c88fa200ca11 100644 --- a/docs/reference/esql/functions/operators.asciidoc +++ b/docs/reference/esql/functions/operators.asciidoc @@ -9,6 +9,7 @@ Boolean operators for comparing against one or multiple expressions. // tag::op_list[] * <> +* <> * <> * <> * <> @@ -23,6 +24,7 @@ Boolean operators for comparing against one or multiple expressions. // end::op_list[] include::binary.asciidoc[] +include::unary.asciidoc[] include::logical.asciidoc[] include::predicates.asciidoc[] include::cidr_match.asciidoc[] diff --git a/docs/reference/esql/functions/signature/add.svg b/docs/reference/esql/functions/signature/add.svg new file mode 100644 index 0000000000000..10d89efc65f3b --- /dev/null +++ b/docs/reference/esql/functions/signature/add.svg @@ -0,0 +1 @@ +lhs+rhs \ No newline at end of file diff --git a/docs/reference/esql/functions/signature/div.svg b/docs/reference/esql/functions/signature/div.svg new file mode 100644 index 0000000000000..ea061ae6ef625 --- /dev/null +++ b/docs/reference/esql/functions/signature/div.svg @@ -0,0 +1 @@ +lhs/rhs \ No newline at end of file diff --git a/docs/reference/esql/functions/signature/equals.svg b/docs/reference/esql/functions/signature/equals.svg new file mode 100644 index 0000000000000..ade4b1260128f --- /dev/null +++ b/docs/reference/esql/functions/signature/equals.svg @@ -0,0 +1 @@ +lhs==rhs \ No newline at end of file diff --git a/docs/reference/esql/functions/signature/greater_than.svg b/docs/reference/esql/functions/signature/greater_than.svg new file mode 100644 index 0000000000000..f5eb082d14642 --- /dev/null +++ b/docs/reference/esql/functions/signature/greater_than.svg @@ -0,0 +1 @@ +lhs>rhs \ No newline at end of file diff --git a/docs/reference/esql/functions/signature/less_than.svg b/docs/reference/esql/functions/signature/less_than.svg new file mode 100644 index 0000000000000..9858a17450f60 --- /dev/null +++ b/docs/reference/esql/functions/signature/less_than.svg @@ -0,0 +1 @@ +lhs<rhs \ No newline at end of file diff --git a/docs/reference/esql/functions/signature/mod.svg b/docs/reference/esql/functions/signature/mod.svg new file mode 100644 index 0000000000000..20a134a26f232 --- /dev/null +++ b/docs/reference/esql/functions/signature/mod.svg @@ -0,0 +1 @@ +lhs%rhs \ No newline at end of file diff --git a/docs/reference/esql/functions/signature/mul.svg b/docs/reference/esql/functions/signature/mul.svg new file mode 100644 index 0000000000000..b15c488eb874b --- /dev/null +++ b/docs/reference/esql/functions/signature/mul.svg @@ -0,0 +1 @@ +lhs*rhs \ No newline at end of file diff --git a/docs/reference/esql/functions/signature/neg.svg b/docs/reference/esql/functions/signature/neg.svg new file mode 100644 index 0000000000000..6090a85310684 --- /dev/null +++ b/docs/reference/esql/functions/signature/neg.svg @@ -0,0 +1 @@ +-v \ No newline at end of file diff --git a/docs/reference/esql/functions/signature/not_equals.svg b/docs/reference/esql/functions/signature/not_equals.svg new file mode 100644 index 0000000000000..d4808abbac5a5 --- /dev/null +++ b/docs/reference/esql/functions/signature/not_equals.svg @@ -0,0 +1 @@ +lhs!=rhs \ No newline at end of file diff --git a/docs/reference/esql/functions/signature/sub.svg b/docs/reference/esql/functions/signature/sub.svg new file mode 100644 index 0000000000000..8d49ad6b0ac1e --- /dev/null +++ b/docs/reference/esql/functions/signature/sub.svg @@ -0,0 +1 @@ +lhs-rhs \ No newline at end of file diff --git a/docs/reference/esql/functions/unary.asciidoc b/docs/reference/esql/functions/unary.asciidoc new file mode 100644 index 0000000000000..2ee35b6c6256f --- /dev/null +++ b/docs/reference/esql/functions/unary.asciidoc @@ -0,0 +1,8 @@ +[discrete] +[[esql-unary-operators]] +=== Unary operators + +These unary mathematical operators are supported: + +[.text-center] +image::esql/functions/signature/neg.svg[Embedded,opts=inline] diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractFunctionTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractFunctionTestCase.java index 3bac4f1c4b5c0..8b4a126d8a0c7 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractFunctionTestCase.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractFunctionTestCase.java @@ -36,6 +36,7 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.conditional.Greatest; import org.elasticsearch.xpack.esql.expression.function.scalar.nulls.Coalesce; import org.elasticsearch.xpack.esql.optimizer.FoldNull; +import org.elasticsearch.xpack.esql.parser.ExpressionBuilder; import org.elasticsearch.xpack.esql.planner.Layout; import org.elasticsearch.xpack.esql.planner.PlannerUtils; import org.elasticsearch.xpack.esql.type.EsqlDataTypes; @@ -158,8 +159,9 @@ protected static Expression deepCopyOfField(String name, DataType type) { /** * Build the expression being tested, for the given source and list of arguments. Test classes need to implement this * to have something to test. + * * @param source the source - * @param args arg list from the test case, should match the length expected + * @param args arg list from the test case, should match the length expected * @return an expression for evaluating the function being tested on the given arguments */ protected abstract Expression build(Source source, List args); @@ -256,8 +258,8 @@ private void testEvaluate(boolean readFloating) { /** * Evaluates a {@link Block} of values, all copied from the input pattern, read directly from the page. *

- * Note that this'll sometimes be a {@link Vector} of values if the - * input pattern contained only a single value. + * Note that this'll sometimes be a {@link Vector} of values if the + * input pattern contained only a single value. *

*/ public final void testEvaluateBlockWithoutNulls() { @@ -267,8 +269,8 @@ public final void testEvaluateBlockWithoutNulls() { /** * Evaluates a {@link Block} of values, all copied from the input pattern, read from an intermediate operator. *

- * Note that this'll sometimes be a {@link Vector} of values if the - * input pattern contained only a single value. + * Note that this'll sometimes be a {@link Vector} of values if the + * input pattern contained only a single value. *

*/ public final void testEvaluateBlockWithoutNullsFloating() { @@ -296,8 +298,8 @@ public final void testEvaluateBlockWithNullsFloating() { * read directly from the {@link Page}, using the * {@link CrankyCircuitBreakerService} which fails randomly. *

- * Note that this'll sometimes be a {@link Vector} of values if the - * input pattern contained only a single value. + * Note that this'll sometimes be a {@link Vector} of values if the + * input pattern contained only a single value. *

*/ public final void testCrankyEvaluateBlockWithoutNulls() { @@ -314,8 +316,8 @@ public final void testCrankyEvaluateBlockWithoutNulls() { * read from an intermediate operator, using the * {@link CrankyCircuitBreakerService} which fails randomly. *

- * Note that this'll sometimes be a {@link Vector} of values if the - * input pattern contained only a single value. + * Note that this'll sometimes be a {@link Vector} of values if the + * input pattern contained only a single value. *

*/ public final void testCrankyEvaluateBlockWithoutNullsFloating() { @@ -544,7 +546,7 @@ public static void testFunctionInfo() { LogManager.getLogger(getTestClass()).info("Skipping function info checks because we're running a portion of the tests"); return; } - FunctionDefinition definition = definition(); + FunctionDefinition definition = definition(functionName()); if (definition == null) { LogManager.getLogger(getTestClass()).info("Skipping function info checks because the function isn't registered"); return; @@ -588,14 +590,15 @@ public static void testFunctionInfo() { /** * Adds cases with {@code null} and asserts that the result is {@code null}. *

- * Note: This won't add more than a single null to any existing test case, - * just to keep the number of test cases from exploding totally. + * Note: This won't add more than a single null to any existing test case, + * just to keep the number of test cases from exploding totally. *

- * @param entirelyNullPreservesType should a test case that only contains parameters - * with the {@code null} type keep it's expected type? - * This is mostly going to be {@code true} - * except for functions that base their type entirely - * on input types like {@link Greatest} or {@link Coalesce}. + * + * @param entirelyNullPreservesType should a test case that only contains parameters + * with the {@code null} type keep it's expected type? + * This is mostly going to be {@code true} + * except for functions that base their type entirely + * on input types like {@link Greatest} or {@link Coalesce}. */ protected static List anyNullIsNull(boolean entirelyNullPreservesType, List testCaseSuppliers) { typesRequired(testCaseSuppliers); @@ -691,8 +694,7 @@ protected static List errorsForCasesWithoutExamples(List, cases will function the same as , * cases. - */ - .filter(types -> types.stream().filter(t -> t == DataTypes.NULL).count() <= 1) + */.filter(types -> types.stream().filter(t -> t == DataTypes.NULL).count() <= 1) .map(types -> typeErrorSupplier(validPerPosition.size() != 1, validPerPosition, types)) .forEach(suppliers::add); return suppliers; @@ -911,30 +913,44 @@ public static void renderSignature() throws IOException { LogManager.getLogger(getTestClass()).info("Skipping rendering signature because we're running a portion of the tests"); return; } - FunctionDefinition definition = definition(); - if (definition == null) { + String rendered = buildSignatureSvg(functionName()); + if (rendered == null) { LogManager.getLogger(getTestClass()).info("Skipping rendering signature because the function isn't registered"); - return; + } else { + LogManager.getLogger(getTestClass()).info("Writing function signature"); + writeToTempDir("signature", rendered, "svg"); } + } - String rendered = RailRoadDiagram.functionSignature(definition); - LogManager.getLogger(getTestClass()).info("Writing function signature"); - writeToTempDir("signature", rendered, "svg"); + private static String buildSignatureSvg(String name) throws IOException { + String binaryOperator = binaryOperator(name); + if (binaryOperator != null) { + return RailRoadDiagram.binaryOperator(binaryOperator); + } + String unaryOperator = unaryOperator(name); + if (unaryOperator != null) { + return RailRoadDiagram.unaryOperator(unaryOperator); + } + FunctionDefinition definition = definition(name); + if (definition != null) { + return RailRoadDiagram.functionSignature(definition); + } + return null; } /** * Unique signatures encountered by this test. *

- * We clear this at the beginning of the test class with - * {@link #clearSignatures} out of paranoia. It is - * shared by many tests, after all. + * We clear this at the beginning of the test class with + * {@link #clearSignatures} out of paranoia. It is + * shared by many tests, after all. *

*

- * After each test method we add the signature it operated on via - * {@link #trackSignature}. Once the test class is done we render - * all the unique signatures to a temp file with {@link #renderTypesTable}. - * We use a temp file because that's all we're allowed to write to. - * Gradle will move the files into the docs after this is done. + * After each test method we add the signature it operated on via + * {@link #trackSignature}. Once the test class is done we render + * all the unique signatures to a temp file with {@link #renderTypesTable}. + * We use a temp file because that's all we're allowed to write to. + * Gradle will move the files into the docs after this is done. *

*/ private static final Map, DataType> signatures = new HashMap<>(); @@ -960,7 +976,8 @@ public static void renderTypesTable() throws IOException { if (System.getProperty("generateDocs") == null) { return; } - FunctionDefinition definition = definition(); + String name = functionName(); // TODO types table for operators + FunctionDefinition definition = definition(name); if (definition == null) { LogManager.getLogger(getTestClass()).info("Skipping rendering types because the function isn't registered"); return; @@ -995,8 +1012,11 @@ public static void renderTypesTable() throws IOException { writeToTempDir("types", rendered, "asciidoc"); } - private static FunctionDefinition definition() { - String name = functionName(); + private static String functionName() { + return StringUtils.camelCaseToUnderscore(getTestClass().getSimpleName().replace("Tests", "")).toLowerCase(Locale.ROOT); + } + + private static FunctionDefinition definition(String name) { EsqlFunctionRegistry registry = new EsqlFunctionRegistry(); if (registry.functionExists(name)) { return registry.resolveFunction(name); @@ -1004,15 +1024,44 @@ private static FunctionDefinition definition() { return null; } - private static String functionName() { - return StringUtils.camelCaseToUnderscore(getTestClass().getSimpleName().replace("Tests", "")).toLowerCase(Locale.ROOT); + /** + * If this test is a for a binary operator return its symbol, otherwise return {@code null}. + * This is functionally the reverse of the combination of + * {@link ExpressionBuilder#visitArithmeticBinary} and {@link ExpressionBuilder#visitComparison}. + */ + private static String binaryOperator(String name) { + return switch (name) { + case "add" -> "+"; + case "div" -> "/"; + case "equals" -> "=="; + case "greater_than" -> ">"; + case "greater_than_or_equal_to" -> ">="; + case "less_than" -> "<"; + case "less_than_or_equal_to" -> "<="; + case "mod" -> "%"; + case "mul" -> "*"; + case "not_equals" -> "!="; + case "sub" -> "-"; + default -> null; + }; + } + + /** + * If this tests is for a unary operator return its symbol, otherwise return {@code null}. + * This is functionally the reverse of {@link ExpressionBuilder#visitArithmeticUnary}. + */ + private static String unaryOperator(String name) { + return switch (name) { + case "neg" -> "-"; + default -> null; + }; } /** * Write some text to a tempdir so we can copy it to the docs later. *

- * We need to write to a tempdir instead of the docs because the tests - * don't have write permission to the docs. + * We need to write to a tempdir instead of the docs because the tests + * don't have write permission to the docs. *

*/ private static void writeToTempDir(String subdir, String str, String extension) throws IOException { diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/RailRoadDiagram.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/RailRoadDiagram.java index 65977ea6a174f..d6501568a85ec 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/RailRoadDiagram.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/RailRoadDiagram.java @@ -42,6 +42,10 @@ public class RailRoadDiagram { */ private static final LazyInitializable FONT = new LazyInitializable<>(() -> loadFont().deriveFont(20.0F)); + /** + * Generate a railroad diagram for a function. The output would look like + * {@code FOO(a, b, c)}. + */ static String functionSignature(FunctionDefinition definition) throws IOException { List expressions = new ArrayList<>(); expressions.add(new SpecialSequence(definition.name().toUpperCase(Locale.ROOT))); @@ -61,10 +65,34 @@ static String functionSignature(FunctionDefinition definition) throws IOExceptio } } expressions.add(new Syntax(")")); - net.nextencia.rrdiagram.grammar.model.Expression rr = new Sequence( - expressions.toArray(net.nextencia.rrdiagram.grammar.model.Expression[]::new) - ); - RRDiagram rrDiagram = new GrammarToRRDiagram().convert(new Rule("test", rr)); + return toSvg(new Sequence(expressions.toArray(Expression[]::new))); + } + + /** + * Generate a railroad diagram for binary operator. The output would look like + * {@code lhs + rhs}. + */ + static String binaryOperator(String operator) throws IOException { + List expressions = new ArrayList<>(); + expressions.add(new Literal("lhs")); + expressions.add(new Syntax(operator)); + expressions.add(new Literal("rhs")); + return toSvg(new Sequence(expressions.toArray(Expression[]::new))); + } + + /** + * Generate a railroad diagram for unary operator. The output would look like + * {@code -v}. + */ + static String unaryOperator(String operator) throws IOException { + List expressions = new ArrayList<>(); + expressions.add(new Syntax(operator)); + expressions.add(new Literal("v")); + return toSvg(new Sequence(expressions.toArray(Expression[]::new))); + } + + private static String toSvg(Expression exp) throws IOException { + RRDiagram rrDiagram = new GrammarToRRDiagram().convert(new Rule("", exp)); RRDiagramToSVG toSvg = new RRDiagramToSVG(); toSvg.setSpecialSequenceShape(RRDiagramToSVG.BoxShape.RECTANGLE); @@ -74,20 +102,29 @@ static String functionSignature(FunctionDefinition definition) throws IOExceptio toSvg.setLiteralFont(FONT.getOrCompute()); toSvg.setRuleFont(FONT.getOrCompute()); - /* - * "Tighten" the styles in the SVG so they beat the styles sitting in the - * main page. We need this because we're embedding the SVG into the page. - * We need to embed the SVG into the page so it can get fonts loaded in the - * primary stylesheet. We need to load a font so they images are consistent - * on all clients. - */ - return toSvg.convert(rrDiagram).replace(".c", "#guide .c").replace(".k", "#guide .k").replace(".s", "#guide .s"); + return tightenStyles(toSvg.convert(rrDiagram)); + } + + /** + * "Tighten" the styles in the SVG so they beat the styles sitting in the + * main page. We need this because we're embedding the SVG into the page. + * We need to embed the SVG into the page so it can get fonts loaded in the + * primary stylesheet. We need to load a font so they images are consistent + * on all clients. + */ + private static String tightenStyles(String svg) { + for (String c : new String[] { "c", "k", "s", "j", "l" }) { + svg = svg.replace("." + c, "#guide ." + c); + } + return svg; } /** * Like a literal but with light grey text for a more muted appearance for syntax. */ private static class Syntax extends Literal { + private static final String LITERAL_CLASS = "l"; + private static final String SYNTAX_CLASS = "lsyn"; private static final String LITERAL_TEXT_CLASS = "j"; private static final String SYNTAX_TEXT_CLASS = "syn"; private static final String SYNTAX_GREY = "8D8D8D"; @@ -101,13 +138,20 @@ private Syntax(String text) { @Override protected RRElement toRRElement(GrammarToRRDiagram grammarToRRDiagram) { - // This performs a monumentally rude hack to replace the text color of this element. + /* + * This performs a monumentally rude hack to replace the text color of this element. + * It renders a "literal" element but intercepts the layer that defines it's css class + * and replaces it with our own. + */ return new RRText(RRText.Type.LITERAL, text, null) { @Override protected void toSVG(RRDiagramToSVG rrDiagramToSVG, int xOffset, int yOffset, RRDiagram.SvgContent svgContent) { super.toSVG(rrDiagramToSVG, xOffset, yOffset, new RRDiagram.SvgContent() { @Override public String getDefinedCSSClass(String style) { + if (style.equals(LITERAL_CLASS)) { + return svgContent.getDefinedCSSClass(SYNTAX_CLASS); + } if (style.equals(LITERAL_TEXT_CLASS)) { return svgContent.getDefinedCSSClass(SYNTAX_TEXT_CLASS); } @@ -116,11 +160,18 @@ public String getDefinedCSSClass(String style) { @Override public String setCSSClass(String cssClass, String definition) { - if (false == cssClass.equals(LITERAL_TEXT_CLASS)) { - return svgContent.setCSSClass(cssClass, definition); + if (cssClass.equals(LITERAL_CLASS)) { + svgContent.setCSSClass(cssClass, definition); + return svgContent.setCSSClass(SYNTAX_CLASS, definition); + } + if (cssClass.equals(LITERAL_TEXT_CLASS)) { + svgContent.setCSSClass(cssClass, definition); + return svgContent.setCSSClass( + SYNTAX_TEXT_CLASS, + definition.replace("fill:#000000", "fill:#" + SYNTAX_GREY) + ); } - svgContent.setCSSClass(cssClass, definition); - return svgContent.setCSSClass(SYNTAX_TEXT_CLASS, definition.replace("fill:#000000", "fill:#" + SYNTAX_GREY)); + return svgContent.setCSSClass(cssClass, definition); } @Override From de70fcd4e4b48dd611f33a2c1e13b81cd8a6abf9 Mon Sep 17 00:00:00 2001 From: Andrei Dan Date: Fri, 8 Dec 2023 16:53:28 +0200 Subject: [PATCH 14/22] Create a DSL health indicator as part of the health API (#103130) This adds a health indicator named `data_stream_lifecycle` that will detect data stream backing indices that cannot make progress (stagnating) due to repeatedly error-ing in their lifecycle execution. The output of the indicator looks like this: ``` "data_stream_lifecycle" : { "status" : "yellow", "symptom" : "2 backing indices have repeatedly encountered errors whilst trying to advance in its lifecycle", "details" : { "stagnating_backing_indices_count" : 2, "stagnating_backing_indices" : [ { "index_name" : ".ds-metrics-foo-2023.12.07-000002", "first_occurrence_timestamp" : 1701951305340, "retry_count" : 4 }, { "index_name" : ".ds-metrics-foo-2023.12.07-000001", "first_occurrence_timestamp" : 1701951305340, "retry_count" : 4 } ], "total_backing_indices_in_error" : 2 }, "impacts" : [ { "id" : "elasticsearch:health:dsl:impact:stagnating_backing_index", "severity" : 3, "description" : "Data streams backing indices cannot make progress in their lifecycle. The performance and stability of the indices and/or the cluster could be impacted.", "impact_areas" : [ "deployment_management" ] } ], "diagnosis" : [ { "id" : "elasticsearch:health:dsl:diagnosis:stagnating_dsl_backing_index", "cause" : "Some backing indices are repeatedly encountering errors in their lifecycle execution.", "action" : "Check the current status of the affected indices using the [GET //_lifecycle/explain] API. Please replace the in the API with the actual index name (or the data stream name for a wider overview).", "help_url" : "https://ela.st/dsl-explain", "affected_resources" : { "indices" : [ ".ds-metrics-foo-2023.12.07-000002", ".ds-metrics-foo-2023.12.07-000001" ] } } ] } ``` Documentation will follow in a subsequent PR. --- docs/changelog/103130.yaml | 5 + .../DataStreamLifecycleServiceIT.java | 76 +++++++++++ .../datastreams/DataStreamsPlugin.java | 13 +- ...StreamLifecycleHealthIndicatorService.java | 125 ++++++++++++++++++ ...mLifecycleHealthIndicatorServiceTests.java | 102 ++++++++++++++ 5 files changed, 320 insertions(+), 1 deletion(-) create mode 100644 docs/changelog/103130.yaml create mode 100644 modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/health/DataStreamLifecycleHealthIndicatorService.java create mode 100644 modules/data-streams/src/test/java/org/elasticsearch/datastreams/lifecycle/health/DataStreamLifecycleHealthIndicatorServiceTests.java diff --git a/docs/changelog/103130.yaml b/docs/changelog/103130.yaml new file mode 100644 index 0000000000000..3ef56ae84d123 --- /dev/null +++ b/docs/changelog/103130.yaml @@ -0,0 +1,5 @@ +pr: 103130 +summary: Create a DSL health indicator as part of the health API +area: Health +type: feature +issues: [] diff --git a/modules/data-streams/src/internalClusterTest/java/org/elasticsearch/datastreams/lifecycle/DataStreamLifecycleServiceIT.java b/modules/data-streams/src/internalClusterTest/java/org/elasticsearch/datastreams/lifecycle/DataStreamLifecycleServiceIT.java index d3eaee36f67f7..03bd753e29068 100644 --- a/modules/data-streams/src/internalClusterTest/java/org/elasticsearch/datastreams/lifecycle/DataStreamLifecycleServiceIT.java +++ b/modules/data-streams/src/internalClusterTest/java/org/elasticsearch/datastreams/lifecycle/DataStreamLifecycleServiceIT.java @@ -30,6 +30,7 @@ import org.elasticsearch.action.datastreams.lifecycle.ErrorEntry; import org.elasticsearch.action.datastreams.lifecycle.ExplainIndexDataStreamLifecycle; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.cluster.coordination.StableMasterHealthIndicatorService; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; import org.elasticsearch.cluster.metadata.DataStream; import org.elasticsearch.cluster.metadata.DataStreamAction; @@ -46,6 +47,11 @@ import org.elasticsearch.datastreams.DataStreamsPlugin; import org.elasticsearch.datastreams.lifecycle.action.ExplainDataStreamLifecycleAction; import org.elasticsearch.datastreams.lifecycle.action.PutDataStreamLifecycleAction; +import org.elasticsearch.datastreams.lifecycle.health.DataStreamLifecycleHealthIndicatorService; +import org.elasticsearch.health.Diagnosis; +import org.elasticsearch.health.GetHealthAction; +import org.elasticsearch.health.HealthIndicatorResult; +import org.elasticsearch.health.HealthStatus; import org.elasticsearch.health.node.DataStreamLifecycleHealthInfo; import org.elasticsearch.health.node.DslErrorInfo; import org.elasticsearch.health.node.FetchHealthInfoCacheAction; @@ -76,9 +82,12 @@ import static org.elasticsearch.datastreams.lifecycle.DataStreamLifecycleService.DATA_STREAM_MERGE_POLICY_TARGET_FLOOR_SEGMENT_SETTING; import static org.elasticsearch.datastreams.lifecycle.DataStreamLifecycleService.ONE_HUNDRED_MB; import static org.elasticsearch.datastreams.lifecycle.DataStreamLifecycleService.TARGET_MERGE_FACTOR_VALUE; +import static org.elasticsearch.datastreams.lifecycle.health.DataStreamLifecycleHealthIndicatorService.STAGNATING_BACKING_INDICES_DIAGNOSIS_DEF; +import static org.elasticsearch.datastreams.lifecycle.health.DataStreamLifecycleHealthIndicatorService.STAGNATING_INDEX_IMPACT; import static org.elasticsearch.index.IndexSettings.LIFECYCLE_ORIGINATION_DATE; import static org.elasticsearch.indices.ShardLimitValidator.SETTING_CLUSTER_MAX_SHARDS_PER_NODE; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThanOrEqualTo; @@ -447,6 +456,27 @@ public void testErrorRecordingOnRollover() throws Exception { assertThat(errorInfo.retryCount(), greaterThanOrEqualTo(3)); }); + GetHealthAction.Response healthResponse = client().execute(GetHealthAction.INSTANCE, new GetHealthAction.Request(true, 1000)) + .actionGet(); + HealthIndicatorResult masterIsStableIndicator = healthResponse.findIndicator(StableMasterHealthIndicatorService.NAME); + // if the cluster doesn't have a stable master we'll avoid asserting on the health report API as some indicators will not + // be computed + if (masterIsStableIndicator.status() == HealthStatus.GREEN) { + // the shards capacity indicator is dictating the overall status + assertThat(healthResponse.getStatus(), is(HealthStatus.RED)); + HealthIndicatorResult dslIndicator = healthResponse.findIndicator(DataStreamLifecycleHealthIndicatorService.NAME); + assertThat(dslIndicator.status(), is(HealthStatus.YELLOW)); + assertThat(dslIndicator.impacts(), is(STAGNATING_INDEX_IMPACT)); + assertThat( + dslIndicator.symptom(), + is("A backing index has repeatedly encountered errors whilst trying to advance in its lifecycle") + ); + + Diagnosis diagnosis = dslIndicator.diagnosisList().get(0); + assertThat(diagnosis.definition(), is(STAGNATING_BACKING_INDICES_DIAGNOSIS_DEF)); + assertThat(diagnosis.affectedResources().get(0).getValues(), containsInAnyOrder(writeIndexName)); + } + // let's reset the cluster max shards per node limit to allow rollover to proceed and check the error store is empty updateClusterSettings(Settings.builder().putNull("*")); @@ -476,6 +506,14 @@ public void testErrorRecordingOnRollover() throws Exception { DataStreamLifecycleHealthInfo dslHealthInfoOnHealthNode = healthNodeResponse.getHealthInfo().dslHealthInfo(); assertThat(dslHealthInfoOnHealthNode, is(DataStreamLifecycleHealthInfo.NO_DSL_ERRORS)); }); + + healthResponse = client().execute(GetHealthAction.INSTANCE, new GetHealthAction.Request(true, 1000)).actionGet(); + masterIsStableIndicator = healthResponse.findIndicator(StableMasterHealthIndicatorService.NAME); + // if the cluster doesn't have a stable master we'll avoid asserting on the health report API as some indicators will not + // be computed + if (masterIsStableIndicator.status() == HealthStatus.GREEN) { + assertThat(healthResponse.getStatus(), is(HealthStatus.GREEN)); + } } public void testErrorRecordingOnRetention() throws Exception { @@ -569,6 +607,30 @@ public void testErrorRecordingOnRetention() throws Exception { assertThat(List.of(firstGenerationIndex, secondGenerationIndex).contains(errorInfo.indexName()), is(true)); }); + GetHealthAction.Response healthResponse = client().execute(GetHealthAction.INSTANCE, new GetHealthAction.Request(true, 1000)) + .actionGet(); + HealthIndicatorResult masterIsStableIndicator = healthResponse.findIndicator(StableMasterHealthIndicatorService.NAME); + // if the cluster doesn't have a stable master we'll avoid asserting on the health report API as some indicators will not + // be computed + if (masterIsStableIndicator.status() == HealthStatus.GREEN) { + // the dsl indicator should turn the overall status yellow + assertThat(healthResponse.getStatus(), is(HealthStatus.YELLOW)); + HealthIndicatorResult dslIndicator = healthResponse.findIndicator(DataStreamLifecycleHealthIndicatorService.NAME); + assertThat(dslIndicator.status(), is(HealthStatus.YELLOW)); + assertThat(dslIndicator.impacts(), is(STAGNATING_INDEX_IMPACT)); + assertThat( + dslIndicator.symptom(), + is("2 backing indices have repeatedly encountered errors whilst trying to advance in its lifecycle") + ); + + Diagnosis diagnosis = dslIndicator.diagnosisList().get(0); + assertThat(diagnosis.definition(), is(STAGNATING_BACKING_INDICES_DIAGNOSIS_DEF)); + assertThat( + diagnosis.affectedResources().get(0).getValues(), + containsInAnyOrder(firstGenerationIndex, secondGenerationIndex) + ); + } + // let's mark the index as writeable and make sure it's deleted and the error store is empty updateIndexSettings(Settings.builder().put(READ_ONLY.settingName(), false), firstGenerationIndex); @@ -598,6 +660,20 @@ public void testErrorRecordingOnRetention() throws Exception { DataStreamLifecycleHealthInfo dslHealthInfoOnHealthNode = healthNodeResponse.getHealthInfo().dslHealthInfo(); assertThat(dslHealthInfoOnHealthNode, is(DataStreamLifecycleHealthInfo.NO_DSL_ERRORS)); }); + + healthResponse = client().execute(GetHealthAction.INSTANCE, new GetHealthAction.Request(true, 1000)).actionGet(); + masterIsStableIndicator = healthResponse.findIndicator(StableMasterHealthIndicatorService.NAME); + // if the cluster doesn't have a stable master we'll avoid asserting on the health report API as some indicators will not + // be computed + if (masterIsStableIndicator.status() == HealthStatus.GREEN) { + // the dsl indicator should turn the overall status yellow + assertThat(healthResponse.getStatus(), is(HealthStatus.GREEN)); + HealthIndicatorResult dslIndicator = healthResponse.findIndicator(DataStreamLifecycleHealthIndicatorService.NAME); + assertThat(dslIndicator.status(), is(HealthStatus.GREEN)); + assertThat(dslIndicator.impacts().size(), is(0)); + assertThat(dslIndicator.symptom(), is("Data streams are executing their lifecycles without issues")); + assertThat(dslIndicator.diagnosisList().size(), is(0)); + } } finally { // when the test executes successfully this will not be needed however, otherwise we need to make sure the index is // "delete-able" for test cleanup diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/DataStreamsPlugin.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/DataStreamsPlugin.java index 9ac3a1afed5a5..fb93b7d688a74 100644 --- a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/DataStreamsPlugin.java +++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/DataStreamsPlugin.java @@ -47,6 +47,7 @@ import org.elasticsearch.datastreams.lifecycle.action.TransportGetDataStreamLifecycleAction; import org.elasticsearch.datastreams.lifecycle.action.TransportGetDataStreamLifecycleStatsAction; import org.elasticsearch.datastreams.lifecycle.action.TransportPutDataStreamLifecycleAction; +import org.elasticsearch.datastreams.lifecycle.health.DataStreamLifecycleHealthIndicatorService; import org.elasticsearch.datastreams.lifecycle.health.DataStreamLifecycleHealthInfoPublisher; import org.elasticsearch.datastreams.lifecycle.rest.RestDataStreamLifecycleStatsAction; import org.elasticsearch.datastreams.lifecycle.rest.RestDeleteDataStreamLifecycleAction; @@ -60,8 +61,10 @@ import org.elasticsearch.datastreams.rest.RestMigrateToDataStreamAction; import org.elasticsearch.datastreams.rest.RestModifyDataStreamsAction; import org.elasticsearch.datastreams.rest.RestPromoteDataStreamAction; +import org.elasticsearch.health.HealthIndicatorService; import org.elasticsearch.index.IndexSettingProvider; import org.elasticsearch.plugins.ActionPlugin; +import org.elasticsearch.plugins.HealthPlugin; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestHandler; @@ -76,7 +79,7 @@ import static org.elasticsearch.cluster.metadata.DataStreamLifecycle.DATA_STREAM_LIFECYCLE_ORIGIN; -public class DataStreamsPlugin extends Plugin implements ActionPlugin { +public class DataStreamsPlugin extends Plugin implements ActionPlugin, HealthPlugin { public static final Setting TIME_SERIES_POLL_INTERVAL = Setting.timeSetting( "time_series.poll_interval", @@ -112,6 +115,7 @@ public class DataStreamsPlugin extends Plugin implements ActionPlugin { private final SetOnce dataLifecycleInitialisationService = new SetOnce<>(); private final SetOnce dataStreamLifecycleErrorsPublisher = new SetOnce<>(); + private final SetOnce dataStreamLifecycleHealthIndicatorService = new SetOnce<>(); private final Settings settings; public DataStreamsPlugin(Settings settings) { @@ -184,6 +188,8 @@ public Collection createComponents(PluginServices services) { ) ); dataLifecycleInitialisationService.get().init(); + dataStreamLifecycleHealthIndicatorService.set(new DataStreamLifecycleHealthIndicatorService()); + components.add(errorStoreInitialisationService.get()); components.add(dataLifecycleInitialisationService.get()); components.add(dataStreamLifecycleErrorsPublisher.get()); @@ -251,4 +257,9 @@ public void close() throws IOException { throw new ElasticsearchException("unable to close the data stream lifecycle service", e); } } + + @Override + public Collection getHealthIndicatorServices() { + return List.of(dataStreamLifecycleHealthIndicatorService.get()); + } } diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/health/DataStreamLifecycleHealthIndicatorService.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/health/DataStreamLifecycleHealthIndicatorService.java new file mode 100644 index 0000000000000..0628bed0f9019 --- /dev/null +++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/health/DataStreamLifecycleHealthIndicatorService.java @@ -0,0 +1,125 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.datastreams.lifecycle.health; + +import org.elasticsearch.health.Diagnosis; +import org.elasticsearch.health.HealthIndicatorDetails; +import org.elasticsearch.health.HealthIndicatorImpact; +import org.elasticsearch.health.HealthIndicatorResult; +import org.elasticsearch.health.HealthIndicatorService; +import org.elasticsearch.health.HealthStatus; +import org.elasticsearch.health.ImpactArea; +import org.elasticsearch.health.SimpleHealthIndicatorDetails; +import org.elasticsearch.health.node.DataStreamLifecycleHealthInfo; +import org.elasticsearch.health.node.DslErrorInfo; +import org.elasticsearch.health.node.HealthInfo; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; + +import static java.util.stream.Collectors.toList; + +public class DataStreamLifecycleHealthIndicatorService implements HealthIndicatorService { + + public static final String NAME = "data_stream_lifecycle"; + public static final String DSL_EXPLAIN_HELP_URL = "https://ela.st/explain-data-stream-lifecycle"; + + public static final String STAGNATING_BACKING_INDEX_IMPACT_ID = "stagnating_backing_index"; + + public static final List STAGNATING_INDEX_IMPACT = List.of( + new HealthIndicatorImpact( + NAME, + STAGNATING_BACKING_INDEX_IMPACT_ID, + 3, + "Data streams backing indices cannot make progress in their lifecycle. The performance and " + + "stability of the indices and/or the cluster could be impacted.", + List.of(ImpactArea.DEPLOYMENT_MANAGEMENT) + ) + ); + + public static final Diagnosis.Definition STAGNATING_BACKING_INDICES_DIAGNOSIS_DEF = new Diagnosis.Definition( + NAME, + "stagnating_dsl_backing_index", + "Some backing indices are repeatedly encountering errors in their lifecycle execution.", + "Check the current status of the affected indices using the [GET //_lifecycle/explain] API. Please " + + "replace the in the API with the actual index name (or the data stream name for a wider overview).", + DSL_EXPLAIN_HELP_URL + ); + + @Override + public String name() { + return NAME; + } + + @Override + public HealthIndicatorResult calculate(boolean verbose, int maxAffectedResourcesCount, HealthInfo healthInfo) { + DataStreamLifecycleHealthInfo dataStreamLifecycleHealthInfo = healthInfo.dslHealthInfo(); + if (dataStreamLifecycleHealthInfo == null) { + // DSL reports health information on every run, so data will eventually arrive to the health node. In the meantime, let's + // report UNKNOWN health + return createIndicator( + HealthStatus.GREEN, + "No data stream lifecycle health data available yet. Health information will be reported after the first run.", + HealthIndicatorDetails.EMPTY, + List.of(), + List.of() + ); + } + + List stagnatingBackingIndices = dataStreamLifecycleHealthInfo.dslErrorsInfo(); + if (stagnatingBackingIndices.isEmpty()) { + return createIndicator( + HealthStatus.GREEN, + "Data streams are executing their lifecycles without issues", + createDetails(verbose, dataStreamLifecycleHealthInfo), + List.of(), + List.of() + ); + } else { + List affectedIndices = stagnatingBackingIndices.stream() + .map(DslErrorInfo::indexName) + .limit(Math.min(maxAffectedResourcesCount, stagnatingBackingIndices.size())) + .collect(toList()); + return createIndicator( + HealthStatus.YELLOW, + (stagnatingBackingIndices.size() > 1 ? stagnatingBackingIndices.size() + " backing indices have" : "A backing index has") + + " repeatedly encountered errors whilst trying to advance in its lifecycle", + createDetails(verbose, dataStreamLifecycleHealthInfo), + STAGNATING_INDEX_IMPACT, + List.of( + new Diagnosis( + STAGNATING_BACKING_INDICES_DIAGNOSIS_DEF, + List.of(new Diagnosis.Resource(Diagnosis.Resource.Type.INDEX, affectedIndices)) + ) + ) + ); + } + } + + private static HealthIndicatorDetails createDetails(boolean verbose, DataStreamLifecycleHealthInfo dataStreamLifecycleHealthInfo) { + if (verbose == false) { + return HealthIndicatorDetails.EMPTY; + } + + var details = new HashMap(); + details.put("total_backing_indices_in_error", dataStreamLifecycleHealthInfo.totalErrorEntriesCount()); + details.put("stagnating_backing_indices_count", dataStreamLifecycleHealthInfo.dslErrorsInfo().size()); + if (dataStreamLifecycleHealthInfo.dslErrorsInfo().isEmpty() == false) { + details.put("stagnating_backing_indices", dataStreamLifecycleHealthInfo.dslErrorsInfo().stream().map(dslError -> { + LinkedHashMap errorDetails = new LinkedHashMap<>(3, 1L); + errorDetails.put("index_name", dslError.indexName()); + errorDetails.put("first_occurrence_timestamp", dslError.firstOccurrence()); + errorDetails.put("retry_count", dslError.retryCount()); + return errorDetails; + }).toList()); + } + return new SimpleHealthIndicatorDetails(details); + } +} diff --git a/modules/data-streams/src/test/java/org/elasticsearch/datastreams/lifecycle/health/DataStreamLifecycleHealthIndicatorServiceTests.java b/modules/data-streams/src/test/java/org/elasticsearch/datastreams/lifecycle/health/DataStreamLifecycleHealthIndicatorServiceTests.java new file mode 100644 index 0000000000000..877b463301311 --- /dev/null +++ b/modules/data-streams/src/test/java/org/elasticsearch/datastreams/lifecycle/health/DataStreamLifecycleHealthIndicatorServiceTests.java @@ -0,0 +1,102 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.datastreams.lifecycle.health; + +import org.elasticsearch.cluster.metadata.DataStream; +import org.elasticsearch.common.Strings; +import org.elasticsearch.health.Diagnosis; +import org.elasticsearch.health.HealthIndicatorDetails; +import org.elasticsearch.health.HealthIndicatorResult; +import org.elasticsearch.health.HealthStatus; +import org.elasticsearch.health.node.DataStreamLifecycleHealthInfo; +import org.elasticsearch.health.node.DslErrorInfo; +import org.elasticsearch.health.node.HealthInfo; +import org.elasticsearch.test.ESTestCase; +import org.junit.Before; + +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import static org.elasticsearch.datastreams.lifecycle.health.DataStreamLifecycleHealthIndicatorService.STAGNATING_BACKING_INDICES_DIAGNOSIS_DEF; +import static org.elasticsearch.datastreams.lifecycle.health.DataStreamLifecycleHealthIndicatorService.STAGNATING_INDEX_IMPACT; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.core.IsNot.not; + +public class DataStreamLifecycleHealthIndicatorServiceTests extends ESTestCase { + + private DataStreamLifecycleHealthIndicatorService service; + + @Before + public void setupService() { + service = new DataStreamLifecycleHealthIndicatorService(); + } + + public void testGreenWhenNoDSLHealthData() { + HealthIndicatorResult result = service.calculate(true, new HealthInfo(Map.of(), null)); + assertThat(result.status(), is(HealthStatus.GREEN)); + assertThat( + result.symptom(), + is("No data stream lifecycle health data available yet. Health information will be reported after the first run.") + ); + assertThat(result.details(), is(HealthIndicatorDetails.EMPTY)); + assertThat(result.impacts(), is(List.of())); + assertThat(result.diagnosisList(), is(List.of())); + } + + public void testGreenWhenEmptyListOfStagnatingIndices() { + HealthIndicatorResult result = service.calculate(true, new HealthInfo(Map.of(), new DataStreamLifecycleHealthInfo(List.of(), 15))); + assertThat(result.status(), is(HealthStatus.GREEN)); + assertThat(result.symptom(), is("Data streams are executing their lifecycles without issues")); + assertThat(result.details(), is(not(HealthIndicatorDetails.EMPTY))); + assertThat(Strings.toString(result.details()), containsString("\"total_backing_indices_in_error\":15")); + assertThat(result.impacts(), is(List.of())); + assertThat(result.diagnosisList(), is(List.of())); + } + + public void testYellowWhenStagnatingIndicesPresent() { + String secondGenerationIndex = DataStream.getDefaultBackingIndexName("foo", 2L); + String firstGenerationIndex = DataStream.getDefaultBackingIndexName("foo", 1L); + HealthIndicatorResult result = service.calculate( + true, + new HealthInfo( + Map.of(), + new DataStreamLifecycleHealthInfo( + List.of(new DslErrorInfo(secondGenerationIndex, 1L, 200), new DslErrorInfo(firstGenerationIndex, 3L, 100)), + 15 + ) + ) + ); + assertThat(result.status(), is(HealthStatus.YELLOW)); + assertThat(result.symptom(), is("2 backing indices have repeatedly encountered errors whilst trying to advance in its lifecycle")); + assertThat(result.details(), is(not(HealthIndicatorDetails.EMPTY))); + String detailsAsString = Strings.toString(result.details()); + assertThat(detailsAsString, containsString("\"total_backing_indices_in_error\":15")); + assertThat(detailsAsString, containsString("\"stagnating_backing_indices_count\":2")); + assertThat( + detailsAsString, + containsString( + String.format( + Locale.ROOT, + "\"index_name\":\"%s\"," + + "\"first_occurrence_timestamp\":1,\"retry_count\":200},{\"index_name\":\"%s\"," + + "\"first_occurrence_timestamp\":3,\"retry_count\":100", + secondGenerationIndex, + firstGenerationIndex + ) + ) + ); + assertThat(result.impacts(), is(STAGNATING_INDEX_IMPACT)); + Diagnosis diagnosis = result.diagnosisList().get(0); + assertThat(diagnosis.definition(), is(STAGNATING_BACKING_INDICES_DIAGNOSIS_DEF)); + assertThat(diagnosis.affectedResources().get(0).getValues(), containsInAnyOrder(secondGenerationIndex, firstGenerationIndex)); + } +} From 7ded90655f4d18e7edcc83e6325849bdd0c53309 Mon Sep 17 00:00:00 2001 From: Nikolaj Volgushev Date: Fri, 8 Dec 2023 16:08:26 +0100 Subject: [PATCH 15/22] Hot-reloadable remote cluster credentials (#102798) This PR enables RCS 2.0 remote clusters to be configured without the need to restart nodes. It works as the follows (assuming both clusters are already running): 1. Get a cross-cluster API key for accessing the _remote_ cluster 2. Add cross-cluster API key to keystores of the _local_ cluster, e.g. ``` echo -n xxx | ./bin/elasticsearch-keystore add cluster.remote.my.credentials -x ``` 3. Call [ReloadSecureSettings API](https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-nodes-reload-secure-settings.html) on the _local_ cluster 4. Configure RCS 2.0 remote cluster should now just work for the _local_ cluster, e.g. ``` PUT /_cluster/settings {"persistent":{"cluster":{"remote":{"my":{"seeds":["127.0.0.1:9443"]}}}}} ``` This PR does **not** include functionality to automatically re-build connections on secure settings reload. I will add this in a follow up PR. The high level technical approach is to maintain a credentials manager class and use this to attach credentials for connections to remote clusters. This [comment](https://github.com/elastic/elasticsearch/pull/102798/files#r1417708553) also provides more context on some lower level details. Relates: https://github.com/elastic/elasticsearch/pull/98120 Relates: ES-6764 --- docs/changelog/102798.yaml | 5 + .../transport/ProxyConnectionStrategy.java | 2 +- .../transport/RemoteClusterConnection.java | 25 +- .../RemoteClusterCredentialsManager.java | 52 +++ .../transport/RemoteClusterService.java | 27 +- .../transport/RemoteConnectionManager.java | 61 +++- .../transport/SniffConnectionStrategy.java | 6 +- .../ProxyConnectionStrategyTests.java | 54 ++- .../RemoteClusterConnectionTests.java | 69 +++- .../RemoteClusterCredentialsManagerTests.java | 43 +++ .../RemoteConnectionManagerTests.java | 32 +- .../RemoteConnectionStrategyTests.java | 18 +- .../SniffConnectionStrategyTests.java | 66 +++- .../ReloadRemoteClusterCredentialsAction.java | 50 +++ .../authz/privilege/SystemPrivilege.java | 4 +- .../xpack/security/operator/Constants.java | 1 + .../ReloadRemoteClusterCredentialsIT.java | 314 ++++++++++++++++++ .../xpack/security/Security.java | 104 ++++-- ...tReloadRemoteClusterCredentialsAction.java | 54 +++ .../RemoteClusterCredentialsResolver.java | 51 --- .../SecurityServerTransportInterceptor.java | 45 +-- .../xpack/security/LocalStateSecurity.java | 14 +- .../xpack/security/SecurityTests.java | 102 ++++++ ...RemoteClusterCredentialsResolverTests.java | 38 --- ...curityServerTransportInterceptorTests.java | 77 ++--- 25 files changed, 1054 insertions(+), 260 deletions(-) create mode 100644 docs/changelog/102798.yaml create mode 100644 server/src/main/java/org/elasticsearch/transport/RemoteClusterCredentialsManager.java create mode 100644 server/src/test/java/org/elasticsearch/transport/RemoteClusterCredentialsManagerTests.java create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/settings/ReloadRemoteClusterCredentialsAction.java create mode 100644 x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/ReloadRemoteClusterCredentialsIT.java create mode 100644 x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/settings/TransportReloadRemoteClusterCredentialsAction.java delete mode 100644 x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/RemoteClusterCredentialsResolver.java delete mode 100644 x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/RemoteClusterCredentialsResolverTests.java diff --git a/docs/changelog/102798.yaml b/docs/changelog/102798.yaml new file mode 100644 index 0000000000000..986ad99f96a19 --- /dev/null +++ b/docs/changelog/102798.yaml @@ -0,0 +1,5 @@ +pr: 102798 +summary: Hot-reloadable remote cluster credentials +area: Security +type: enhancement +issues: [] diff --git a/server/src/main/java/org/elasticsearch/transport/ProxyConnectionStrategy.java b/server/src/main/java/org/elasticsearch/transport/ProxyConnectionStrategy.java index 320b9cfdbf7e6..cfb6f872ce748 100644 --- a/server/src/main/java/org/elasticsearch/transport/ProxyConnectionStrategy.java +++ b/server/src/main/java/org/elasticsearch/transport/ProxyConnectionStrategy.java @@ -179,7 +179,7 @@ public class ProxyConnectionStrategy extends RemoteConnectionStrategy { RemoteConnectionManager.wrapConnectionWithRemoteClusterInfo( newConnection, clusterAlias, - actualProfile.getTransportProfile() + connectionManager.getCredentialsManager() ), actualProfile.getHandshakeTimeout(), cn -> true, diff --git a/server/src/main/java/org/elasticsearch/transport/RemoteClusterConnection.java b/server/src/main/java/org/elasticsearch/transport/RemoteClusterConnection.java index a055e4122257f..3c74e46851504 100644 --- a/server/src/main/java/org/elasticsearch/transport/RemoteClusterConnection.java +++ b/server/src/main/java/org/elasticsearch/transport/RemoteClusterConnection.java @@ -57,15 +57,28 @@ final class RemoteClusterConnection implements Closeable { * @param settings the nodes settings object * @param clusterAlias the configured alias of the cluster to connect to * @param transportService the local nodes transport service - * @param credentialsProtected Whether the remote cluster is protected by a credentials, i.e. it has a credentials configured - * via secure setting. This means the remote cluster uses the new configurable access RCS model - * (as opposed to the basic model). + * @param credentialsManager object to lookup remote cluster credentials by cluster alias. If a cluster is protected by a credential, + * i.e. it has a credential configured via secure setting. + * This means the remote cluster uses the advances RCS model (as opposed to the basic model). */ - RemoteClusterConnection(Settings settings, String clusterAlias, TransportService transportService, boolean credentialsProtected) { + RemoteClusterConnection( + Settings settings, + String clusterAlias, + TransportService transportService, + RemoteClusterCredentialsManager credentialsManager + ) { this.transportService = transportService; this.clusterAlias = clusterAlias; - ConnectionProfile profile = RemoteConnectionStrategy.buildConnectionProfile(clusterAlias, settings, credentialsProtected); - this.remoteConnectionManager = new RemoteConnectionManager(clusterAlias, createConnectionManager(profile, transportService)); + ConnectionProfile profile = RemoteConnectionStrategy.buildConnectionProfile( + clusterAlias, + settings, + credentialsManager.hasCredentials(clusterAlias) + ); + this.remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + credentialsManager, + createConnectionManager(profile, transportService) + ); this.connectionStrategy = RemoteConnectionStrategy.buildStrategy(clusterAlias, transportService, remoteConnectionManager, settings); // we register the transport service here as a listener to make sure we notify handlers on disconnect etc. this.remoteConnectionManager.addListener(transportService); diff --git a/server/src/main/java/org/elasticsearch/transport/RemoteClusterCredentialsManager.java b/server/src/main/java/org/elasticsearch/transport/RemoteClusterCredentialsManager.java new file mode 100644 index 0000000000000..32a5e196c3a0b --- /dev/null +++ b/server/src/main/java/org/elasticsearch/transport/RemoteClusterCredentialsManager.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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.transport; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.settings.SecureString; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.core.Nullable; + +import java.util.Map; + +import static org.elasticsearch.transport.RemoteClusterService.REMOTE_CLUSTER_CREDENTIALS; + +public class RemoteClusterCredentialsManager { + + private static final Logger logger = LogManager.getLogger(RemoteClusterCredentialsManager.class); + + private volatile Map clusterCredentials; + + public RemoteClusterCredentialsManager(Settings settings) { + updateClusterCredentials(settings); + } + + public void updateClusterCredentials(Settings settings) { + clusterCredentials = REMOTE_CLUSTER_CREDENTIALS.getAsMap(settings); + logger.debug( + () -> Strings.format( + "Updated remote cluster credentials for clusters: [%s]", + Strings.collectionToCommaDelimitedString(clusterCredentials.keySet()) + ) + ); + } + + @Nullable + public SecureString resolveCredentials(String clusterAlias) { + return clusterCredentials.get(clusterAlias); + } + + public boolean hasCredentials(String clusterAlias) { + return clusterCredentials.containsKey(clusterAlias); + } + + public static final RemoteClusterCredentialsManager EMPTY = new RemoteClusterCredentialsManager(Settings.EMPTY); +} diff --git a/server/src/main/java/org/elasticsearch/transport/RemoteClusterService.java b/server/src/main/java/org/elasticsearch/transport/RemoteClusterService.java index c38f4b26c665f..6bfbb95cbcfe9 100644 --- a/server/src/main/java/org/elasticsearch/transport/RemoteClusterService.java +++ b/server/src/main/java/org/elasticsearch/transport/RemoteClusterService.java @@ -147,15 +147,14 @@ public boolean isRemoteClusterServerEnabled() { private final TransportService transportService; private final Map remoteClusters = ConcurrentCollections.newConcurrentMap(); - private final Set credentialsProtectedRemoteClusters; + private final RemoteClusterCredentialsManager remoteClusterCredentialsManager; RemoteClusterService(Settings settings, TransportService transportService) { super(settings); this.enabled = DiscoveryNode.isRemoteClusterClient(settings); this.remoteClusterServerEnabled = REMOTE_CLUSTER_SERVER_ENABLED.get(settings); this.transportService = transportService; - this.credentialsProtectedRemoteClusters = REMOTE_CLUSTER_CREDENTIALS.getAsMap(settings).keySet(); - + this.remoteClusterCredentialsManager = new RemoteClusterCredentialsManager(settings); if (remoteClusterServerEnabled) { registerRemoteClusterHandshakeRequestHandler(transportService); } @@ -305,6 +304,14 @@ private synchronized void updateSkipUnavailable(String clusterAlias, Boolean ski } } + public void updateRemoteClusterCredentials(Settings settings) { + remoteClusterCredentialsManager.updateClusterCredentials(settings); + } + + public RemoteClusterCredentialsManager getRemoteClusterCredentialsManager() { + return remoteClusterCredentialsManager; + } + @Override protected void updateRemoteCluster(String clusterAlias, Settings settings) { CountDownLatch latch = new CountDownLatch(1); @@ -363,12 +370,7 @@ synchronized void updateRemoteCluster( if (remote == null) { // this is a new cluster we have to add a new representation Settings finalSettings = Settings.builder().put(this.settings, false).put(newSettings, false).build(); - remote = new RemoteClusterConnection( - finalSettings, - clusterAlias, - transportService, - credentialsProtectedRemoteClusters.contains(clusterAlias) - ); + remote = new RemoteClusterConnection(finalSettings, clusterAlias, transportService, remoteClusterCredentialsManager); remoteClusters.put(clusterAlias, remote); remote.ensureConnected(listener.map(ignored -> RemoteClusterConnectionStatus.CONNECTED)); } else if (remote.shouldRebuildConnection(newSettings)) { @@ -380,12 +382,7 @@ synchronized void updateRemoteCluster( } remoteClusters.remove(clusterAlias); Settings finalSettings = Settings.builder().put(this.settings, false).put(newSettings, false).build(); - remote = new RemoteClusterConnection( - finalSettings, - clusterAlias, - transportService, - credentialsProtectedRemoteClusters.contains(clusterAlias) - ); + remote = new RemoteClusterConnection(finalSettings, clusterAlias, transportService, remoteClusterCredentialsManager); remoteClusters.put(clusterAlias, remote); remote.ensureConnected(listener.map(ignored -> RemoteClusterConnectionStatus.RECONNECTED)); } else { diff --git a/server/src/main/java/org/elasticsearch/transport/RemoteConnectionManager.java b/server/src/main/java/org/elasticsearch/transport/RemoteConnectionManager.java index b16734b273376..3b531d54fb033 100644 --- a/server/src/main/java/org/elasticsearch/transport/RemoteConnectionManager.java +++ b/server/src/main/java/org/elasticsearch/transport/RemoteConnectionManager.java @@ -12,6 +12,7 @@ import org.elasticsearch.TransportVersion; import org.elasticsearch.action.ActionListener; import org.elasticsearch.cluster.node.DiscoveryNode; +import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.common.util.CollectionUtils; import org.elasticsearch.core.Nullable; import org.elasticsearch.core.Releasable; @@ -25,18 +26,19 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicLong; -import static org.elasticsearch.transport.RemoteClusterPortSettings.REMOTE_CLUSTER_PROFILE; import static org.elasticsearch.transport.RemoteClusterService.REMOTE_CLUSTER_HANDSHAKE_ACTION_NAME; public class RemoteConnectionManager implements ConnectionManager { private final String clusterAlias; + private final RemoteClusterCredentialsManager credentialsManager; private final ConnectionManager delegate; private final AtomicLong counter = new AtomicLong(); private volatile List connectedNodes = Collections.emptyList(); - RemoteConnectionManager(String clusterAlias, ConnectionManager delegate) { + RemoteConnectionManager(String clusterAlias, RemoteClusterCredentialsManager credentialsManager, ConnectionManager delegate) { this.clusterAlias = clusterAlias; + this.credentialsManager = credentialsManager; this.delegate = delegate; this.delegate.addListener(new TransportConnectionListener() { @Override @@ -51,6 +53,10 @@ public void onNodeDisconnected(DiscoveryNode node, Transport.Connection connecti }); } + public RemoteClusterCredentialsManager getCredentialsManager() { + return credentialsManager; + } + /** * Remote cluster connections have a different lifecycle from intra-cluster connections. Use {@link #connectToRemoteClusterNode} * instead of this method. @@ -95,13 +101,7 @@ public void openConnection(DiscoveryNode node, @Nullable ConnectionProfile profi node, profile, listener.delegateFailureAndWrap( - (l, connection) -> l.onResponse( - new InternalRemoteConnection( - connection, - clusterAlias, - profile != null ? profile.getTransportProfile() : getConnectionProfile().getTransportProfile() - ) - ) + (l, connection) -> l.onResponse(wrapConnectionWithRemoteClusterInfo(connection, clusterAlias, credentialsManager)) ) ); } @@ -182,16 +182,35 @@ public void closeNoBlock() { * @return a cluster alias if the connection target a node in the remote cluster, otherwise an empty result */ public static Optional resolveRemoteClusterAlias(Transport.Connection connection) { + return resolveRemoteClusterAliasWithCredentials(connection).map(RemoteClusterAliasWithCredentials::clusterAlias); + } + + public record RemoteClusterAliasWithCredentials(String clusterAlias, @Nullable SecureString credentials) { + @Override + public String toString() { + return "RemoteClusterAliasWithCredentials{clusterAlias='" + clusterAlias + "', credentials='::es_redacted::'}"; + } + } + + /** + * This method returns information (alias and credentials) for remote cluster for the given transport connection. + * Either or both of alias and credentials can be null depending on the connection. + * + * @param connection the transport connection for which to resolve a remote cluster alias + */ + public static Optional resolveRemoteClusterAliasWithCredentials(Transport.Connection connection) { Transport.Connection unwrapped = TransportService.unwrapConnection(connection); if (unwrapped instanceof InternalRemoteConnection remoteConnection) { - return Optional.of(remoteConnection.getClusterAlias()); + return Optional.of( + new RemoteClusterAliasWithCredentials(remoteConnection.getClusterAlias(), remoteConnection.getClusterCredentials()) + ); } return Optional.empty(); } private Transport.Connection getConnectionInternal(DiscoveryNode node) throws NodeNotConnectedException { Transport.Connection connection = delegate.getConnection(node); - return new InternalRemoteConnection(connection, clusterAlias, getConnectionProfile().getTransportProfile()); + return wrapConnectionWithRemoteClusterInfo(connection, clusterAlias, credentialsManager); } private synchronized void addConnectedNode(DiscoveryNode addedNode) { @@ -297,21 +316,27 @@ private static final class InternalRemoteConnection implements Transport.Connect private static final Logger logger = LogManager.getLogger(InternalRemoteConnection.class); private final Transport.Connection connection; private final String clusterAlias; - private final boolean isRemoteClusterProfile; + @Nullable + private final SecureString clusterCredentials; - InternalRemoteConnection(Transport.Connection connection, String clusterAlias, String transportProfile) { + private InternalRemoteConnection(Transport.Connection connection, String clusterAlias, @Nullable SecureString clusterCredentials) { assert false == connection instanceof InternalRemoteConnection : "should not double wrap"; assert false == connection instanceof ProxyConnection : "proxy connection should wrap internal remote connection, not the other way around"; - this.clusterAlias = Objects.requireNonNull(clusterAlias); this.connection = Objects.requireNonNull(connection); - this.isRemoteClusterProfile = REMOTE_CLUSTER_PROFILE.equals(Objects.requireNonNull(transportProfile)); + this.clusterAlias = Objects.requireNonNull(clusterAlias); + this.clusterCredentials = clusterCredentials; } public String getClusterAlias() { return clusterAlias; } + @Nullable + public SecureString getClusterCredentials() { + return clusterCredentials; + } + @Override public DiscoveryNode getNode() { return connection.getNode(); @@ -321,7 +346,7 @@ public DiscoveryNode getNode() { public void sendRequest(long requestId, String action, TransportRequest request, TransportRequestOptions options) throws IOException, TransportException { final String effectiveAction; - if (isRemoteClusterProfile && TransportService.HANDSHAKE_ACTION_NAME.equals(action)) { + if (clusterCredentials != null && TransportService.HANDSHAKE_ACTION_NAME.equals(action)) { logger.trace("sending remote cluster specific handshake to node [{}] of remote cluster [{}]", getNode(), clusterAlias); effectiveAction = REMOTE_CLUSTER_HANDSHAKE_ACTION_NAME; } else { @@ -389,8 +414,8 @@ public boolean hasReferences() { static InternalRemoteConnection wrapConnectionWithRemoteClusterInfo( Transport.Connection connection, String clusterAlias, - String transportProfile + RemoteClusterCredentialsManager credentialsManager ) { - return new InternalRemoteConnection(connection, clusterAlias, transportProfile); + return new InternalRemoteConnection(connection, clusterAlias, credentialsManager.resolveCredentials(clusterAlias)); } } diff --git a/server/src/main/java/org/elasticsearch/transport/SniffConnectionStrategy.java b/server/src/main/java/org/elasticsearch/transport/SniffConnectionStrategy.java index 0dcad9cf6864c..0f68a58faf463 100644 --- a/server/src/main/java/org/elasticsearch/transport/SniffConnectionStrategy.java +++ b/server/src/main/java/org/elasticsearch/transport/SniffConnectionStrategy.java @@ -357,7 +357,11 @@ private ConnectionManager.ConnectionValidator getConnectionValidator(DiscoveryNo : "transport profile must be consistent between the connection manager and the actual profile"; transportService.connectionValidator(node) .validate( - RemoteConnectionManager.wrapConnectionWithRemoteClusterInfo(connection, clusterAlias, profile.getTransportProfile()), + RemoteConnectionManager.wrapConnectionWithRemoteClusterInfo( + connection, + clusterAlias, + connectionManager.getCredentialsManager() + ), profile, listener ); diff --git a/server/src/test/java/org/elasticsearch/transport/ProxyConnectionStrategyTests.java b/server/src/test/java/org/elasticsearch/transport/ProxyConnectionStrategyTests.java index ead43d0bac05e..b3c7c5adac95d 100644 --- a/server/src/test/java/org/elasticsearch/transport/ProxyConnectionStrategyTests.java +++ b/server/src/test/java/org/elasticsearch/transport/ProxyConnectionStrategyTests.java @@ -130,7 +130,11 @@ public void testProxyStrategyWillOpenExpectedNumberOfConnectionsToAddress() { ); int numOfConnections = randomIntBetween(4, 8); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); ProxyConnectionStrategy strategy = new ProxyConnectionStrategy( clusterAlias, localService, @@ -188,7 +192,11 @@ public void testProxyStrategyWillOpenNewConnectionsOnDisconnect() throws Excepti AtomicBoolean useAddress1 = new AtomicBoolean(true); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); ProxyConnectionStrategy strategy = new ProxyConnectionStrategy( clusterAlias, localService, @@ -263,7 +271,11 @@ public void testConnectFailsWithIncompatibleNodes() { ); int numOfConnections = randomIntBetween(4, 8); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); ProxyConnectionStrategy strategy = new ProxyConnectionStrategy( clusterAlias, localService, @@ -328,7 +340,11 @@ public void testConnectFailsWithNonRetryableException() { ); int numOfConnections = randomIntBetween(4, 8); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); ProxyConnectionStrategy strategy = new ProxyConnectionStrategy( clusterAlias, localService, @@ -388,7 +404,11 @@ public void testClusterNameValidationPreventConnectingToDifferentClusters() thro AtomicBoolean useAddress1 = new AtomicBoolean(true); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); ProxyConnectionStrategy strategy = new ProxyConnectionStrategy( clusterAlias, localService, @@ -459,7 +479,11 @@ public void testProxyStrategyWillResolveAddressesEachConnect() throws Exception ); int numOfConnections = randomIntBetween(4, 8); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); ProxyConnectionStrategy strategy = new ProxyConnectionStrategy( clusterAlias, localService, @@ -511,7 +535,11 @@ public void onNodeConnected(DiscoveryNode node, Transport.Connection connection) }); try ( - var remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + var remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); var strategy = new ProxyConnectionStrategy( clusterAlias, localService, @@ -554,7 +582,11 @@ public void testProxyStrategyWillNeedToBeRebuiltIfNumOfSocketsOrAddressesOrServe ); int numOfConnections = randomIntBetween(4, 8); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); ProxyConnectionStrategy strategy = new ProxyConnectionStrategy( clusterAlias, localService, @@ -672,7 +704,11 @@ public void testServerNameAttributes() { ); int numOfConnections = randomIntBetween(4, 8); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); ProxyConnectionStrategy strategy = new ProxyConnectionStrategy( clusterAlias, localService, diff --git a/server/src/test/java/org/elasticsearch/transport/RemoteClusterConnectionTests.java b/server/src/test/java/org/elasticsearch/transport/RemoteClusterConnectionTests.java index d4f03f1027838..cbe15cc9664f4 100644 --- a/server/src/test/java/org/elasticsearch/transport/RemoteClusterConnectionTests.java +++ b/server/src/test/java/org/elasticsearch/transport/RemoteClusterConnectionTests.java @@ -62,6 +62,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; @@ -252,7 +253,14 @@ public void run() { AtomicReference exceptionReference = new AtomicReference<>(); String clusterAlias = "test-cluster"; Settings settings = buildRandomSettings(clusterAlias, addresses(seedNode)); - try (RemoteClusterConnection connection = new RemoteClusterConnection(settings, clusterAlias, service, randomBoolean())) { + try ( + RemoteClusterConnection connection = new RemoteClusterConnection( + settings, + clusterAlias, + service, + randomFrom(RemoteClusterCredentialsManager.EMPTY, buildCredentialsManager(clusterAlias)) + ) + ) { ActionListener listener = ActionListener.wrap(x -> { listenerCalled.countDown(); fail("expected exception"); @@ -322,7 +330,14 @@ public void testCloseWhileConcurrentlyConnecting() throws IOException, Interrupt service.acceptIncomingRequests(); String clusterAlias = "test-cluster"; Settings settings = buildRandomSettings(clusterAlias, seedNodes); - try (RemoteClusterConnection connection = new RemoteClusterConnection(settings, clusterAlias, service, false)) { + try ( + RemoteClusterConnection connection = new RemoteClusterConnection( + settings, + clusterAlias, + service, + RemoteClusterCredentialsManager.EMPTY + ) + ) { int numThreads = randomIntBetween(4, 10); Thread[] threads = new Thread[numThreads]; CyclicBarrier barrier = new CyclicBarrier(numThreads + 1); @@ -470,7 +485,12 @@ private void doTestGetConnectionInfo(boolean hasClusterCredentials) throws Excep settings = Settings.builder().put(settings).setSecureSettings(secureSettings).build(); } try ( - RemoteClusterConnection connection = new RemoteClusterConnection(settings, clusterAlias, service, hasClusterCredentials) + RemoteClusterConnection connection = new RemoteClusterConnection( + settings, + clusterAlias, + service, + hasClusterCredentials ? buildCredentialsManager(clusterAlias) : RemoteClusterCredentialsManager.EMPTY + ) ) { // test no nodes connected RemoteConnectionInfo remoteConnectionInfo = assertSerialization(connection.getConnectionInfo()); @@ -662,7 +682,12 @@ private void doTestCollectNodes(boolean hasClusterCredentials) throws Exception } try ( - RemoteClusterConnection connection = new RemoteClusterConnection(settings, clusterAlias, service, hasClusterCredentials) + RemoteClusterConnection connection = new RemoteClusterConnection( + settings, + clusterAlias, + service, + hasClusterCredentials ? buildCredentialsManager(clusterAlias) : RemoteClusterCredentialsManager.EMPTY + ) ) { CountDownLatch responseLatch = new CountDownLatch(1); AtomicReference> reference = new AtomicReference<>(); @@ -713,7 +738,14 @@ public void testNoChannelsExceptREG() throws Exception { String clusterAlias = "test-cluster"; Settings settings = buildRandomSettings(clusterAlias, addresses(seedNode)); - try (RemoteClusterConnection connection = new RemoteClusterConnection(settings, clusterAlias, service, false)) { + try ( + RemoteClusterConnection connection = new RemoteClusterConnection( + settings, + clusterAlias, + service, + RemoteClusterCredentialsManager.EMPTY + ) + ) { PlainActionFuture plainActionFuture = new PlainActionFuture<>(); connection.ensureConnected(plainActionFuture); plainActionFuture.get(10, TimeUnit.SECONDS); @@ -779,7 +811,14 @@ public void testConnectedNodesConcurrentAccess() throws IOException, Interrupted String clusterAlias = "test-cluster"; Settings settings = buildRandomSettings(clusterAlias, seedNodes); - try (RemoteClusterConnection connection = new RemoteClusterConnection(settings, clusterAlias, service, randomBoolean())) { + try ( + RemoteClusterConnection connection = new RemoteClusterConnection( + settings, + clusterAlias, + service, + randomFrom(RemoteClusterCredentialsManager.EMPTY, buildCredentialsManager(clusterAlias)) + ) + ) { final int numGetThreads = randomIntBetween(4, 10); final Thread[] getThreads = new Thread[numGetThreads]; final int numModifyingThreads = randomIntBetween(4, 10); @@ -873,7 +912,14 @@ public void testGetConnection() throws Exception { service.acceptIncomingRequests(); String clusterAlias = "test-cluster"; Settings settings = buildRandomSettings(clusterAlias, addresses(seedNode)); - try (RemoteClusterConnection connection = new RemoteClusterConnection(settings, clusterAlias, service, false)) { + try ( + RemoteClusterConnection connection = new RemoteClusterConnection( + settings, + clusterAlias, + service, + RemoteClusterCredentialsManager.EMPTY + ) + ) { PlainActionFuture.get(fut -> connection.ensureConnected(fut.map(x -> null))); for (int i = 0; i < 10; i++) { // always a direct connection as the remote node is already connected @@ -921,4 +967,13 @@ private static Settings buildSniffSettings(String clusterAlias, List see ); return builder.build(); } + + private static RemoteClusterCredentialsManager buildCredentialsManager(String clusterAlias) { + Objects.requireNonNull(clusterAlias); + final Settings.Builder builder = Settings.builder(); + final MockSecureSettings secureSettings = new MockSecureSettings(); + secureSettings.setString("cluster.remote." + clusterAlias + ".credentials", randomAlphaOfLength(20)); + builder.setSecureSettings(secureSettings); + return new RemoteClusterCredentialsManager(builder.build()); + } } diff --git a/server/src/test/java/org/elasticsearch/transport/RemoteClusterCredentialsManagerTests.java b/server/src/test/java/org/elasticsearch/transport/RemoteClusterCredentialsManagerTests.java new file mode 100644 index 0000000000000..f02148a40e47e --- /dev/null +++ b/server/src/test/java/org/elasticsearch/transport/RemoteClusterCredentialsManagerTests.java @@ -0,0 +1,43 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.transport; + +import org.elasticsearch.common.settings.MockSecureSettings; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.test.ESTestCase; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; + +public class RemoteClusterCredentialsManagerTests extends ESTestCase { + public void testResolveRemoteClusterCredentials() { + final String clusterAlias = randomAlphaOfLength(9); + final String otherClusterAlias = randomAlphaOfLength(10); + + final String secret = randomAlphaOfLength(20); + final Settings settings = buildSettingsWithCredentials(clusterAlias, secret); + RemoteClusterCredentialsManager credentialsManager = new RemoteClusterCredentialsManager(settings); + assertThat(credentialsManager.resolveCredentials(clusterAlias).toString(), equalTo(secret)); + assertThat(credentialsManager.hasCredentials(otherClusterAlias), is(false)); + + final String updatedSecret = randomAlphaOfLength(21); + credentialsManager.updateClusterCredentials(buildSettingsWithCredentials(clusterAlias, updatedSecret)); + assertThat(credentialsManager.resolveCredentials(clusterAlias).toString(), equalTo(updatedSecret)); + + credentialsManager.updateClusterCredentials(Settings.EMPTY); + assertThat(credentialsManager.hasCredentials(clusterAlias), is(false)); + } + + private Settings buildSettingsWithCredentials(String clusterAlias, String secret) { + final Settings.Builder builder = Settings.builder(); + final MockSecureSettings secureSettings = new MockSecureSettings(); + secureSettings.setString("cluster.remote." + clusterAlias + ".credentials", secret); + return builder.setSecureSettings(secureSettings).build(); + } +} diff --git a/server/src/test/java/org/elasticsearch/transport/RemoteConnectionManagerTests.java b/server/src/test/java/org/elasticsearch/transport/RemoteConnectionManagerTests.java index 839138d3c7c34..b1ffda669e6a1 100644 --- a/server/src/test/java/org/elasticsearch/transport/RemoteConnectionManagerTests.java +++ b/server/src/test/java/org/elasticsearch/transport/RemoteConnectionManagerTests.java @@ -13,6 +13,7 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.node.DiscoveryNodeUtils; import org.elasticsearch.common.Strings; +import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.common.util.concurrent.ThreadContext; @@ -23,17 +24,20 @@ import java.io.IOException; import java.net.InetAddress; import java.util.HashSet; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ExecutionException; import static org.elasticsearch.transport.RemoteClusterService.REMOTE_CLUSTER_HANDSHAKE_ACTION_NAME; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; public class RemoteConnectionManagerTests extends ESTestCase { @@ -49,6 +53,7 @@ public void setUp() throws Exception { transport = mock(Transport.class); remoteConnectionManager = new RemoteConnectionManager( "remote-cluster", + RemoteClusterCredentialsManager.EMPTY, new ClusterConnectionManager(Settings.EMPTY, transport, new ThreadContext(Settings.EMPTY)) ); @@ -120,10 +125,13 @@ public void testResolveRemoteClusterAlias() throws ExecutionException, Interrupt public void testRewriteHandshakeAction() throws IOException { final Transport.Connection connection = mock(Transport.Connection.class); + final String clusterAlias = randomAlphaOfLengthBetween(3, 8); + final RemoteClusterCredentialsManager credentialsResolver = mock(RemoteClusterCredentialsManager.class); + when(credentialsResolver.resolveCredentials(clusterAlias)).thenReturn(new SecureString(randomAlphaOfLength(42))); final Transport.Connection wrappedConnection = RemoteConnectionManager.wrapConnectionWithRemoteClusterInfo( connection, - randomAlphaOfLengthBetween(3, 8), - RemoteClusterPortSettings.REMOTE_CLUSTER_PROFILE + clusterAlias, + credentialsResolver ); final long requestId = randomLong(); final TransportRequest request = mock(TransportRequest.class); @@ -142,6 +150,26 @@ public void testRewriteHandshakeAction() throws IOException { verify(connection).sendRequest(requestId, anotherAction, request, options); } + public void testWrapAndResolveConnectionRoundTrip() { + final Transport.Connection connection = mock(Transport.Connection.class); + final String clusterAlias = randomAlphaOfLengthBetween(3, 8); + final RemoteClusterCredentialsManager credentialsResolver = mock(RemoteClusterCredentialsManager.class); + final SecureString credentials = new SecureString(randomAlphaOfLength(42)); + // second credential will never be resolved + when(credentialsResolver.resolveCredentials(clusterAlias)).thenReturn(credentials, (SecureString) null); + final Transport.Connection wrappedConnection = RemoteConnectionManager.wrapConnectionWithRemoteClusterInfo( + connection, + clusterAlias, + credentialsResolver + ); + + final Optional actual = RemoteConnectionManager + .resolveRemoteClusterAliasWithCredentials(wrappedConnection); + + assertThat(actual.isPresent(), is(true)); + assertThat(actual.get(), equalTo(new RemoteConnectionManager.RemoteClusterAliasWithCredentials(clusterAlias, credentials))); + } + private static class TestRemoteConnection extends CloseableConnection { private final DiscoveryNode node; diff --git a/server/src/test/java/org/elasticsearch/transport/RemoteConnectionStrategyTests.java b/server/src/test/java/org/elasticsearch/transport/RemoteConnectionStrategyTests.java index 5d461e906a266..ca9986ba5eb1f 100644 --- a/server/src/test/java/org/elasticsearch/transport/RemoteConnectionStrategyTests.java +++ b/server/src/test/java/org/elasticsearch/transport/RemoteConnectionStrategyTests.java @@ -26,7 +26,11 @@ public void testStrategyChangeMeansThatStrategyMustBeRebuilt() { mock(Transport.class), threadContext ); - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager("cluster-alias", connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + "cluster-alias", + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); FakeConnectionStrategy first = new FakeConnectionStrategy( "cluster-alias", mock(TransportService.class), @@ -46,7 +50,11 @@ public void testSameStrategyChangeMeansThatStrategyDoesNotNeedToBeRebuilt() { mock(Transport.class), threadContext ); - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager("cluster-alias", connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + "cluster-alias", + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); FakeConnectionStrategy first = new FakeConnectionStrategy( "cluster-alias", mock(TransportService.class), @@ -69,7 +77,11 @@ public void testChangeInConnectionProfileMeansTheStrategyMustBeRebuilt() { assertEquals(TimeValue.MINUS_ONE, connectionManager.getConnectionProfile().getPingInterval()); assertEquals(Compression.Enabled.INDEXING_DATA, connectionManager.getConnectionProfile().getCompressionEnabled()); assertEquals(Compression.Scheme.LZ4, connectionManager.getConnectionProfile().getCompressionScheme()); - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager("cluster-alias", connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + "cluster-alias", + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); FakeConnectionStrategy first = new FakeConnectionStrategy( "cluster-alias", mock(TransportService.class), diff --git a/server/src/test/java/org/elasticsearch/transport/SniffConnectionStrategyTests.java b/server/src/test/java/org/elasticsearch/transport/SniffConnectionStrategyTests.java index 3c955258d45c8..ddee1ff4d690a 100644 --- a/server/src/test/java/org/elasticsearch/transport/SniffConnectionStrategyTests.java +++ b/server/src/test/java/org/elasticsearch/transport/SniffConnectionStrategyTests.java @@ -192,7 +192,11 @@ public void testSniffStrategyWillConnectToAndDiscoverNodes() { threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + hasClusterCredentials ? new RemoteClusterCredentialsManager(clientSettings) : RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -262,7 +266,11 @@ public void testSniffStrategyWillResolveDiscoveryNodesEachConnect() throws Excep threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -336,7 +344,11 @@ public void testSniffStrategyWillConnectToMaxAllowedNodesAndOpenNewConnectionsOn threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -424,7 +436,11 @@ public void testDiscoverWithSingleIncompatibleSeedNode() { threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -486,7 +502,11 @@ public void testConnectFailsWithIncompatibleNodes() { threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -549,7 +569,11 @@ public void testFilterNodesWithNodePredicate() { threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -617,7 +641,11 @@ public void testConnectFailsIfNoConnectionsOpened() { threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -694,7 +722,11 @@ public void testClusterNameValidationPreventConnectingToDifferentClusters() thro threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -783,7 +815,11 @@ public void testMultipleCallsToConnectEnsuresConnection() { threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -895,7 +931,11 @@ public void testConfiguredProxyAddressModeWillReplaceNodeAddress() { threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -964,7 +1004,11 @@ public void testSniffStrategyWillNeedToBeRebuiltIfNumOfConnectionsOrSeedsOrProxy threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( + clusterAlias, + RemoteClusterCredentialsManager.EMPTY, + connectionManager + ); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/settings/ReloadRemoteClusterCredentialsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/settings/ReloadRemoteClusterCredentialsAction.java new file mode 100644 index 0000000000000..27b9460dd67cb --- /dev/null +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/settings/ReloadRemoteClusterCredentialsAction.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.core.security.action.settings; + +import org.elasticsearch.action.ActionRequest; +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.io.stream.StreamOutput; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.common.settings.Settings; + +import java.io.IOException; + +public class ReloadRemoteClusterCredentialsAction extends ActionType { + public static final String NAME = "cluster:admin/xpack/security/remote_cluster_credentials/reload"; + public static final ReloadRemoteClusterCredentialsAction INSTANCE = new ReloadRemoteClusterCredentialsAction(); + + private ReloadRemoteClusterCredentialsAction() { + super(NAME, Writeable.Reader.localOnly()); + } + + public static class Request extends ActionRequest { + private final Settings settings; + + public Request(Settings settings) { + this.settings = settings; + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + public Settings getSettings() { + return settings; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + TransportAction.localOnly(); + } + } +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/SystemPrivilege.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/SystemPrivilege.java index bc42632507256..4d24a757537e2 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/SystemPrivilege.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/SystemPrivilege.java @@ -12,6 +12,7 @@ import org.elasticsearch.index.seqno.RetentionLeaseSyncAction; import org.elasticsearch.persistent.CompletionPersistentTaskAction; import org.elasticsearch.transport.TransportActionProxy; +import org.elasticsearch.xpack.core.security.action.settings.ReloadRemoteClusterCredentialsAction; import org.elasticsearch.xpack.core.security.support.StringMatcher; import java.util.Collections; @@ -43,7 +44,8 @@ public final class SystemPrivilege extends Privilege { "indices:data/read/*", // needed for SystemIndexMigrator "indices:admin/refresh", // needed for SystemIndexMigrator "indices:admin/aliases", // needed for SystemIndexMigrator - TransportSearchShardsAction.TYPE.name() // added so this API can be called with the system user by other APIs + TransportSearchShardsAction.TYPE.name(), // added so this API can be called with the system user by other APIs + ReloadRemoteClusterCredentialsAction.NAME // needed for Security plugin reload of remote cluster credentials ); private static final Predicate PREDICATE = (action) -> { 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 6e78eb2fb5b83..ea27eb9406d09 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 @@ -255,6 +255,7 @@ public class Constants { "cluster:admin/xpack/security/profile/suggest", "cluster:admin/xpack/security/profile/set_enabled", "cluster:admin/xpack/security/realm/cache/clear", + "cluster:admin/xpack/security/remote_cluster_credentials/reload", "cluster:admin/xpack/security/role/delete", "cluster:admin/xpack/security/role/get", "cluster:admin/xpack/security/role/put", diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/ReloadRemoteClusterCredentialsIT.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/ReloadRemoteClusterCredentialsIT.java new file mode 100644 index 0000000000000..6042d0072270d --- /dev/null +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/ReloadRemoteClusterCredentialsIT.java @@ -0,0 +1,314 @@ +/* + * 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.security; + +import org.apache.lucene.search.TotalHits; +import org.elasticsearch.TransportVersion; +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.admin.cluster.node.reload.NodesReloadSecureSettingsResponse; +import org.elasticsearch.action.admin.cluster.remote.RemoteClusterNodesAction; +import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest; +import org.elasticsearch.action.admin.cluster.state.ClusterStateAction; +import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest; +import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.search.SearchShardsRequest; +import org.elasticsearch.action.search.SearchShardsResponse; +import org.elasticsearch.action.search.ShardSearchFailure; +import org.elasticsearch.action.search.TransportSearchAction; +import org.elasticsearch.action.search.TransportSearchShardsAction; +import org.elasticsearch.cluster.ClusterName; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.node.VersionInformation; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.settings.KeyStoreWrapper; +import org.elasticsearch.common.settings.SecureString; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.transport.TransportAddress; +import org.elasticsearch.common.util.concurrent.ConcurrentCollections; +import org.elasticsearch.common.util.concurrent.EsExecutors; +import org.elasticsearch.env.Environment; +import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.SearchHits; +import org.elasticsearch.search.aggregations.InternalAggregations; +import org.elasticsearch.search.internal.InternalSearchResponse; +import org.elasticsearch.test.SecuritySingleNodeTestCase; +import org.elasticsearch.test.transport.MockTransportService; +import org.elasticsearch.threadpool.TestThreadPool; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.transport.RemoteClusterCredentialsManager; +import org.elasticsearch.transport.TransportService; +import org.elasticsearch.xpack.security.authc.ApiKeyService; +import org.elasticsearch.xpack.security.authc.CrossClusterAccessHeaders; +import org.junit.BeforeClass; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasKey; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; + +public class ReloadRemoteClusterCredentialsIT extends SecuritySingleNodeTestCase { + private static final String CLUSTER_ALIAS = "my_remote_cluster"; + + @BeforeClass + public static void disableInFips() { + assumeFalse( + "Cannot run in FIPS mode since the keystore will be password protected and sending a password in the reload" + + "settings api call, require TLS to be configured for the transport layer", + inFipsJvm() + ); + } + + @Override + public String configRoles() { + return org.elasticsearch.core.Strings.format(""" + user: + cluster: [ "ALL" ] + indices: + - names: '*' + privileges: [ "ALL" ] + remote_indices: + - names: '*' + privileges: [ "ALL" ] + clusters: ["*"] + """); + } + + @Override + public void tearDown() throws Exception { + try { + clearRemoteCluster(); + super.tearDown(); + } finally { + ThreadPool.terminate(threadPool, 10, TimeUnit.SECONDS); + } + } + + private final ThreadPool threadPool = new TestThreadPool(getClass().getName()); + + public void testReloadRemoteClusterCredentials() throws Exception { + final String credentials = randomAlphaOfLength(42); + writeCredentialsToKeyStore(credentials); + final RemoteClusterCredentialsManager clusterCredentialsManager = getInstanceFromNode(TransportService.class) + .getRemoteClusterService() + .getRemoteClusterCredentialsManager(); + // Until we reload, credentials written to keystore are not loaded into the credentials manager + assertThat(clusterCredentialsManager.hasCredentials(CLUSTER_ALIAS), is(false)); + reloadSecureSettings(); + assertThat(clusterCredentialsManager.resolveCredentials(CLUSTER_ALIAS), equalTo(credentials)); + + // Check that credentials get used for a remote connection, once we configure it + final BlockingQueue> capturedHeaders = ConcurrentCollections.newBlockingQueue(); + try (MockTransportService remoteTransport = startTransport("remoteNodeA", threadPool, capturedHeaders)) { + final TransportAddress remoteAddress = remoteTransport.getOriginalTransport() + .profileBoundAddresses() + .get("_remote_cluster") + .publishAddress(); + + configureRemoteCluster(remoteAddress); + + // Run search to trigger header capturing on the receiving side + client().search(new SearchRequest(CLUSTER_ALIAS + ":index-a")).get(); + + assertHeadersContainCredentialsThenClear(credentials, capturedHeaders); + + // Update credentials and ensure they are used + final String updatedCredentials = randomAlphaOfLength(41); + writeCredentialsToKeyStore(updatedCredentials); + reloadSecureSettings(); + + client().search(new SearchRequest(CLUSTER_ALIAS + ":index-a")).get(); + + assertHeadersContainCredentialsThenClear(updatedCredentials, capturedHeaders); + } + } + + private void assertHeadersContainCredentialsThenClear(String credentials, BlockingQueue> capturedHeaders) { + assertThat(capturedHeaders, is(not(empty()))); + for (Map actualHeaders : capturedHeaders) { + assertThat(actualHeaders, hasKey(CrossClusterAccessHeaders.CROSS_CLUSTER_ACCESS_CREDENTIALS_HEADER_KEY)); + assertThat( + actualHeaders.get(CrossClusterAccessHeaders.CROSS_CLUSTER_ACCESS_CREDENTIALS_HEADER_KEY), + equalTo(ApiKeyService.withApiKeyPrefix(credentials)) + ); + } + capturedHeaders.clear(); + assertThat(capturedHeaders, is(empty())); + } + + private void clearRemoteCluster() throws InterruptedException, ExecutionException { + final var builder = Settings.builder() + .putNull("cluster.remote." + CLUSTER_ALIAS + ".mode") + .putNull("cluster.remote." + CLUSTER_ALIAS + ".seeds") + .putNull("cluster.remote." + CLUSTER_ALIAS + ".proxy_address"); + clusterAdmin().updateSettings(new ClusterUpdateSettingsRequest().persistentSettings(builder)).get(); + } + + @Override + protected Settings nodeSettings() { + return Settings.builder().put(super.nodeSettings()).put("xpack.security.remote_cluster_client.ssl.enabled", false).build(); + } + + private void configureRemoteCluster(TransportAddress remoteAddress) throws InterruptedException, ExecutionException { + final Settings.Builder builder = Settings.builder(); + if (randomBoolean()) { + builder.put("cluster.remote." + CLUSTER_ALIAS + ".mode", "sniff") + .put("cluster.remote." + CLUSTER_ALIAS + ".seeds", remoteAddress.toString()) + .putNull("cluster.remote." + CLUSTER_ALIAS + ".proxy_address"); + } else { + builder.put("cluster.remote." + CLUSTER_ALIAS + ".mode", "proxy") + .put("cluster.remote." + CLUSTER_ALIAS + ".proxy_address", remoteAddress.toString()) + .putNull("cluster.remote." + CLUSTER_ALIAS + ".seeds"); + } + clusterAdmin().updateSettings(new ClusterUpdateSettingsRequest().persistentSettings(builder)).get(); + } + + private void writeCredentialsToKeyStore(String credentials) throws Exception { + final Environment environment = getInstanceFromNode(Environment.class); + final KeyStoreWrapper keyStoreWrapper = KeyStoreWrapper.create(); + keyStoreWrapper.setString("cluster.remote." + CLUSTER_ALIAS + ".credentials", credentials.toCharArray()); + keyStoreWrapper.save(environment.configFile(), new char[0], false); + } + + public static MockTransportService startTransport( + final String nodeName, + final ThreadPool threadPool, + final BlockingQueue> capturedHeaders + ) { + boolean success = false; + final Settings settings = Settings.builder() + .put("node.name", nodeName) + .put("remote_cluster_server.enabled", "true") + .put("remote_cluster.port", "0") + .put("xpack.security.remote_cluster_server.ssl.enabled", "false") + .build(); + final MockTransportService service = MockTransportService.createNewService( + settings, + VersionInformation.CURRENT, + TransportVersion.current(), + threadPool, + null + ); + try { + service.registerRequestHandler( + ClusterStateAction.NAME, + EsExecutors.DIRECT_EXECUTOR_SERVICE, + ClusterStateRequest::new, + (request, channel, task) -> { + capturedHeaders.add(Map.copyOf(threadPool.getThreadContext().getHeaders())); + channel.sendResponse( + new ClusterStateResponse(ClusterName.DEFAULT, ClusterState.builder(ClusterName.DEFAULT).build(), false) + ); + } + ); + service.registerRequestHandler( + RemoteClusterNodesAction.TYPE.name(), + EsExecutors.DIRECT_EXECUTOR_SERVICE, + RemoteClusterNodesAction.Request::new, + (request, channel, task) -> { + capturedHeaders.add(Map.copyOf(threadPool.getThreadContext().getHeaders())); + channel.sendResponse(new RemoteClusterNodesAction.Response(List.of())); + } + ); + service.registerRequestHandler( + TransportSearchShardsAction.TYPE.name(), + EsExecutors.DIRECT_EXECUTOR_SERVICE, + SearchShardsRequest::new, + (request, channel, task) -> { + capturedHeaders.add(Map.copyOf(threadPool.getThreadContext().getHeaders())); + channel.sendResponse(new SearchShardsResponse(List.of(), List.of(), Collections.emptyMap())); + } + ); + service.registerRequestHandler( + TransportSearchAction.TYPE.name(), + EsExecutors.DIRECT_EXECUTOR_SERVICE, + SearchRequest::new, + (request, channel, task) -> { + capturedHeaders.add(Map.copyOf(threadPool.getThreadContext().getHeaders())); + channel.sendResponse( + new SearchResponse( + new InternalSearchResponse( + new SearchHits(new SearchHit[0], new TotalHits(0, TotalHits.Relation.EQUAL_TO), Float.NaN), + InternalAggregations.EMPTY, + null, + null, + false, + null, + 1 + ), + null, + 1, + 1, + 0, + 100, + ShardSearchFailure.EMPTY_ARRAY, + SearchResponse.Clusters.EMPTY + ) + ); + } + ); + service.start(); + service.acceptIncomingRequests(); + success = true; + return service; + } finally { + if (success == false) { + service.close(); + } + } + } + + private void reloadSecureSettings() throws InterruptedException { + final AtomicReference reloadSettingsError = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + final SecureString emptyPassword = randomBoolean() ? new SecureString(new char[0]) : null; + clusterAdmin().prepareReloadSecureSettings() + .setSecureStorePassword(emptyPassword) + .setNodesIds(Strings.EMPTY_ARRAY) + .execute(new ActionListener<>() { + @Override + public void onResponse(NodesReloadSecureSettingsResponse nodesReloadResponse) { + try { + assertThat(nodesReloadResponse, notNullValue()); + final Map nodesMap = nodesReloadResponse.getNodesMap(); + assertThat(nodesMap.size(), equalTo(1)); + for (final NodesReloadSecureSettingsResponse.NodeResponse nodeResponse : nodesReloadResponse.getNodes()) { + assertThat(nodeResponse.reloadException(), nullValue()); + } + } catch (final AssertionError e) { + reloadSettingsError.set(e); + } finally { + latch.countDown(); + } + } + + @Override + public void onFailure(Exception e) { + reloadSettingsError.set(new AssertionError("Nodes request failed", e)); + latch.countDown(); + } + }); + latch.await(); + if (reloadSettingsError.get() != null) { + throw reloadSettingsError.get(); + } + } +} diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java index 6d7f6fcd3822b..349cebe7f705f 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java @@ -13,6 +13,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.lucene.util.SetOnce; +import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.TransportVersion; @@ -156,6 +157,7 @@ import org.elasticsearch.xpack.core.security.action.service.GetServiceAccountCredentialsAction; import org.elasticsearch.xpack.core.security.action.service.GetServiceAccountNodesCredentialsAction; import org.elasticsearch.xpack.core.security.action.settings.GetSecuritySettingsAction; +import org.elasticsearch.xpack.core.security.action.settings.ReloadRemoteClusterCredentialsAction; import org.elasticsearch.xpack.core.security.action.settings.UpdateSecuritySettingsAction; import org.elasticsearch.xpack.core.security.action.token.CreateTokenAction; import org.elasticsearch.xpack.core.security.action.token.InvalidateTokenAction; @@ -247,6 +249,7 @@ import org.elasticsearch.xpack.security.action.service.TransportGetServiceAccountCredentialsAction; import org.elasticsearch.xpack.security.action.service.TransportGetServiceAccountNodesCredentialsAction; import org.elasticsearch.xpack.security.action.settings.TransportGetSecuritySettingsAction; +import org.elasticsearch.xpack.security.action.settings.TransportReloadRemoteClusterCredentialsAction; import org.elasticsearch.xpack.security.action.settings.TransportUpdateSecuritySettingsAction; import org.elasticsearch.xpack.security.action.token.TransportCreateTokenAction; import org.elasticsearch.xpack.security.action.token.TransportInvalidateTokenAction; @@ -367,7 +370,6 @@ import org.elasticsearch.xpack.security.support.CacheInvalidatorRegistry; import org.elasticsearch.xpack.security.support.ExtensionComponents; import org.elasticsearch.xpack.security.support.SecuritySystemIndices; -import org.elasticsearch.xpack.security.transport.RemoteClusterCredentialsResolver; import org.elasticsearch.xpack.security.transport.SecurityHttpSettings; import org.elasticsearch.xpack.security.transport.SecurityServerTransportInterceptor; import org.elasticsearch.xpack.security.transport.filter.IPFilter; @@ -557,6 +559,7 @@ public class Security extends Plugin private final SetOnce reservedRoleMappingAction = new SetOnce<>(); private final SetOnce workflowService = new SetOnce<>(); private final SetOnce realms = new SetOnce<>(); + private final SetOnce client = new SetOnce<>(); public Security(Settings settings) { this(settings, Collections.emptyList()); @@ -576,25 +579,30 @@ public Security(Settings settings) { runStartupChecks(settings); Automatons.updateConfiguration(settings); } else { - final List remoteClusterCredentialsSettingKeys = RemoteClusterService.REMOTE_CLUSTER_CREDENTIALS.getAllConcreteSettings( - settings - ).map(Setting::getKey).sorted().toList(); - if (false == remoteClusterCredentialsSettingKeys.isEmpty()) { - throw new IllegalArgumentException( - format( - "Found [%s] remote clusters with credentials [%s]. Security [%s] must be enabled to connect to them. " - + "Please either enable security or remove these settings from the keystore.", - remoteClusterCredentialsSettingKeys.size(), - Strings.collectionToCommaDelimitedString(remoteClusterCredentialsSettingKeys), - XPackSettings.SECURITY_ENABLED.getKey() - ) - ); - } + ensureNoRemoteClusterCredentialsOnDisabledSecurity(settings); this.bootstrapChecks.set(Collections.emptyList()); } this.securityExtensions.addAll(extensions); } + private void ensureNoRemoteClusterCredentialsOnDisabledSecurity(Settings settings) { + assert false == enabled; + final List remoteClusterCredentialsSettingKeys = RemoteClusterService.REMOTE_CLUSTER_CREDENTIALS.getAllConcreteSettings( + settings + ).map(Setting::getKey).sorted().toList(); + if (false == remoteClusterCredentialsSettingKeys.isEmpty()) { + throw new IllegalArgumentException( + format( + "Found [%s] remote clusters with credentials [%s]. Security [%s] must be enabled to connect to them. " + + "Please either enable security or remove these settings from the keystore.", + remoteClusterCredentialsSettingKeys.size(), + Strings.collectionToCommaDelimitedString(remoteClusterCredentialsSettingKeys), + XPackSettings.SECURITY_ENABLED.getKey() + ) + ); + } + } + private static void runStartupChecks(Settings settings) { validateRealmSettings(settings); if (XPackSettings.FIPS_MODE_ENABLED.get(settings)) { @@ -619,6 +627,14 @@ protected XPackLicenseState getLicenseState() { return XPackPlugin.getSharedLicenseState(); } + protected Client getClient() { + return client.get(); + } + + protected Realms getRealms() { + return realms.get(); + } + @Override public Collection createComponents(PluginServices services) { try { @@ -657,6 +673,8 @@ Collection createComponents( return Collections.singletonList(new SecurityUsageServices(null, null, null, null, null, null)); } + this.client.set(client); + // The settings in `environment` may have additional values over what was provided during construction // See Plugin#additionalSettings() this.settings = environment.settings(); @@ -983,8 +1001,6 @@ Collection createComponents( ipFilter.set(new IPFilter(settings, auditTrailService, clusterService.getClusterSettings(), getLicenseState())); components.add(ipFilter.get()); - final RemoteClusterCredentialsResolver remoteClusterCredentialsResolver = new RemoteClusterCredentialsResolver(settings); - DestructiveOperations destructiveOperations = new DestructiveOperations(settings, clusterService.getClusterSettings()); crossClusterAccessAuthcService.set(new CrossClusterAccessAuthenticationService(clusterService, apiKeyService, authcService.get())); components.add(crossClusterAccessAuthcService.get()); @@ -998,7 +1014,6 @@ Collection createComponents( securityContext.get(), destructiveOperations, crossClusterAccessAuthcService.get(), - remoteClusterCredentialsResolver, getLicenseState() ) ); @@ -1351,6 +1366,7 @@ public void onIndexModule(IndexModule module) { new ActionHandler<>(SetProfileEnabledAction.INSTANCE, TransportSetProfileEnabledAction.class), new ActionHandler<>(GetSecuritySettingsAction.INSTANCE, TransportGetSecuritySettingsAction.class), new ActionHandler<>(UpdateSecuritySettingsAction.INSTANCE, TransportUpdateSecuritySettingsAction.class), + new ActionHandler<>(ReloadRemoteClusterCredentialsAction.INSTANCE, TransportReloadRemoteClusterCredentialsAction.class), usageAction, infoAction ).filter(Objects::nonNull).toList(); @@ -1890,16 +1906,54 @@ public BiConsumer getJoinValidator() { @Override public void reload(Settings settings) throws Exception { if (enabled) { - realms.get().stream().filter(r -> JwtRealmSettings.TYPE.equals(r.realmRef().getType())).forEach(realm -> { - if (realm instanceof JwtRealm jwtRealm) { - jwtRealm.rotateClientSecret( - CLIENT_AUTHENTICATION_SHARED_SECRET.getConcreteSettingForNamespace(realm.realmRef().getName()).get(settings) - ); - } - }); + final List reloadExceptions = new ArrayList<>(); + try { + reloadRemoteClusterCredentials(settings); + } catch (Exception ex) { + reloadExceptions.add(ex); + } + + try { + reloadSharedSecretsForJwtRealms(settings); + } catch (Exception ex) { + reloadExceptions.add(ex); + } + + if (false == reloadExceptions.isEmpty()) { + final var combinedException = new ElasticsearchException( + "secure settings reload failed for one or more security components" + ); + reloadExceptions.forEach(combinedException::addSuppressed); + throw combinedException; + } + } else { + ensureNoRemoteClusterCredentialsOnDisabledSecurity(settings); } } + private void reloadSharedSecretsForJwtRealms(Settings settingsWithKeystore) { + getRealms().stream().filter(r -> JwtRealmSettings.TYPE.equals(r.realmRef().getType())).forEach(realm -> { + if (realm instanceof JwtRealm jwtRealm) { + jwtRealm.rotateClientSecret( + CLIENT_AUTHENTICATION_SHARED_SECRET.getConcreteSettingForNamespace(realm.realmRef().getName()).get(settingsWithKeystore) + ); + } + }); + } + + /** + * This method uses a transport action internally to access classes that are injectable but not part of the plugin contract. + * See {@link TransportReloadRemoteClusterCredentialsAction} for more context. + */ + private void reloadRemoteClusterCredentials(Settings settingsWithKeystore) { + // Accepting a blocking call here since the underlying action is local-only and only performs fast in-memory ops + // (extracts a subset of passed in `settingsWithKeystore` and stores them in a map) + getClient().execute( + ReloadRemoteClusterCredentialsAction.INSTANCE, + new ReloadRemoteClusterCredentialsAction.Request(settingsWithKeystore) + ).actionGet(); + } + static final class ValidateLicenseForFIPS implements BiConsumer { private final boolean inFipsMode; private final LicenseService licenseService; diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/settings/TransportReloadRemoteClusterCredentialsAction.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/settings/TransportReloadRemoteClusterCredentialsAction.java new file mode 100644 index 0000000000000..de696a3e0353f --- /dev/null +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/settings/TransportReloadRemoteClusterCredentialsAction.java @@ -0,0 +1,54 @@ +/* + * 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.security.action.settings; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.action.support.TransportAction; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.tasks.Task; +import org.elasticsearch.transport.RemoteClusterService; +import org.elasticsearch.transport.TransportService; +import org.elasticsearch.xpack.core.security.action.settings.ReloadRemoteClusterCredentialsAction; +import org.elasticsearch.xpack.security.Security; + +/** + * This is a local-only action which updates remote cluster credentials for remote cluster connections, from keystore settings reloaded via + * a call to {@link org.elasticsearch.rest.action.admin.cluster.RestReloadSecureSettingsAction}. + * + * It's invoked as part of the {@link Security#reload(Settings)} call. + * + * This action is largely an implementation detail to work around the fact that Security is a plugin without direct access to many core + * classes, including the {@link RemoteClusterService} which is required for credentials update. A transport action gives us access to + * the {@link RemoteClusterService} which is injectable but not part of the plugin contract. + */ +public class TransportReloadRemoteClusterCredentialsAction extends TransportAction< + ReloadRemoteClusterCredentialsAction.Request, + ActionResponse.Empty> { + + private final RemoteClusterService remoteClusterService; + + @Inject + public TransportReloadRemoteClusterCredentialsAction(TransportService transportService, ActionFilters actionFilters) { + super(ReloadRemoteClusterCredentialsAction.NAME, actionFilters, transportService.getTaskManager()); + this.remoteClusterService = transportService.getRemoteClusterService(); + } + + @Override + protected void doExecute( + Task task, + ReloadRemoteClusterCredentialsAction.Request request, + ActionListener listener + ) { + // We avoid stashing and marking context as system to keep the action as minimal as possible (i.e., avoid copying context) + remoteClusterService.updateRemoteClusterCredentials(request.getSettings()); + listener.onResponse(ActionResponse.Empty.INSTANCE); + } +} diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/RemoteClusterCredentialsResolver.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/RemoteClusterCredentialsResolver.java deleted file mode 100644 index 93735a700bf92..0000000000000 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/RemoteClusterCredentialsResolver.java +++ /dev/null @@ -1,51 +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.security.transport; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.settings.SecureString; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.xpack.security.authc.ApiKeyService; - -import java.util.Map; -import java.util.Optional; - -import static org.elasticsearch.transport.RemoteClusterService.REMOTE_CLUSTER_CREDENTIALS; - -public class RemoteClusterCredentialsResolver { - - private static final Logger logger = LogManager.getLogger(RemoteClusterCredentialsResolver.class); - - private final Map clusterCredentials; - - public RemoteClusterCredentialsResolver(final Settings settings) { - this.clusterCredentials = REMOTE_CLUSTER_CREDENTIALS.getAsMap(settings); - logger.debug( - "Read cluster credentials for remote clusters [{}]", - Strings.collectionToCommaDelimitedString(clusterCredentials.keySet()) - ); - } - - public Optional resolve(final String clusterAlias) { - final SecureString apiKey = clusterCredentials.get(clusterAlias); - if (apiKey == null) { - return Optional.empty(); - } else { - return Optional.of(new RemoteClusterCredentials(clusterAlias, ApiKeyService.withApiKeyPrefix(apiKey.toString()))); - } - } - - record RemoteClusterCredentials(String clusterAlias, String credentials) { - @Override - public String toString() { - return "RemoteClusterCredentials{clusterAlias='" + clusterAlias + "', credentials='::es_redacted::'}"; - } - } -} diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportInterceptor.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportInterceptor.java index 53dd31fe46793..162cabf5297ce 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportInterceptor.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportInterceptor.java @@ -12,6 +12,7 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.admin.cluster.state.ClusterStateAction; import org.elasticsearch.action.support.DestructiveOperations; +import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.ssl.SslConfiguration; import org.elasticsearch.common.util.Maps; @@ -24,6 +25,7 @@ import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.RemoteConnectionManager; +import org.elasticsearch.transport.RemoteConnectionManager.RemoteClusterAliasWithCredentials; import org.elasticsearch.transport.SendRequestTransportException; import org.elasticsearch.transport.Transport; import org.elasticsearch.transport.TransportChannel; @@ -46,6 +48,7 @@ import org.elasticsearch.xpack.core.ssl.SSLService; import org.elasticsearch.xpack.security.Security; import org.elasticsearch.xpack.security.audit.AuditUtil; +import org.elasticsearch.xpack.security.authc.ApiKeyService; import org.elasticsearch.xpack.security.authc.AuthenticationService; import org.elasticsearch.xpack.security.authc.CrossClusterAccessAuthenticationService; import org.elasticsearch.xpack.security.authc.CrossClusterAccessHeaders; @@ -63,7 +66,6 @@ import static org.elasticsearch.transport.RemoteClusterPortSettings.REMOTE_CLUSTER_PROFILE; import static org.elasticsearch.transport.RemoteClusterPortSettings.REMOTE_CLUSTER_SERVER_ENABLED; import static org.elasticsearch.transport.RemoteClusterPortSettings.TRANSPORT_VERSION_ADVANCED_REMOTE_CLUSTER_SECURITY; -import static org.elasticsearch.xpack.security.transport.RemoteClusterCredentialsResolver.RemoteClusterCredentials; public class SecurityServerTransportInterceptor implements TransportInterceptor { @@ -85,8 +87,7 @@ public class SecurityServerTransportInterceptor implements TransportInterceptor private final Settings settings; private final SecurityContext securityContext; private final CrossClusterAccessAuthenticationService crossClusterAccessAuthcService; - private final RemoteClusterCredentialsResolver remoteClusterCredentialsResolver; - private final Function> remoteClusterAliasResolver; + private final Function> remoteClusterCredentialsResolver; private final XPackLicenseState licenseState; public SecurityServerTransportInterceptor( @@ -98,7 +99,6 @@ public SecurityServerTransportInterceptor( SecurityContext securityContext, DestructiveOperations destructiveOperations, CrossClusterAccessAuthenticationService crossClusterAccessAuthcService, - RemoteClusterCredentialsResolver remoteClusterCredentialsResolver, XPackLicenseState licenseState ) { this( @@ -110,9 +110,8 @@ public SecurityServerTransportInterceptor( securityContext, destructiveOperations, crossClusterAccessAuthcService, - remoteClusterCredentialsResolver, licenseState, - RemoteConnectionManager::resolveRemoteClusterAlias + RemoteConnectionManager::resolveRemoteClusterAliasWithCredentials ); } @@ -125,10 +124,9 @@ public SecurityServerTransportInterceptor( SecurityContext securityContext, DestructiveOperations destructiveOperations, CrossClusterAccessAuthenticationService crossClusterAccessAuthcService, - RemoteClusterCredentialsResolver remoteClusterCredentialsResolver, XPackLicenseState licenseState, // Inject for simplified testing - Function> remoteClusterAliasResolver + Function> remoteClusterCredentialsResolver ) { this.settings = settings; this.threadPool = threadPool; @@ -139,7 +137,6 @@ public SecurityServerTransportInterceptor( this.crossClusterAccessAuthcService = crossClusterAccessAuthcService; this.licenseState = licenseState; this.remoteClusterCredentialsResolver = remoteClusterCredentialsResolver; - this.remoteClusterAliasResolver = remoteClusterAliasResolver; this.profileFilters = initializeProfileFilters(destructiveOperations); } @@ -159,7 +156,8 @@ public void sendRequest( TransportResponseHandler handler ) { assertNoCrossClusterAccessHeadersInContext(); - final Optional remoteClusterAlias = remoteClusterAliasResolver.apply(connection); + final Optional remoteClusterAlias = remoteClusterCredentialsResolver.apply(connection) + .map(RemoteClusterAliasWithCredentials::clusterAlias); if (PreAuthorizationUtils.shouldRemoveParentAuthorizationFromThreadContext(remoteClusterAlias, action, securityContext)) { securityContext.executeAfterRemovingParentAuthorization(original -> { sendRequestInner( @@ -278,22 +276,23 @@ public void sendRequest( * Returns cluster credentials if the connection is remote, and cluster credentials are set up for the target cluster. */ private Optional getRemoteClusterCredentials(Transport.Connection connection) { - final Optional optionalRemoteClusterAlias = remoteClusterAliasResolver.apply(connection); - if (optionalRemoteClusterAlias.isEmpty()) { + final Optional remoteClusterAliasWithCredentials = remoteClusterCredentialsResolver + .apply(connection); + if (remoteClusterAliasWithCredentials.isEmpty()) { logger.trace("Connection is not remote"); return Optional.empty(); } - final String remoteClusterAlias = optionalRemoteClusterAlias.get(); - final Optional remoteClusterCredentials = remoteClusterCredentialsResolver.resolve( - remoteClusterAlias - ); - if (remoteClusterCredentials.isEmpty()) { + final String remoteClusterAlias = remoteClusterAliasWithCredentials.get().clusterAlias(); + final SecureString remoteClusterCredentials = remoteClusterAliasWithCredentials.get().credentials(); + if (remoteClusterCredentials == null) { logger.trace("No cluster credentials are configured for remote cluster [{}]", remoteClusterAlias); return Optional.empty(); } - return remoteClusterCredentials; + return Optional.of( + new RemoteClusterCredentials(remoteClusterAlias, ApiKeyService.withApiKeyPrefix(remoteClusterCredentials.toString())) + ); } private void sendWithCrossClusterAccessHeaders( @@ -442,7 +441,7 @@ private void sendWithUser( throw new IllegalStateException("there should always be a user when sending a message for action [" + action + "]"); } - assert securityContext.getParentAuthorization() == null || remoteClusterAliasResolver.apply(connection).isPresent() == false + assert securityContext.getParentAuthorization() == null || remoteClusterCredentialsResolver.apply(connection).isEmpty() : "parent authorization header should not be set for remote cluster requests"; try { @@ -663,4 +662,12 @@ public void onFailure(Exception e) { } } } + + record RemoteClusterCredentials(String clusterAlias, String credentials) { + + @Override + public String toString() { + return "RemoteClusterCredentials{clusterAlias='" + clusterAlias + "', credentials='::es_redacted::'}"; + } + } } diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/LocalStateSecurity.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/LocalStateSecurity.java index d44e7c27d760e..a2aa04e0f56c3 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/LocalStateSecurity.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/LocalStateSecurity.java @@ -16,6 +16,7 @@ import org.elasticsearch.license.LicenseService; import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.plugins.ReloadablePlugin; import org.elasticsearch.protocol.xpack.XPackInfoRequest; import org.elasticsearch.protocol.xpack.XPackInfoResponse; import org.elasticsearch.protocol.xpack.XPackUsageRequest; @@ -36,7 +37,7 @@ import java.util.Collections; import java.util.List; -public class LocalStateSecurity extends LocalStateCompositeXPackPlugin { +public class LocalStateSecurity extends LocalStateCompositeXPackPlugin implements ReloadablePlugin { public static class SecurityTransportXPackUsageAction extends TransportXPackUsageAction { @Inject @@ -130,4 +131,15 @@ protected Class> public List plugins() { return plugins; } + + @Override + public void reload(Settings settings) throws Exception { + plugins.stream().filter(p -> p instanceof ReloadablePlugin).forEach(p -> { + try { + ((ReloadablePlugin) p).reload(settings); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } } diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java index 6773da137ac96..75e134691225d 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java @@ -9,10 +9,13 @@ import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.Version; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionModule; +import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterState; @@ -72,6 +75,7 @@ import org.elasticsearch.xpack.core.security.SecurityContext; import org.elasticsearch.xpack.core.security.SecurityExtension; import org.elasticsearch.xpack.core.security.SecurityField; +import org.elasticsearch.xpack.core.security.action.settings.ReloadRemoteClusterCredentialsAction; import org.elasticsearch.xpack.core.security.authc.Authentication; import org.elasticsearch.xpack.core.security.authc.AuthenticationTestHelper; import org.elasticsearch.xpack.core.security.authc.Realm; @@ -116,6 +120,7 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; +import java.util.stream.Stream; import static java.util.Collections.emptyMap; import static org.elasticsearch.xpack.core.security.authc.RealmSettings.getFullSettingKey; @@ -133,7 +138,9 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class SecurityTests extends ESTestCase { @@ -877,6 +884,23 @@ public void testSecurityMustBeEnableToConnectRemoteClusterWithCredentials() { + "Please either enable security or remove these settings from the keystore." ) ); + + // Security off, remote cluster with credentials on reload call + final MockSecureSettings secureSettings5 = new MockSecureSettings(); + secureSettings5.setString("cluster.remote.my1.credentials", randomAlphaOfLength(20)); + secureSettings5.setString("cluster.remote.my2.credentials", randomAlphaOfLength(20)); + final Settings.Builder builder5 = Settings.builder().setSecureSettings(secureSettings5); + // Use builder with security disabled to construct valid Security instance + final var security = new Security(builder2.build()); + final IllegalArgumentException e5 = expectThrows(IllegalArgumentException.class, () -> security.reload(builder5.build())); + assertThat( + e5.getMessage(), + containsString( + "Found [2] remote clusters with credentials [cluster.remote.my1.credentials,cluster.remote.my2.credentials]. " + + "Security [xpack.security.enabled] must be enabled to connect to them. " + + "Please either enable security or remove these settings from the keystore." + ) + ); } public void testLoadExtensions() throws Exception { @@ -905,6 +929,84 @@ public List loadExtensions(Class extensionPointType) { assertThat(registry, instanceOf(DummyOperatorOnlyRegistry.class)); } + public void testReload() throws Exception { + final Settings settings = Settings.builder().put("xpack.security.enabled", true).put("path.home", createTempDir()).build(); + + final PlainActionFuture value = new PlainActionFuture<>(); + value.onResponse(ActionResponse.Empty.INSTANCE); + final Client mockedClient = mock(Client.class); + + final Realms mockedRealms = mock(Realms.class); + when(mockedRealms.stream()).thenReturn(Stream.of()); + when(mockedClient.execute(eq(ReloadRemoteClusterCredentialsAction.INSTANCE), any())).thenReturn(value); + security = new Security(settings, Collections.emptyList()) { + @Override + protected Client getClient() { + return mockedClient; + } + + @Override + protected Realms getRealms() { + return mockedRealms; + } + }; + + final Settings inputSettings = Settings.EMPTY; + security.reload(inputSettings); + + verify(mockedClient).execute(eq(ReloadRemoteClusterCredentialsAction.INSTANCE), any()); + verify(mockedRealms).stream(); + } + + public void testReloadWithFailures() { + final Settings settings = Settings.builder().put("xpack.security.enabled", true).put("path.home", createTempDir()).build(); + + final boolean failRemoteClusterCredentialsReload = randomBoolean(); + final PlainActionFuture value = new PlainActionFuture<>(); + if (failRemoteClusterCredentialsReload) { + value.onFailure(new RuntimeException("failed remote cluster credentials reload")); + } else { + value.onResponse(ActionResponse.Empty.INSTANCE); + } + final Client mockedClient = mock(Client.class); + when(mockedClient.execute(eq(ReloadRemoteClusterCredentialsAction.INSTANCE), any())).thenReturn(value); + + final Realms mockedRealms = mock(Realms.class); + final boolean failRealmsReload = (false == failRemoteClusterCredentialsReload) || randomBoolean(); + if (failRealmsReload) { + when(mockedRealms.stream()).thenThrow(new RuntimeException("failed jwt realms reload")); + } else { + when(mockedRealms.stream()).thenReturn(Stream.of()); + } + security = new Security(settings, Collections.emptyList()) { + @Override + protected Client getClient() { + return mockedClient; + } + + @Override + protected Realms getRealms() { + return mockedRealms; + } + }; + + final Settings inputSettings = Settings.EMPTY; + final var exception = expectThrows(ElasticsearchException.class, () -> security.reload(inputSettings)); + + assertThat(exception.getMessage(), containsString("secure settings reload failed for one or more security component")); + if (failRemoteClusterCredentialsReload) { + assertThat(exception.getSuppressed()[0].getMessage(), containsString("failed remote cluster credentials reload")); + if (failRealmsReload) { + assertThat(exception.getSuppressed()[1].getMessage(), containsString("failed jwt realms reload")); + } + } else { + assertThat(exception.getSuppressed()[0].getMessage(), containsString("failed jwt realms reload")); + } + // Verify both called despite failure + verify(mockedClient).execute(eq(ReloadRemoteClusterCredentialsAction.INSTANCE), any()); + verify(mockedRealms).stream(); + } + public void testLoadNoExtensions() throws Exception { Settings settings = Settings.builder() .put("xpack.security.enabled", true) diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/RemoteClusterCredentialsResolverTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/RemoteClusterCredentialsResolverTests.java deleted file mode 100644 index debb50384e217..0000000000000 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/RemoteClusterCredentialsResolverTests.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.security.transport; - -import org.elasticsearch.common.settings.MockSecureSettings; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.test.ESTestCase; -import org.elasticsearch.xpack.security.authc.ApiKeyService; - -import java.util.Optional; - -import static org.elasticsearch.xpack.security.transport.RemoteClusterCredentialsResolver.RemoteClusterCredentials; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; - -public class RemoteClusterCredentialsResolverTests extends ESTestCase { - - public void testResolveRemoteClusterCredentials() { - final String clusterNameA = "clusterA"; - final String clusterDoesNotExist = randomAlphaOfLength(10); - final Settings.Builder builder = Settings.builder(); - - final String secret = randomAlphaOfLength(20); - final MockSecureSettings secureSettings = new MockSecureSettings(); - secureSettings.setString("cluster.remote." + clusterNameA + ".credentials", secret); - final Settings settings = builder.setSecureSettings(secureSettings).build(); - RemoteClusterCredentialsResolver remoteClusterAuthorizationResolver = new RemoteClusterCredentialsResolver(settings); - final Optional remoteClusterCredentials = remoteClusterAuthorizationResolver.resolve(clusterNameA); - assertThat(remoteClusterCredentials.isPresent(), is(true)); - assertThat(remoteClusterCredentials.get().clusterAlias(), equalTo(clusterNameA)); - assertThat(remoteClusterCredentials.get().credentials(), equalTo(ApiKeyService.withApiKeyPrefix(secret))); - assertThat(remoteClusterAuthorizationResolver.resolve(clusterDoesNotExist), is(Optional.empty())); - } -} 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 9bd5d416940d3..822c04be4363f 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 @@ -18,6 +18,7 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.settings.ClusterSettings; +import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.ssl.SslClientAuthenticationMode; import org.elasticsearch.common.ssl.SslConfiguration; @@ -33,6 +34,7 @@ import org.elasticsearch.threadpool.TestThreadPool; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.RemoteClusterPortSettings; +import org.elasticsearch.transport.RemoteConnectionManager.RemoteClusterAliasWithCredentials; import org.elasticsearch.transport.SendRequestTransportException; import org.elasticsearch.transport.Transport; import org.elasticsearch.transport.Transport.Connection; @@ -77,6 +79,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; +import java.util.function.Function; import static org.elasticsearch.cluster.metadata.DataStreamLifecycle.DATA_STREAM_LIFECYCLE_ORIGIN; import static org.elasticsearch.test.ActionListenerUtils.anyActionListener; @@ -87,7 +90,6 @@ import static org.elasticsearch.xpack.core.security.authc.CrossClusterAccessSubjectInfo.CROSS_CLUSTER_ACCESS_SUBJECT_INFO_HEADER_KEY; import static org.elasticsearch.xpack.core.security.authz.RoleDescriptorTests.randomUniquelyNamedRoleDescriptors; import static org.elasticsearch.xpack.security.authc.CrossClusterAccessHeaders.CROSS_CLUSTER_ACCESS_CREDENTIALS_HEADER_KEY; -import static org.elasticsearch.xpack.security.transport.RemoteClusterCredentialsResolver.RemoteClusterCredentials; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.equalTo; @@ -153,7 +155,6 @@ public void testSendAsync() throws Exception { new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), - new RemoteClusterCredentialsResolver(settings), mockLicenseState ); ClusterServiceUtils.setState(clusterService, clusterService.state()); // force state update to trigger listener @@ -205,7 +206,6 @@ public void testSendAsyncSwitchToSystem() throws Exception { new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), - new RemoteClusterCredentialsResolver(settings), mockLicenseState ); ClusterServiceUtils.setState(clusterService, clusterService.state()); // force state update to trigger listener @@ -250,7 +250,6 @@ public void testSendWithoutUser() throws Exception { new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), - new RemoteClusterCredentialsResolver(settings), mockLicenseState ) { @Override @@ -313,7 +312,6 @@ public void testSendToNewerVersionSetsCorrectVersion() throws Exception { new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), - new RemoteClusterCredentialsResolver(settings), mockLicenseState ); ClusterServiceUtils.setState(clusterService, clusterService.state()); // force state update to trigger listener @@ -382,7 +380,6 @@ public void testSendToOlderVersionSetsCorrectVersion() throws Exception { new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), - new RemoteClusterCredentialsResolver(settings), mockLicenseState ); ClusterServiceUtils.setState(clusterService, clusterService.state()); // force state update to trigger listener @@ -449,7 +446,6 @@ public void testSetUserBasedOnActionOrigin() { new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), - new RemoteClusterCredentialsResolver(settings), mockLicenseState ); @@ -604,7 +600,6 @@ public void testSendWithCrossClusterAccessHeadersWithUnsupportedLicense() throws AuthenticationTestHelper.builder().build().writeToContext(threadContext); final String remoteClusterAlias = randomAlphaOfLengthBetween(5, 10); - final RemoteClusterCredentialsResolver remoteClusterCredentialsResolver = mockRemoteClusterCredentialsResolver(remoteClusterAlias); final SecurityServerTransportInterceptor interceptor = new SecurityServerTransportInterceptor( settings, @@ -618,9 +613,8 @@ public void testSendWithCrossClusterAccessHeadersWithUnsupportedLicense() throws new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), - remoteClusterCredentialsResolver, unsupportedLicenseState, - ignored -> Optional.of(remoteClusterAlias) + mockRemoteClusterCredentialsResolver(remoteClusterAlias) ); final AsyncSender sender = interceptor.interceptSender(mock(AsyncSender.class, ignored -> { @@ -661,18 +655,16 @@ public TransportResponse read(StreamInput in) { actualException.get().getCause().getMessage(), equalTo("current license is non-compliant for [" + Security.ADVANCED_REMOTE_CLUSTER_SECURITY_FEATURE.getName() + "]") ); - verify(remoteClusterCredentialsResolver, times(1)).resolve(eq(remoteClusterAlias)); assertThat(securityContext.getThreadContext().getHeader(CROSS_CLUSTER_ACCESS_SUBJECT_INFO_HEADER_KEY), nullValue()); assertThat(securityContext.getThreadContext().getHeader(CROSS_CLUSTER_ACCESS_CREDENTIALS_HEADER_KEY), nullValue()); } - private RemoteClusterCredentialsResolver mockRemoteClusterCredentialsResolver(String remoteClusterAlias) { - final RemoteClusterCredentialsResolver remoteClusterCredentialsResolver = mock(RemoteClusterCredentialsResolver.class); - final String remoteClusterCredential = ApiKeyService.withApiKeyPrefix(randomAlphaOfLengthBetween(10, 42)); - when(remoteClusterCredentialsResolver.resolve(any())).thenReturn( - Optional.of(new RemoteClusterCredentials(remoteClusterAlias, remoteClusterCredential)) + private Function> mockRemoteClusterCredentialsResolver( + String remoteClusterAlias + ) { + return connection -> Optional.of( + new RemoteClusterAliasWithCredentials(remoteClusterAlias, new SecureString(randomAlphaOfLengthBetween(10, 42).toCharArray())) ); - return remoteClusterCredentialsResolver; } public void testSendWithCrossClusterAccessHeadersForSystemUserRegularAction() throws Exception { @@ -736,12 +728,9 @@ private void doTestSendWithCrossClusterAccessHeaders( ) throws IOException { authentication.writeToContext(threadContext); final String expectedRequestId = AuditUtil.getOrGenerateRequestId(threadContext); - final RemoteClusterCredentialsResolver remoteClusterCredentialsResolver = mock(RemoteClusterCredentialsResolver.class); final String remoteClusterAlias = randomAlphaOfLengthBetween(5, 10); - final String remoteClusterCredential = ApiKeyService.withApiKeyPrefix(randomAlphaOfLengthBetween(10, 42)); - when(remoteClusterCredentialsResolver.resolve(any())).thenReturn( - Optional.of(new RemoteClusterCredentials(remoteClusterAlias, remoteClusterCredential)) - ); + final String encodedApiKey = randomAlphaOfLengthBetween(10, 42); + final String remoteClusterCredential = ApiKeyService.withApiKeyPrefix(encodedApiKey); final AuthorizationService authzService = mock(AuthorizationService.class); // We capture the listener so that we can complete the full flow, by calling onResponse further down @SuppressWarnings("unchecked") @@ -760,9 +749,8 @@ private void doTestSendWithCrossClusterAccessHeaders( new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), - remoteClusterCredentialsResolver, mockLicenseState, - ignored -> Optional.of(remoteClusterAlias) + ignored -> Optional.of(new RemoteClusterAliasWithCredentials(remoteClusterAlias, new SecureString(encodedApiKey.toCharArray()))) ); final AtomicBoolean calledWrappedSender = new AtomicBoolean(false); @@ -861,7 +849,6 @@ public TransportResponse read(StreamInput in) { } assertThat(sentCredential.get(), equalTo(remoteClusterCredential)); verify(securityContext, never()).executeAsInternalUser(any(), any(), anyConsumer()); - verify(remoteClusterCredentialsResolver, times(1)).resolve(eq(remoteClusterAlias)); assertThat(securityContext.getThreadContext().getHeader(CROSS_CLUSTER_ACCESS_SUBJECT_INFO_HEADER_KEY), nullValue()); assertThat(securityContext.getThreadContext().getHeader(CROSS_CLUSTER_ACCESS_CREDENTIALS_HEADER_KEY), nullValue()); assertThat(AuditUtil.extractRequestId(securityContext.getThreadContext()), equalTo(expectedRequestId)); @@ -874,15 +861,9 @@ public void testSendWithUserIfCrossClusterAccessHeadersConditionNotMet() throws if (false == (notRemoteConnection || noCredential)) { noCredential = true; } + final boolean finalNoCredential = noCredential; final String remoteClusterAlias = randomAlphaOfLengthBetween(5, 10); - final RemoteClusterCredentialsResolver remoteClusterCredentialsResolver = mock(RemoteClusterCredentialsResolver.class); - when(remoteClusterCredentialsResolver.resolve(any())).thenReturn( - noCredential - ? Optional.empty() - : Optional.of( - new RemoteClusterCredentials(remoteClusterAlias, ApiKeyService.withApiKeyPrefix(randomAlphaOfLengthBetween(10, 42))) - ) - ); + final String encodedApiKey = randomAlphaOfLengthBetween(10, 42); final AuthenticationTestHelper.AuthenticationTestBuilder builder = AuthenticationTestHelper.builder(); final Authentication authentication = randomFrom( builder.apiKey().build(), @@ -904,9 +885,12 @@ public void testSendWithUserIfCrossClusterAccessHeadersConditionNotMet() throws new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), - remoteClusterCredentialsResolver, mockLicenseState, - ignored -> notRemoteConnection ? Optional.empty() : Optional.of(remoteClusterAlias) + ignored -> notRemoteConnection + ? Optional.empty() + : (finalNoCredential + ? Optional.of(new RemoteClusterAliasWithCredentials(remoteClusterAlias, null)) + : Optional.of(new RemoteClusterAliasWithCredentials(remoteClusterAlias, new SecureString(encodedApiKey.toCharArray())))) ); final AtomicBoolean calledWrappedSender = new AtomicBoolean(false); @@ -944,12 +928,9 @@ public void testSendWithCrossClusterAccessHeadersThrowsOnOldConnection() throws .realm() .build(); authentication.writeToContext(threadContext); - final RemoteClusterCredentialsResolver remoteClusterCredentialsResolver = mock(RemoteClusterCredentialsResolver.class); final String remoteClusterAlias = randomAlphaOfLengthBetween(5, 10); - final String remoteClusterCredential = ApiKeyService.withApiKeyPrefix(randomAlphaOfLengthBetween(10, 42)); - when(remoteClusterCredentialsResolver.resolve(any())).thenReturn( - Optional.of(new RemoteClusterCredentials(remoteClusterAlias, remoteClusterCredential)) - ); + final String encodedApiKey = randomAlphaOfLengthBetween(10, 42); + final String remoteClusterCredential = ApiKeyService.withApiKeyPrefix(encodedApiKey); final SecurityServerTransportInterceptor interceptor = new SecurityServerTransportInterceptor( settings, @@ -963,9 +944,8 @@ public void testSendWithCrossClusterAccessHeadersThrowsOnOldConnection() throws new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), - remoteClusterCredentialsResolver, mockLicenseState, - ignored -> Optional.of(remoteClusterAlias) + ignored -> Optional.of(new RemoteClusterAliasWithCredentials(remoteClusterAlias, new SecureString(encodedApiKey.toCharArray()))) ); final AsyncSender sender = interceptor.interceptSender(new AsyncSender() { @@ -1029,7 +1009,6 @@ public TransportResponse read(StreamInput in) { + "] does not support receiving them" ) ); - verify(remoteClusterCredentialsResolver, times(1)).resolve(eq(remoteClusterAlias)); assertThat(securityContext.getThreadContext().getHeader(CROSS_CLUSTER_ACCESS_SUBJECT_INFO_HEADER_KEY), nullValue()); assertThat(securityContext.getThreadContext().getHeader(CROSS_CLUSTER_ACCESS_CREDENTIALS_HEADER_KEY), nullValue()); } @@ -1040,12 +1019,9 @@ public void testSendRemoteRequestFailsIfUserHasNoRemoteIndicesPrivileges() throw .realm() .build(); authentication.writeToContext(threadContext); - final RemoteClusterCredentialsResolver remoteClusterCredentialsResolver = mock(RemoteClusterCredentialsResolver.class); final String remoteClusterAlias = randomAlphaOfLengthBetween(5, 10); - final String remoteClusterCredential = ApiKeyService.withApiKeyPrefix(randomAlphaOfLengthBetween(10, 42)); - when(remoteClusterCredentialsResolver.resolve(any())).thenReturn( - Optional.of(new RemoteClusterCredentials(remoteClusterAlias, remoteClusterCredential)) - ); + final String encodedApiKey = randomAlphaOfLengthBetween(10, 42); + final String remoteClusterCredential = ApiKeyService.withApiKeyPrefix(encodedApiKey); final AuthorizationService authzService = mock(AuthorizationService.class); doAnswer(invocation -> { @@ -1067,9 +1043,8 @@ public void testSendRemoteRequestFailsIfUserHasNoRemoteIndicesPrivileges() throw new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), - remoteClusterCredentialsResolver, mockLicenseState, - ignored -> Optional.of(remoteClusterAlias) + ignored -> Optional.of(new RemoteClusterAliasWithCredentials(remoteClusterAlias, new SecureString(encodedApiKey.toCharArray()))) ); final AsyncSender sender = interceptor.interceptSender(new AsyncSender() { @@ -1171,7 +1146,6 @@ public void testProfileFiltersCreatedDifferentlyForDifferentTransportAndRemoteCl new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), - new RemoteClusterCredentialsResolver(settings), mockLicenseState ); @@ -1225,7 +1199,6 @@ public void testNoProfileFilterForRemoteClusterWhenTheFeatureIsDisabled() { new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), - new RemoteClusterCredentialsResolver(settings), mockLicenseState ); From 18691593e850bba997d0c7127379e478e7a974e4 Mon Sep 17 00:00:00 2001 From: Stuart Tettemer Date: Fri, 8 Dec 2023 09:22:22 -0600 Subject: [PATCH 16/22] Metrics: Allow AsyncCounters to switch providers (#103025) {Double,Long}AsyncCounters were not in the registrar list so they were not included when switching providers. Other changes: * Moved DoubleAsyncCounter's register and get to match the order of the rest of APMMeterRegistry. * Fixed RecordingOtelMeter's Histogram and DoubleUpDownCounter * Fixed String format in RecordingMeter's asserts. --- docs/changelog/103025.yaml | 5 ++ .../telemetry/apm/APMMeterRegistry.java | 61 ++++++++------- .../telemetry/apm/APMMeterRegistryTests.java | 77 ++++++++++++++++++- .../telemetry/apm/RecordingOtelMeter.java | 10 ++- .../telemetry/MetricRecorder.java | 4 +- 5 files changed, 124 insertions(+), 33 deletions(-) create mode 100644 docs/changelog/103025.yaml diff --git a/docs/changelog/103025.yaml b/docs/changelog/103025.yaml new file mode 100644 index 0000000000000..856a7c022d5dd --- /dev/null +++ b/docs/changelog/103025.yaml @@ -0,0 +1,5 @@ +pr: 103025 +summary: "Metrics: Allow `AsyncCounters` to switch providers" +area: Infra/Core +type: bug +issues: [] diff --git a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/APMMeterRegistry.java b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/APMMeterRegistry.java index 51f008db646fa..cd6d3d209b3ed 100644 --- a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/APMMeterRegistry.java +++ b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/APMMeterRegistry.java @@ -48,12 +48,12 @@ */ public class APMMeterRegistry implements MeterRegistry { private final Registrar doubleCounters = new Registrar<>(); + private final Registrar doubleAsynchronousCounters = new Registrar<>(); private final Registrar doubleUpDownCounters = new Registrar<>(); private final Registrar doubleGauges = new Registrar<>(); private final Registrar doubleHistograms = new Registrar<>(); private final Registrar longCounters = new Registrar<>(); private final Registrar longAsynchronousCounters = new Registrar<>(); - private final Registrar doubleAsynchronousCounters = new Registrar<>(); private final Registrar longUpDownCounters = new Registrar<>(); private final Registrar longGauges = new Registrar<>(); private final Registrar longHistograms = new Registrar<>(); @@ -66,10 +66,12 @@ public APMMeterRegistry(Meter meter) { private final List> registrars = List.of( doubleCounters, + doubleAsynchronousCounters, doubleUpDownCounters, doubleGauges, doubleHistograms, longCounters, + longAsynchronousCounters, longUpDownCounters, longGauges, longHistograms @@ -81,7 +83,7 @@ public APMMeterRegistry(Meter meter) { @Override public DoubleCounter registerDoubleCounter(String name, String description, String unit) { try (ReleasableLock lock = registerLock.acquire()) { - return doubleCounters.register(new DoubleCounterAdapter(meter, name, description, unit)); + return register(doubleCounters, new DoubleCounterAdapter(meter, name, description, unit)); } } @@ -90,10 +92,27 @@ public DoubleCounter getDoubleCounter(String name) { return doubleCounters.get(name); } + @Override + public DoubleAsyncCounter registerDoubleAsyncCounter( + String name, + String description, + String unit, + Supplier observer + ) { + try (ReleasableLock lock = registerLock.acquire()) { + return register(doubleAsynchronousCounters, new DoubleAsyncCounterAdapter(meter, name, description, unit, observer)); + } + } + + @Override + public DoubleAsyncCounter getDoubleAsyncCounter(String name) { + return doubleAsynchronousCounters.get(name); + } + @Override public DoubleUpDownCounter registerDoubleUpDownCounter(String name, String description, String unit) { try (ReleasableLock lock = registerLock.acquire()) { - return doubleUpDownCounters.register(new DoubleUpDownCounterAdapter(meter, name, description, unit)); + return register(doubleUpDownCounters, new DoubleUpDownCounterAdapter(meter, name, description, unit)); } } @@ -105,7 +124,7 @@ public DoubleUpDownCounter getDoubleUpDownCounter(String name) { @Override public DoubleGauge registerDoubleGauge(String name, String description, String unit, Supplier observer) { try (ReleasableLock lock = registerLock.acquire()) { - return doubleGauges.register(new DoubleGaugeAdapter(meter, name, description, unit, observer)); + return register(doubleGauges, new DoubleGaugeAdapter(meter, name, description, unit, observer)); } } @@ -117,7 +136,7 @@ public DoubleGauge getDoubleGauge(String name) { @Override public DoubleHistogram registerDoubleHistogram(String name, String description, String unit) { try (ReleasableLock lock = registerLock.acquire()) { - return doubleHistograms.register(new DoubleHistogramAdapter(meter, name, description, unit)); + return register(doubleHistograms, new DoubleHistogramAdapter(meter, name, description, unit)); } } @@ -129,14 +148,14 @@ public DoubleHistogram getDoubleHistogram(String name) { @Override public LongCounter registerLongCounter(String name, String description, String unit) { try (ReleasableLock lock = registerLock.acquire()) { - return longCounters.register(new LongCounterAdapter(meter, name, description, unit)); + return register(longCounters, new LongCounterAdapter(meter, name, description, unit)); } } @Override public LongAsyncCounter registerLongAsyncCounter(String name, String description, String unit, Supplier observer) { try (ReleasableLock lock = registerLock.acquire()) { - return longAsynchronousCounters.register(new LongAsyncCounterAdapter(meter, name, description, unit, observer)); + return register(longAsynchronousCounters, new LongAsyncCounterAdapter(meter, name, description, unit, observer)); } } @@ -145,23 +164,6 @@ public LongAsyncCounter getLongAsyncCounter(String name) { return longAsynchronousCounters.get(name); } - @Override - public DoubleAsyncCounter registerDoubleAsyncCounter( - String name, - String description, - String unit, - Supplier observer - ) { - try (ReleasableLock lock = registerLock.acquire()) { - return doubleAsynchronousCounters.register(new DoubleAsyncCounterAdapter(meter, name, description, unit, observer)); - } - } - - @Override - public DoubleAsyncCounter getDoubleAsyncCounter(String name) { - return doubleAsynchronousCounters.get(name); - } - @Override public LongCounter getLongCounter(String name) { return longCounters.get(name); @@ -170,7 +172,7 @@ public LongCounter getLongCounter(String name) { @Override public LongUpDownCounter registerLongUpDownCounter(String name, String description, String unit) { try (ReleasableLock lock = registerLock.acquire()) { - return longUpDownCounters.register(new LongUpDownCounterAdapter(meter, name, description, unit)); + return register(longUpDownCounters, new LongUpDownCounterAdapter(meter, name, description, unit)); } } @@ -182,7 +184,7 @@ public LongUpDownCounter getLongUpDownCounter(String name) { @Override public LongGauge registerLongGauge(String name, String description, String unit, Supplier observer) { try (ReleasableLock lock = registerLock.acquire()) { - return longGauges.register(new LongGaugeAdapter(meter, name, description, unit, observer)); + return register(longGauges, new LongGaugeAdapter(meter, name, description, unit, observer)); } } @@ -194,7 +196,7 @@ public LongGauge getLongGauge(String name) { @Override public LongHistogram registerLongHistogram(String name, String description, String unit) { try (ReleasableLock lock = registerLock.acquire()) { - return longHistograms.register(new LongHistogramAdapter(meter, name, description, unit)); + return register(longHistograms, new LongHistogramAdapter(meter, name, description, unit)); } } @@ -203,6 +205,11 @@ public LongHistogram getLongHistogram(String name) { return longHistograms.get(name); } + private > T register(Registrar registrar, T adapter) { + assert registrars.contains(registrar) : "usage of unknown registrar"; + return registrar.register(adapter); + } + public void setProvider(Meter meter) { try (ReleasableLock lock = registerLock.acquire()) { this.meter = meter; diff --git a/modules/apm/src/test/java/org/elasticsearch/telemetry/apm/APMMeterRegistryTests.java b/modules/apm/src/test/java/org/elasticsearch/telemetry/apm/APMMeterRegistryTests.java index 82dd911d1b821..778ca108dc5fe 100644 --- a/modules/apm/src/test/java/org/elasticsearch/telemetry/apm/APMMeterRegistryTests.java +++ b/modules/apm/src/test/java/org/elasticsearch/telemetry/apm/APMMeterRegistryTests.java @@ -12,19 +12,37 @@ import io.opentelemetry.api.metrics.Meter; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.telemetry.Measurement; import org.elasticsearch.telemetry.apm.internal.APMAgentSettings; import org.elasticsearch.telemetry.apm.internal.APMMeterService; import org.elasticsearch.telemetry.apm.internal.TestAPMMeterService; +import org.elasticsearch.telemetry.metric.DoubleAsyncCounter; import org.elasticsearch.telemetry.metric.DoubleCounter; +import org.elasticsearch.telemetry.metric.DoubleGauge; +import org.elasticsearch.telemetry.metric.DoubleHistogram; +import org.elasticsearch.telemetry.metric.DoubleUpDownCounter; +import org.elasticsearch.telemetry.metric.DoubleWithAttributes; +import org.elasticsearch.telemetry.metric.Instrument; +import org.elasticsearch.telemetry.metric.LongAsyncCounter; import org.elasticsearch.telemetry.metric.LongCounter; +import org.elasticsearch.telemetry.metric.LongGauge; +import org.elasticsearch.telemetry.metric.LongHistogram; +import org.elasticsearch.telemetry.metric.LongUpDownCounter; +import org.elasticsearch.telemetry.metric.LongWithAttributes; import org.elasticsearch.test.ESTestCase; +import java.util.Collections; +import java.util.List; +import java.util.function.Supplier; + 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.hamcrest.Matchers.sameInstance; public class APMMeterRegistryTests extends ESTestCase { - Meter testOtel = new RecordingOtelMeter(); + RecordingOtelMeter testOtel = new RecordingOtelMeter(); Meter noopOtel = OpenTelemetry.noop().getMeter("noop"); @@ -97,4 +115,61 @@ public void testMaxNameLength() { ); assertThat(iae.getMessage(), containsString("exceeds maximum length [255]")); } + + public void testAllInstrumentsSwitchProviders() { + TestAPMMeterService apmMeter = new TestAPMMeterService( + Settings.builder().put(APMAgentSettings.TELEMETRY_METRICS_ENABLED_SETTING.getKey(), false).build(), + () -> testOtel, + () -> noopOtel + ); + APMMeterRegistry registry = apmMeter.getMeterRegistry(); + + Supplier doubleObserver = () -> new DoubleWithAttributes(1.5, Collections.emptyMap()); + DoubleCounter dc = registry.registerDoubleCounter("dc", "", ""); + DoubleUpDownCounter dudc = registry.registerDoubleUpDownCounter("dudc", "", ""); + DoubleHistogram dh = registry.registerDoubleHistogram("dh", "", ""); + DoubleAsyncCounter dac = registry.registerDoubleAsyncCounter("dac", "", "", doubleObserver); + DoubleGauge dg = registry.registerDoubleGauge("dg", "", "", doubleObserver); + + Supplier longObserver = () -> new LongWithAttributes(100, Collections.emptyMap()); + LongCounter lc = registry.registerLongCounter("lc", "", ""); + LongUpDownCounter ludc = registry.registerLongUpDownCounter("ludc", "", ""); + LongHistogram lh = registry.registerLongHistogram("lh", "", ""); + LongAsyncCounter lac = registry.registerLongAsyncCounter("lac", "", "", longObserver); + LongGauge lg = registry.registerLongGauge("lg", "", "", longObserver); + + apmMeter.setEnabled(true); + + testOtel.collectMetrics(); + dc.increment(); + dudc.add(1.0); + dh.record(1.0); + lc.increment(); + ludc.add(1); + lh.record(1); + + hasOneDouble(dc, 1.0d); + hasOneDouble(dudc, 1.0d); + hasOneDouble(dh, 1.0d); + hasOneDouble(dac, 1.5d); + hasOneDouble(dg, 1.5d); + + hasOneLong(lc, 1L); + hasOneLong(ludc, 1L); + hasOneLong(lh, 1L); + hasOneLong(lac, 100L); + hasOneLong(lg, 100L); + } + + private void hasOneDouble(Instrument instrument, double value) { + List measurements = testOtel.getRecorder().getMeasurements(instrument); + assertThat(measurements, hasSize(1)); + assertThat(measurements.get(0).getDouble(), equalTo(value)); + } + + private void hasOneLong(Instrument instrument, long value) { + List measurements = testOtel.getRecorder().getMeasurements(instrument); + assertThat(measurements, hasSize(1)); + assertThat(measurements.get(0).getLong(), equalTo(value)); + } } diff --git a/modules/apm/src/test/java/org/elasticsearch/telemetry/apm/RecordingOtelMeter.java b/modules/apm/src/test/java/org/elasticsearch/telemetry/apm/RecordingOtelMeter.java index 94627c1e53813..793803fb8c277 100644 --- a/modules/apm/src/test/java/org/elasticsearch/telemetry/apm/RecordingOtelMeter.java +++ b/modules/apm/src/test/java/org/elasticsearch/telemetry/apm/RecordingOtelMeter.java @@ -355,7 +355,7 @@ public ObservableDoubleMeasurement buildObserver() { private class DoubleUpDownRecorder extends AbstractInstrument implements DoubleUpDownCounter, OtelInstrument { DoubleUpDownRecorder(String name) { - super(name, InstrumentType.LONG_UP_DOWN_COUNTER); + super(name, InstrumentType.DOUBLE_UP_DOWN_COUNTER); } protected DoubleUpDownRecorder(String name, InstrumentType instrument) { @@ -616,7 +616,9 @@ public LongHistogramBuilder ofLongs() { @Override public DoubleHistogram build() { - return new DoubleHistogramRecorder(name); + DoubleHistogramRecorder histogram = new DoubleHistogramRecorder(name); + recorder.register(histogram, histogram.getInstrument(), name, description, unit); + return histogram; } } @@ -661,7 +663,9 @@ public LongHistogramBuilder setUnit(String unit) { @Override public LongHistogram build() { - return new LongHistogramRecorder(name); + LongHistogramRecorder histogram = new LongHistogramRecorder(name); + recorder.register(histogram, histogram.getInstrument(), name, description, unit); + return histogram; } } diff --git a/test/framework/src/main/java/org/elasticsearch/telemetry/MetricRecorder.java b/test/framework/src/main/java/org/elasticsearch/telemetry/MetricRecorder.java index cf8f23f06155d..aa14d0067b68e 100644 --- a/test/framework/src/main/java/org/elasticsearch/telemetry/MetricRecorder.java +++ b/test/framework/src/main/java/org/elasticsearch/telemetry/MetricRecorder.java @@ -39,7 +39,7 @@ private record RegisteredMetric( ) { void register(String name, String description, String unit, I instrument) { assert registered.containsKey(name) == false - : Strings.format("unexpected [{}]: [{}][{}], already registered[{}]", name, description, unit, registered.get(name)); + : Strings.format("unexpected [%s]: [%s][%s], already registered[%s]", name, description, unit, registered.get(name)); registered.put(name, new Registration(name, description, unit)); instruments.put(name, instrument); if (instrument instanceof Runnable callback) { @@ -48,7 +48,7 @@ void register(String name, String description, String unit, I instrument) { } void call(String name, Measurement call) { - assert registered.containsKey(name) : Strings.format("call for unregistered metric [{}]: [{}]", name, call); + assert registered.containsKey(name) : Strings.format("call for unregistered metric [%s]: [%s]", name, call); called.computeIfAbsent(Objects.requireNonNull(name), k -> new CopyOnWriteArrayList<>()).add(call); } From ab12d4e3620dc9deb89f4129d1f4c104b0e17913 Mon Sep 17 00:00:00 2001 From: Stuart Tettemer Date: Fri, 8 Dec 2023 09:24:10 -0600 Subject: [PATCH 17/22] Metrics: Handle null observations in observers (#103091) Avoid null pointer error when an observation is null [0]. * To get the tests working, replace the this-escape buildInstrument with a Builder. * Removes locking around close --- docs/changelog/103091.yaml | 5 ++ .../telemetry/apm/AbstractInstrument.java | 61 ++++++++++--------- .../metrics/DoubleAsyncCounterAdapter.java | 45 ++++++-------- .../metrics/DoubleCounterAdapter.java | 22 ++++--- .../internal/metrics/DoubleGaugeAdapter.java | 48 ++++++--------- .../metrics/DoubleHistogramAdapter.java | 19 +++--- .../metrics/DoubleUpDownCounterAdapter.java | 23 +++---- .../metrics/LongAsyncCounterAdapter.java | 44 ++++++------- .../internal/metrics/LongCounterAdapter.java | 20 +++--- .../internal/metrics/LongGaugeAdapter.java | 50 ++++++--------- .../metrics/LongHistogramAdapter.java | 24 ++++---- .../metrics/LongUpDownCounterAdapter.java | 19 +++--- .../apm/internal/metrics/OtelHelper.java | 45 ++++++++++++++ .../metrics/AsyncCountersAdapterTests.java | 22 +++++++ .../internal/metrics/GaugeAdapterTests.java | 12 ++++ 15 files changed, 262 insertions(+), 197 deletions(-) create mode 100644 docs/changelog/103091.yaml diff --git a/docs/changelog/103091.yaml b/docs/changelog/103091.yaml new file mode 100644 index 0000000000000..ae4ac11933d4e --- /dev/null +++ b/docs/changelog/103091.yaml @@ -0,0 +1,5 @@ +pr: 103091 +summary: "Metrics: Handle null observations in observers" +area: Infra/Core +type: bug +issues: [] diff --git a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/AbstractInstrument.java b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/AbstractInstrument.java index bbeaba0f6f088..72c6ccf905873 100644 --- a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/AbstractInstrument.java +++ b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/AbstractInstrument.java @@ -17,6 +17,7 @@ import java.security.PrivilegedAction; import java.util.Objects; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; /** * An instrument that contains the name, description and unit. The delegate may be replaced when @@ -25,27 +26,14 @@ * @param delegated instrument */ public abstract class AbstractInstrument implements Instrument { - private static final int MAX_NAME_LENGTH = 255; - private final AtomicReference delegate; + private final AtomicReference delegate = new AtomicReference<>(); private final String name; - private final String description; - private final String unit; + private final Function instrumentBuilder; - @SuppressWarnings("this-escape") - public AbstractInstrument(Meter meter, String name, String description, String unit) { - this.name = Objects.requireNonNull(name); - if (name.length() > MAX_NAME_LENGTH) { - throw new IllegalArgumentException( - "Instrument name [" + name + "] with length [" + name.length() + "] exceeds maximum length [" + MAX_NAME_LENGTH + "]" - ); - } - this.description = Objects.requireNonNull(description); - this.unit = Objects.requireNonNull(unit); - this.delegate = new AtomicReference<>(doBuildInstrument(meter)); - } - - private T doBuildInstrument(Meter meter) { - return AccessController.doPrivileged((PrivilegedAction) () -> buildInstrument(meter)); + public AbstractInstrument(Meter meter, Builder builder) { + this.name = builder.getName(); + this.instrumentBuilder = m -> AccessController.doPrivileged((PrivilegedAction) () -> builder.build(m)); + this.delegate.set(this.instrumentBuilder.apply(meter)); } @Override @@ -53,21 +41,36 @@ public String getName() { return name; } - public String getUnit() { - return unit.toString(); - } - protected T getInstrument() { return delegate.get(); } - protected String getDescription() { - return description; - } - void setProvider(@Nullable Meter meter) { - delegate.set(doBuildInstrument(Objects.requireNonNull(meter))); + delegate.set(instrumentBuilder.apply(Objects.requireNonNull(meter))); } - protected abstract T buildInstrument(Meter meter); + protected abstract static class Builder { + private static final int MAX_NAME_LENGTH = 255; + + protected final String name; + protected final String description; + protected final String unit; + + public Builder(String name, String description, String unit) { + if (name.length() > MAX_NAME_LENGTH) { + throw new IllegalArgumentException( + "Instrument name [" + name + "] with length [" + name.length() + "] exceeds maximum length [" + MAX_NAME_LENGTH + "]" + ); + } + this.name = Objects.requireNonNull(name); + this.description = Objects.requireNonNull(description); + this.unit = Objects.requireNonNull(unit); + } + + public String getName() { + return name; + } + + public abstract T build(Meter meter); + } } diff --git a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleAsyncCounterAdapter.java b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleAsyncCounterAdapter.java index a1ea9f33e31fb..6b17a83619ef7 100644 --- a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleAsyncCounterAdapter.java +++ b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleAsyncCounterAdapter.java @@ -11,47 +11,40 @@ import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.metrics.ObservableDoubleCounter; -import org.elasticsearch.common.util.concurrent.ReleasableLock; import org.elasticsearch.telemetry.apm.AbstractInstrument; import org.elasticsearch.telemetry.metric.DoubleAsyncCounter; import org.elasticsearch.telemetry.metric.DoubleWithAttributes; import java.util.Objects; -import java.util.concurrent.locks.ReentrantLock; import java.util.function.Supplier; public class DoubleAsyncCounterAdapter extends AbstractInstrument implements DoubleAsyncCounter { - private final Supplier observer; - private final ReleasableLock closedLock = new ReleasableLock(new ReentrantLock()); - private boolean closed = false; public DoubleAsyncCounterAdapter(Meter meter, String name, String description, String unit, Supplier observer) { - super(meter, name, description, unit); - this.observer = observer; + super(meter, new Builder(name, description, unit, observer)); } @Override - protected ObservableDoubleCounter buildInstrument(Meter meter) { - var builder = Objects.requireNonNull(meter).counterBuilder(getName()); - return builder.setDescription(getDescription()).setUnit(getUnit()).ofDoubles().buildWithCallback(measurement -> { - DoubleWithAttributes observation; - try { - observation = observer.get(); - } catch (RuntimeException err) { - assert false : "observer must not throw [" + err.getMessage() + "]"; - return; - } - measurement.record(observation.value(), OtelHelper.fromMap(observation.attributes())); - }); + public void close() throws Exception { + getInstrument().close(); } - @Override - public void close() throws Exception { - try (ReleasableLock lock = closedLock.acquire()) { - if (closed == false) { - getInstrument().close(); - } - closed = true; + private static class Builder extends AbstractInstrument.Builder { + private final Supplier observer; + + private Builder(String name, String description, String unit, Supplier observer) { + super(name, description, unit); + this.observer = Objects.requireNonNull(observer); + } + + @Override + public ObservableDoubleCounter build(Meter meter) { + return Objects.requireNonNull(meter) + .counterBuilder(name) + .setDescription(description) + .setUnit(unit) + .ofDoubles() + .buildWithCallback(OtelHelper.doubleMeasurementCallback(observer)); } } } diff --git a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleCounterAdapter.java b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleCounterAdapter.java index faba8c2e3e67e..398419f6c3f69 100644 --- a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleCounterAdapter.java +++ b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleCounterAdapter.java @@ -22,16 +22,7 @@ public class DoubleCounterAdapter extends AbstractInstrument implements org.elasticsearch.telemetry.metric.DoubleCounter { public DoubleCounterAdapter(Meter meter, String name, String description, String unit) { - super(meter, name, description, unit); - } - - protected io.opentelemetry.api.metrics.DoubleCounter buildInstrument(Meter meter) { - return Objects.requireNonNull(meter) - .counterBuilder(getName()) - .ofDoubles() - .setDescription(getDescription()) - .setUnit(getUnit()) - .build(); + super(meter, new Builder(name, description, unit)); } @Override @@ -50,4 +41,15 @@ public void incrementBy(double inc, Map attributes) { assert inc >= 0; getInstrument().add(inc, OtelHelper.fromMap(attributes)); } + + private static class Builder extends AbstractInstrument.Builder { + private Builder(String name, String description, String unit) { + super(name, description, unit); + } + + @Override + public DoubleCounter build(Meter meter) { + return Objects.requireNonNull(meter).counterBuilder(name).ofDoubles().setDescription(description).setUnit(unit).build(); + } + } } diff --git a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleGaugeAdapter.java b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleGaugeAdapter.java index faef8bd723fcf..ed6ecee66d696 100644 --- a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleGaugeAdapter.java +++ b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleGaugeAdapter.java @@ -11,12 +11,10 @@ import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.metrics.ObservableDoubleGauge; -import org.elasticsearch.common.util.concurrent.ReleasableLock; import org.elasticsearch.telemetry.apm.AbstractInstrument; import org.elasticsearch.telemetry.metric.DoubleWithAttributes; import java.util.Objects; -import java.util.concurrent.locks.ReentrantLock; import java.util.function.Supplier; /** @@ -26,40 +24,30 @@ public class DoubleGaugeAdapter extends AbstractInstrument observer; - private final ReleasableLock closedLock = new ReleasableLock(new ReentrantLock()); - private boolean closed = false; - public DoubleGaugeAdapter(Meter meter, String name, String description, String unit, Supplier observer) { - super(meter, name, description, unit); - this.observer = observer; + super(meter, new Builder(name, description, unit, observer)); } @Override - protected io.opentelemetry.api.metrics.ObservableDoubleGauge buildInstrument(Meter meter) { - return Objects.requireNonNull(meter) - .gaugeBuilder(getName()) - .setDescription(getDescription()) - .setUnit(getUnit()) - .buildWithCallback(measurement -> { - DoubleWithAttributes observation; - try { - observation = observer.get(); - } catch (RuntimeException err) { - assert false : "observer must not throw [" + err.getMessage() + "]"; - return; - } - measurement.record(observation.value(), OtelHelper.fromMap(observation.attributes())); - }); + public void close() throws Exception { + getInstrument().close(); } - @Override - public void close() throws Exception { - try (ReleasableLock lock = closedLock.acquire()) { - if (closed == false) { - getInstrument().close(); - } - closed = true; + private static class Builder extends AbstractInstrument.Builder { + private final Supplier observer; + + private Builder(String name, String description, String unit, Supplier observer) { + super(name, description, unit); + this.observer = Objects.requireNonNull(observer); + } + + @Override + public ObservableDoubleGauge build(Meter meter) { + return Objects.requireNonNull(meter) + .gaugeBuilder(name) + .setDescription(description) + .setUnit(unit) + .buildWithCallback(OtelHelper.doubleMeasurementCallback(observer)); } } } diff --git a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleHistogramAdapter.java b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleHistogramAdapter.java index e126aa6af7cf0..47b54a84d0aa9 100644 --- a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleHistogramAdapter.java +++ b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleHistogramAdapter.java @@ -24,13 +24,7 @@ public class DoubleHistogramAdapter extends AbstractInstrument org.elasticsearch.telemetry.metric.DoubleHistogram { public DoubleHistogramAdapter(Meter meter, String name, String description, String unit) { - super(meter, name, description, unit); - } - - @Override - protected io.opentelemetry.api.metrics.DoubleHistogram buildInstrument(Meter meter) { - var builder = Objects.requireNonNull(meter).histogramBuilder(getName()); - return builder.setDescription(getDescription()).setUnit(getUnit()).build(); + super(meter, new Builder(name, description, unit)); } @Override @@ -42,4 +36,15 @@ public void record(double value) { public void record(double value, Map attributes) { getInstrument().record(value, OtelHelper.fromMap(attributes)); } + + private static class Builder extends AbstractInstrument.Builder { + private Builder(String name, String description, String unit) { + super(name, description, unit); + } + + @Override + public DoubleHistogram build(Meter meter) { + return Objects.requireNonNull(meter).histogramBuilder(name).setDescription(description).setUnit(unit).build(); + } + } } diff --git a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleUpDownCounterAdapter.java b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleUpDownCounterAdapter.java index a204627a04f1e..7cb7100ba2631 100644 --- a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleUpDownCounterAdapter.java +++ b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/DoubleUpDownCounterAdapter.java @@ -24,17 +24,7 @@ public class DoubleUpDownCounterAdapter extends AbstractInstrument attributes) { getInstrument().add(inc, OtelHelper.fromMap(attributes)); } + + private static class Builder extends AbstractInstrument.Builder { + private Builder(String name, String description, String unit) { + super(name, description, unit); + } + + @Override + public DoubleUpDownCounter build(Meter meter) { + return Objects.requireNonNull(meter).upDownCounterBuilder(name).ofDoubles().setDescription(description).setUnit(unit).build(); + } + } } diff --git a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongAsyncCounterAdapter.java b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongAsyncCounterAdapter.java index 126cca1964283..14c58139d03e1 100644 --- a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongAsyncCounterAdapter.java +++ b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongAsyncCounterAdapter.java @@ -11,47 +11,39 @@ import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.metrics.ObservableLongCounter; -import org.elasticsearch.common.util.concurrent.ReleasableLock; import org.elasticsearch.telemetry.apm.AbstractInstrument; import org.elasticsearch.telemetry.metric.LongAsyncCounter; import org.elasticsearch.telemetry.metric.LongWithAttributes; import java.util.Objects; -import java.util.concurrent.locks.ReentrantLock; import java.util.function.Supplier; public class LongAsyncCounterAdapter extends AbstractInstrument implements LongAsyncCounter { - private final Supplier observer; - private final ReleasableLock closedLock = new ReleasableLock(new ReentrantLock()); - private boolean closed = false; public LongAsyncCounterAdapter(Meter meter, String name, String description, String unit, Supplier observer) { - super(meter, name, description, unit); - this.observer = observer; + super(meter, new Builder(name, description, unit, observer)); } @Override - protected ObservableLongCounter buildInstrument(Meter meter) { - var builder = Objects.requireNonNull(meter).counterBuilder(getName()); - return builder.setDescription(getDescription()).setUnit(getUnit()).buildWithCallback(measurement -> { - LongWithAttributes observation; - try { - observation = observer.get(); - } catch (RuntimeException err) { - assert false : "observer must not throw [" + err.getMessage() + "]"; - return; - } - measurement.record(observation.value(), OtelHelper.fromMap(observation.attributes())); - }); + public void close() throws Exception { + getInstrument().close(); } - @Override - public void close() throws Exception { - try (ReleasableLock lock = closedLock.acquire()) { - if (closed == false) { - getInstrument().close(); - } - closed = true; + private static class Builder extends AbstractInstrument.Builder { + private final Supplier observer; + + private Builder(String name, String description, String unit, Supplier observer) { + super(name, description, unit); + this.observer = Objects.requireNonNull(observer); + } + + @Override + public ObservableLongCounter build(Meter meter) { + return Objects.requireNonNull(meter) + .counterBuilder(name) + .setDescription(description) + .setUnit(unit) + .buildWithCallback(OtelHelper.longMeasurementCallback(observer)); } } } diff --git a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongCounterAdapter.java b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongCounterAdapter.java index 9b46b8c97994a..54a7c3e3cab29 100644 --- a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongCounterAdapter.java +++ b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongCounterAdapter.java @@ -20,15 +20,8 @@ * LongCounterAdapter wraps an otel LongCounter */ public class LongCounterAdapter extends AbstractInstrument implements org.elasticsearch.telemetry.metric.LongCounter { - public LongCounterAdapter(Meter meter, String name, String description, String unit) { - super(meter, name, description, unit); - } - - @Override - protected io.opentelemetry.api.metrics.LongCounter buildInstrument(Meter meter) { - var builder = Objects.requireNonNull(meter).counterBuilder(getName()); - return builder.setDescription(getDescription()).setUnit(getUnit()).build(); + super(meter, new Builder(name, description, unit)); } @Override @@ -47,4 +40,15 @@ public void incrementBy(long inc, Map attributes) { assert inc >= 0; getInstrument().add(inc, OtelHelper.fromMap(attributes)); } + + private static class Builder extends AbstractInstrument.Builder { + private Builder(String name, String description, String unit) { + super(name, description, unit); + } + + @Override + public LongCounter build(Meter meter) { + return Objects.requireNonNull(meter).counterBuilder(name).setDescription(description).setUnit(unit).build(); + } + } } diff --git a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongGaugeAdapter.java b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongGaugeAdapter.java index e297ba7ee963a..52c19c80c284f 100644 --- a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongGaugeAdapter.java +++ b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongGaugeAdapter.java @@ -11,53 +11,41 @@ import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.metrics.ObservableLongGauge; -import org.elasticsearch.common.util.concurrent.ReleasableLock; import org.elasticsearch.telemetry.apm.AbstractInstrument; import org.elasticsearch.telemetry.metric.LongWithAttributes; import java.util.Objects; -import java.util.concurrent.locks.ReentrantLock; import java.util.function.Supplier; /** * LongGaugeAdapter wraps an otel ObservableLongGauge */ public class LongGaugeAdapter extends AbstractInstrument implements org.elasticsearch.telemetry.metric.LongGauge { - private final Supplier observer; - private final ReleasableLock closedLock = new ReleasableLock(new ReentrantLock()); - private boolean closed = false; - public LongGaugeAdapter(Meter meter, String name, String description, String unit, Supplier observer) { - super(meter, name, description, unit); - this.observer = observer; + super(meter, new Builder(name, description, unit, observer)); } @Override - protected io.opentelemetry.api.metrics.ObservableLongGauge buildInstrument(Meter meter) { - return Objects.requireNonNull(meter) - .gaugeBuilder(getName()) - .ofLongs() - .setDescription(getDescription()) - .setUnit(getUnit()) - .buildWithCallback(measurement -> { - LongWithAttributes observation; - try { - observation = observer.get(); - } catch (RuntimeException err) { - assert false : "observer must not throw [" + err.getMessage() + "]"; - return; - } - measurement.record(observation.value(), OtelHelper.fromMap(observation.attributes())); - }); + public void close() throws Exception { + getInstrument().close(); } - @Override - public void close() throws Exception { - try (ReleasableLock lock = closedLock.acquire()) { - if (closed == false) { - getInstrument().close(); - } - closed = true; + private static class Builder extends AbstractInstrument.Builder { + private final Supplier observer; + + private Builder(String name, String description, String unit, Supplier observer) { + super(name, description, unit); + this.observer = Objects.requireNonNull(observer); + } + + @Override + public ObservableLongGauge build(Meter meter) { + return Objects.requireNonNull(meter) + .gaugeBuilder(name) + .ofLongs() + .setDescription(description) + .setUnit(unit) + .buildWithCallback(OtelHelper.longMeasurementCallback(observer)); } } } diff --git a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongHistogramAdapter.java b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongHistogramAdapter.java index 2b8e76df0dd0e..286922027ce2a 100644 --- a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongHistogramAdapter.java +++ b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongHistogramAdapter.java @@ -20,19 +20,8 @@ * LongHistogramAdapter wraps an otel LongHistogram */ public class LongHistogramAdapter extends AbstractInstrument implements org.elasticsearch.telemetry.metric.LongHistogram { - public LongHistogramAdapter(Meter meter, String name, String description, String unit) { - super(meter, name, description, unit); - } - - @Override - protected io.opentelemetry.api.metrics.LongHistogram buildInstrument(Meter meter) { - return Objects.requireNonNull(meter) - .histogramBuilder(getName()) - .ofLongs() - .setDescription(getDescription()) - .setUnit(getUnit()) - .build(); + super(meter, new Builder(name, description, unit)); } @Override @@ -44,4 +33,15 @@ public void record(long value) { public void record(long value, Map attributes) { getInstrument().record(value, OtelHelper.fromMap(attributes)); } + + private static class Builder extends AbstractInstrument.Builder { + private Builder(String name, String description, String unit) { + super(name, description, unit); + } + + @Override + public LongHistogram build(Meter meter) { + return Objects.requireNonNull(meter).histogramBuilder(name).ofLongs().setDescription(description).setUnit(unit).build(); + } + } } diff --git a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongUpDownCounterAdapter.java b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongUpDownCounterAdapter.java index a59a114bc2264..fa09740085aa3 100644 --- a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongUpDownCounterAdapter.java +++ b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/LongUpDownCounterAdapter.java @@ -24,13 +24,7 @@ public class LongUpDownCounterAdapter extends AbstractInstrument attributes) { getInstrument().add(inc, OtelHelper.fromMap(attributes)); } + + private static class Builder extends AbstractInstrument.Builder { + private Builder(String name, String description, String unit) { + super(name, description, unit); + } + + @Override + public LongUpDownCounter build(Meter meter) { + return Objects.requireNonNull(meter).upDownCounterBuilder(name).setDescription(description).setUnit(unit).build(); + } + } } diff --git a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/OtelHelper.java b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/OtelHelper.java index 18bf66cee5391..3e8ab415bd25e 100644 --- a/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/OtelHelper.java +++ b/modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/metrics/OtelHelper.java @@ -9,10 +9,21 @@ package org.elasticsearch.telemetry.apm.internal.metrics; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; +import io.opentelemetry.api.metrics.ObservableLongMeasurement; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.elasticsearch.telemetry.metric.DoubleWithAttributes; +import org.elasticsearch.telemetry.metric.LongWithAttributes; import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Supplier; class OtelHelper { + private static final Logger logger = LogManager.getLogger(OtelHelper.class); + static Attributes fromMap(Map attributes) { if (attributes == null || attributes.isEmpty()) { return Attributes.empty(); @@ -41,4 +52,38 @@ static Attributes fromMap(Map attributes) { }); return builder.build(); } + + static Consumer doubleMeasurementCallback(Supplier observer) { + return measurement -> { + DoubleWithAttributes observation; + try { + observation = observer.get(); + } catch (RuntimeException err) { + assert false : "observer must not throw [" + err.getMessage() + "]"; + logger.error("doubleMeasurementCallback observer unexpected error", err); + return; + } + if (observation == null) { + return; + } + measurement.record(observation.value(), OtelHelper.fromMap(observation.attributes())); + }; + } + + static Consumer longMeasurementCallback(Supplier observer) { + return measurement -> { + LongWithAttributes observation; + try { + observation = observer.get(); + } catch (RuntimeException err) { + assert false : "observer must not throw [" + err.getMessage() + "]"; + logger.error("longMeasurementCallback observer unexpected error", err); + return; + } + if (observation == null) { + return; + } + measurement.record(observation.value(), OtelHelper.fromMap(observation.attributes())); + }; + } } diff --git a/modules/apm/src/test/java/org/elasticsearch/telemetry/apm/internal/metrics/AsyncCountersAdapterTests.java b/modules/apm/src/test/java/org/elasticsearch/telemetry/apm/internal/metrics/AsyncCountersAdapterTests.java index fa8706deee870..3e23b741e01e5 100644 --- a/modules/apm/src/test/java/org/elasticsearch/telemetry/apm/internal/metrics/AsyncCountersAdapterTests.java +++ b/modules/apm/src/test/java/org/elasticsearch/telemetry/apm/internal/metrics/AsyncCountersAdapterTests.java @@ -99,4 +99,26 @@ public void testDoubleAsyncAdapter() throws Exception { metrics = otelMeter.getRecorder().getMeasurements(doubleAsyncCounter); assertThat(metrics, hasSize(0)); } + + public void testNullGaugeRecord() throws Exception { + DoubleAsyncCounter dcounter = registry.registerDoubleAsyncCounter( + "name", + "desc", + "unit", + new AtomicReference()::get + ); + otelMeter.collectMetrics(); + List metrics = otelMeter.getRecorder().getMeasurements(dcounter); + assertThat(metrics, hasSize(0)); + + LongAsyncCounter lcounter = registry.registerLongAsyncCounter( + "name", + "desc", + "unit", + new AtomicReference()::get + ); + otelMeter.collectMetrics(); + metrics = otelMeter.getRecorder().getMeasurements(lcounter); + assertThat(metrics, hasSize(0)); + } } diff --git a/modules/apm/src/test/java/org/elasticsearch/telemetry/apm/internal/metrics/GaugeAdapterTests.java b/modules/apm/src/test/java/org/elasticsearch/telemetry/apm/internal/metrics/GaugeAdapterTests.java index e8cd18521f842..10f2d58768d48 100644 --- a/modules/apm/src/test/java/org/elasticsearch/telemetry/apm/internal/metrics/GaugeAdapterTests.java +++ b/modules/apm/src/test/java/org/elasticsearch/telemetry/apm/internal/metrics/GaugeAdapterTests.java @@ -100,4 +100,16 @@ public void testDoubleGaugeRecord() throws Exception { metrics = otelMeter.getRecorder().getMeasurements(gauge); assertThat(metrics, hasSize(0)); } + + public void testNullGaugeRecord() throws Exception { + DoubleGauge dgauge = registry.registerDoubleGauge("name", "desc", "unit", new AtomicReference()::get); + otelMeter.collectMetrics(); + List metrics = otelMeter.getRecorder().getMeasurements(dgauge); + assertThat(metrics, hasSize(0)); + + LongGauge lgauge = registry.registerLongGauge("name", "desc", "unit", new AtomicReference()::get); + otelMeter.collectMetrics(); + metrics = otelMeter.getRecorder().getMeasurements(lgauge); + assertThat(metrics, hasSize(0)); + } } From ff1e2dfb2926fda6c3d1a216e23153125e331d24 Mon Sep 17 00:00:00 2001 From: Nhat Nguyen Date: Fri, 8 Dec 2023 07:24:42 -0800 Subject: [PATCH 18/22] Deep copy term returned from ordinal lookup (#103167) We should perform a deep copy of the term returned from the ordinal lookup before passing it to the constant block since that BytesRef may be reused in subsequent lookups. Closes #103106 --- .../index/mapper/BlockDocValuesReader.java | 3 +- .../ValuesSourceReaderOperatorTests.java | 65 +++++++++++++++---- 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/index/mapper/BlockDocValuesReader.java b/server/src/main/java/org/elasticsearch/index/mapper/BlockDocValuesReader.java index 2160f52cbec02..a9781aeb9e2db 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/BlockDocValuesReader.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/BlockDocValuesReader.java @@ -558,7 +558,8 @@ private static class SingletonOrdinals extends BlockDocValuesReader { private BlockLoader.Block readSingleDoc(BlockFactory factory, int docId) throws IOException { if (ordinals.advanceExact(docId)) { BytesRef v = ordinals.lookupOrd(ordinals.ordValue()); - return factory.constantBytes(v); + // the returned BytesRef can be reused + return factory.constantBytes(BytesRef.deepCopyOf(v)); } else { return factory.constantNulls(); } diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/lucene/ValuesSourceReaderOperatorTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/lucene/ValuesSourceReaderOperatorTests.java index 424f88413af8f..03815dcdaea78 100644 --- a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/lucene/ValuesSourceReaderOperatorTests.java +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/lucene/ValuesSourceReaderOperatorTests.java @@ -78,6 +78,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -111,6 +112,7 @@ public class ValuesSourceReaderOperatorTests extends OperatorTestCase { private Directory directory = newDirectory(); private IndexReader reader; + private static final Map keyToTags = new HashMap<>(); @After public void closeIndex() throws IOException { @@ -144,12 +146,14 @@ static Operator.OperatorFactory factory(IndexReader reader, String name, BlockLo @Override protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { - // The test wants more than one segment. We shoot for 10. - int commitEvery = Math.max(1, (int) Math.ceil((double) size / 10)); - return simpleInput(driverContext(), size, commitEvery); + return simpleInput(driverContext(), size, commitEvery(size), randomPageSize()); } - private SourceOperator simpleInput(DriverContext context, int size, int commitEvery) { + private int commitEvery(int numDocs) { + return Math.max(1, (int) Math.ceil((double) numDocs / 10)); + } + + private SourceOperator simpleInput(DriverContext context, int size, int commitEvery, int pageSize) { try { initIndex(size, commitEvery); } catch (IOException e) { @@ -160,13 +164,14 @@ private SourceOperator simpleInput(DriverContext context, int size, int commitEv ctx -> new MatchAllDocsQuery(), DataPartitioning.SHARD, randomIntBetween(1, 10), - size, + pageSize, LuceneOperator.NO_LIMIT ); return luceneFactory.get(context); } private void initIndex(int size, int commitEvery) throws IOException { + keyToTags.clear(); try ( IndexWriter writer = new IndexWriter( directory, @@ -181,9 +186,8 @@ private void initIndex(int size, int commitEvery) throws IOException { doc.add(new SortedNumericDocValuesField("short", (short) d)); doc.add(new SortedNumericDocValuesField("byte", (byte) d)); doc.add(new SortedNumericDocValuesField("long", d)); - doc.add( - new KeywordFieldMapper.KeywordField("kwd", new BytesRef(Integer.toString(d)), KeywordFieldMapper.Defaults.FIELD_TYPE) - ); + String tag = keyToTags.computeIfAbsent(d, k -> "tag-" + randomIntBetween(1, 5)); + doc.add(new KeywordFieldMapper.KeywordField("kwd", new BytesRef(tag), KeywordFieldMapper.Defaults.FIELD_TYPE)); doc.add(new StoredField("stored_kwd", new BytesRef(Integer.toString(d)))); doc.add(new StoredField("stored_text", Integer.toString(d))); doc.add(new SortedNumericDocValuesField("bool", d % 2 == 0 ? 1 : 0)); @@ -295,6 +299,37 @@ public void testLoadAllInOnePage() { ); } + public void testManySingleDocPages() { + DriverContext driverContext = driverContext(); + int numDocs = between(10, 100); + List input = CannedSourceOperator.collectPages(simpleInput(driverContext, numDocs, between(1, numDocs), 1)); + Randomness.shuffle(input); + List operators = new ArrayList<>(); + Checks checks = new Checks(Block.MvOrdering.DEDUPLICATED_AND_SORTED_ASCENDING); + FieldCase testCase = new FieldCase( + new KeywordFieldMapper.KeywordFieldType("kwd"), + checks::tags, + StatusChecks::keywordsFromDocValues + ); + operators.add( + new ValuesSourceReaderOperator.Factory( + List.of(testCase.info, fieldInfo(docValuesNumberField("key", NumberFieldMapper.NumberType.INTEGER))), + List.of(new ValuesSourceReaderOperator.ShardContext(reader, () -> SourceLoader.FROM_STORED_SOURCE)), + 0 + ).get(driverContext) + ); + List results = drive(operators, input.iterator(), driverContext); + assertThat(results, hasSize(input.size())); + for (Page page : results) { + assertThat(page.getBlockCount(), equalTo(3)); + IntVector keys = page.getBlock(2).asVector(); + for (int p = 0; p < page.getPositionCount(); p++) { + int key = keys.getInt(p); + testCase.checkResults.check(page.getBlock(1), p, key); + } + } + } + public void testEmpty() { DriverContext driverContext = driverContext(); loadSimpleAndAssert( @@ -440,7 +475,8 @@ public void testLoadAllStatusAllInOnePage() { private void testLoadAllStatus(boolean allInOnePage) { DriverContext driverContext = driverContext(); - List input = CannedSourceOperator.collectPages(simpleInput(driverContext.blockFactory(), between(100, 5000))); + int numDocs = between(100, 5000); + List input = CannedSourceOperator.collectPages(simpleInput(driverContext, numDocs, commitEvery(numDocs), numDocs)); assertThat(reader.leaves(), hasSize(10)); assertThat(input, hasSize(10)); List cases = infoAndChecksForEachType(Block.MvOrdering.DEDUPLICATED_AND_SORTED_ASCENDING); @@ -585,7 +621,7 @@ private List infoAndChecksForEachType(Block.MvOrdering docValuesMvOrd r.add(new FieldCase(new BooleanFieldMapper.BooleanFieldType("bool"), checks::bools, StatusChecks::boolFromDocValues)); r.add(new FieldCase(new BooleanFieldMapper.BooleanFieldType("mv_bool"), checks::mvBools, StatusChecks::mvBoolFromDocValues)); r.add(new FieldCase(new BooleanFieldMapper.BooleanFieldType("missing_bool"), checks::constantNulls, StatusChecks::constantNulls)); - r.add(new FieldCase(new KeywordFieldMapper.KeywordFieldType("kwd"), checks::strings, StatusChecks::keywordsFromDocValues)); + r.add(new FieldCase(new KeywordFieldMapper.KeywordFieldType("kwd"), checks::tags, StatusChecks::keywordsFromDocValues)); r.add( new FieldCase( new KeywordFieldMapper.KeywordFieldType("mv_kwd"), @@ -611,7 +647,7 @@ private List infoAndChecksForEachType(Block.MvOrdering docValuesMvOrd r.add( new FieldCase( textFieldWithDelegate("text_with_delegate", new KeywordFieldMapper.KeywordFieldType("kwd")), - checks::strings, + checks::tags, StatusChecks::textWithDelegate ) ); @@ -680,6 +716,11 @@ void strings(Block block, int position, int key) { assertThat(keywords.getBytesRef(position, new BytesRef()).utf8ToString(), equalTo(Integer.toString(key))); } + void tags(Block block, int position, int key) { + BytesRefVector keywords = ((BytesRefBlock) block).asVector(); + assertThat(keywords.getBytesRef(position, new BytesRef()).utf8ToString(), equalTo(keyToTags.get(key))); + } + void bools(Block block, int position, int key) { BooleanVector bools = ((BooleanBlock) block).asVector(); assertThat(bools.getBoolean(position), equalTo(key % 2 == 0)); @@ -1285,7 +1326,7 @@ public void testSequentialStoredFieldsBigEnough() { private void testSequentialStoredFields(boolean sequential, int docCount) { DriverContext driverContext = driverContext(); - List source = CannedSourceOperator.collectPages(simpleInput(driverContext, docCount, docCount)); + List source = CannedSourceOperator.collectPages(simpleInput(driverContext, docCount, docCount, docCount)); assertThat(source, hasSize(1)); // We want one page for simpler assertions, and we want them all in one segment assertTrue(source.get(0).getBlock(0).asVector().singleSegmentNonDecreasing()); Operator op = new ValuesSourceReaderOperator.Factory( From 9db4cb4f98ec3a94243a0d2898a8b32df6429f67 Mon Sep 17 00:00:00 2001 From: Nikolaj Volgushev Date: Fri, 8 Dec 2023 18:51:02 +0100 Subject: [PATCH 19/22] Revert "Hot-reloadable remote cluster credentials (#102798)" (#103211) Reverts elastic/elasticsearch#102798 --- docs/changelog/102798.yaml | 5 - .../transport/ProxyConnectionStrategy.java | 2 +- .../transport/RemoteClusterConnection.java | 25 +- .../RemoteClusterCredentialsManager.java | 52 --- .../transport/RemoteClusterService.java | 27 +- .../transport/RemoteConnectionManager.java | 61 +--- .../transport/SniffConnectionStrategy.java | 6 +- .../ProxyConnectionStrategyTests.java | 54 +-- .../RemoteClusterConnectionTests.java | 69 +--- .../RemoteClusterCredentialsManagerTests.java | 43 --- .../RemoteConnectionManagerTests.java | 32 +- .../RemoteConnectionStrategyTests.java | 18 +- .../SniffConnectionStrategyTests.java | 66 +--- .../ReloadRemoteClusterCredentialsAction.java | 50 --- .../authz/privilege/SystemPrivilege.java | 4 +- .../xpack/security/operator/Constants.java | 1 - .../ReloadRemoteClusterCredentialsIT.java | 314 ------------------ .../xpack/security/Security.java | 104 ++---- ...tReloadRemoteClusterCredentialsAction.java | 54 --- .../RemoteClusterCredentialsResolver.java | 51 +++ .../SecurityServerTransportInterceptor.java | 45 ++- .../xpack/security/LocalStateSecurity.java | 14 +- .../xpack/security/SecurityTests.java | 102 ------ ...RemoteClusterCredentialsResolverTests.java | 38 +++ ...curityServerTransportInterceptorTests.java | 77 +++-- 25 files changed, 260 insertions(+), 1054 deletions(-) delete mode 100644 docs/changelog/102798.yaml delete mode 100644 server/src/main/java/org/elasticsearch/transport/RemoteClusterCredentialsManager.java delete mode 100644 server/src/test/java/org/elasticsearch/transport/RemoteClusterCredentialsManagerTests.java delete mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/settings/ReloadRemoteClusterCredentialsAction.java delete mode 100644 x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/ReloadRemoteClusterCredentialsIT.java delete mode 100644 x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/settings/TransportReloadRemoteClusterCredentialsAction.java create mode 100644 x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/RemoteClusterCredentialsResolver.java create mode 100644 x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/RemoteClusterCredentialsResolverTests.java diff --git a/docs/changelog/102798.yaml b/docs/changelog/102798.yaml deleted file mode 100644 index 986ad99f96a19..0000000000000 --- a/docs/changelog/102798.yaml +++ /dev/null @@ -1,5 +0,0 @@ -pr: 102798 -summary: Hot-reloadable remote cluster credentials -area: Security -type: enhancement -issues: [] diff --git a/server/src/main/java/org/elasticsearch/transport/ProxyConnectionStrategy.java b/server/src/main/java/org/elasticsearch/transport/ProxyConnectionStrategy.java index cfb6f872ce748..320b9cfdbf7e6 100644 --- a/server/src/main/java/org/elasticsearch/transport/ProxyConnectionStrategy.java +++ b/server/src/main/java/org/elasticsearch/transport/ProxyConnectionStrategy.java @@ -179,7 +179,7 @@ public class ProxyConnectionStrategy extends RemoteConnectionStrategy { RemoteConnectionManager.wrapConnectionWithRemoteClusterInfo( newConnection, clusterAlias, - connectionManager.getCredentialsManager() + actualProfile.getTransportProfile() ), actualProfile.getHandshakeTimeout(), cn -> true, diff --git a/server/src/main/java/org/elasticsearch/transport/RemoteClusterConnection.java b/server/src/main/java/org/elasticsearch/transport/RemoteClusterConnection.java index 3c74e46851504..a055e4122257f 100644 --- a/server/src/main/java/org/elasticsearch/transport/RemoteClusterConnection.java +++ b/server/src/main/java/org/elasticsearch/transport/RemoteClusterConnection.java @@ -57,28 +57,15 @@ final class RemoteClusterConnection implements Closeable { * @param settings the nodes settings object * @param clusterAlias the configured alias of the cluster to connect to * @param transportService the local nodes transport service - * @param credentialsManager object to lookup remote cluster credentials by cluster alias. If a cluster is protected by a credential, - * i.e. it has a credential configured via secure setting. - * This means the remote cluster uses the advances RCS model (as opposed to the basic model). + * @param credentialsProtected Whether the remote cluster is protected by a credentials, i.e. it has a credentials configured + * via secure setting. This means the remote cluster uses the new configurable access RCS model + * (as opposed to the basic model). */ - RemoteClusterConnection( - Settings settings, - String clusterAlias, - TransportService transportService, - RemoteClusterCredentialsManager credentialsManager - ) { + RemoteClusterConnection(Settings settings, String clusterAlias, TransportService transportService, boolean credentialsProtected) { this.transportService = transportService; this.clusterAlias = clusterAlias; - ConnectionProfile profile = RemoteConnectionStrategy.buildConnectionProfile( - clusterAlias, - settings, - credentialsManager.hasCredentials(clusterAlias) - ); - this.remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - credentialsManager, - createConnectionManager(profile, transportService) - ); + ConnectionProfile profile = RemoteConnectionStrategy.buildConnectionProfile(clusterAlias, settings, credentialsProtected); + this.remoteConnectionManager = new RemoteConnectionManager(clusterAlias, createConnectionManager(profile, transportService)); this.connectionStrategy = RemoteConnectionStrategy.buildStrategy(clusterAlias, transportService, remoteConnectionManager, settings); // we register the transport service here as a listener to make sure we notify handlers on disconnect etc. this.remoteConnectionManager.addListener(transportService); diff --git a/server/src/main/java/org/elasticsearch/transport/RemoteClusterCredentialsManager.java b/server/src/main/java/org/elasticsearch/transport/RemoteClusterCredentialsManager.java deleted file mode 100644 index 32a5e196c3a0b..0000000000000 --- a/server/src/main/java/org/elasticsearch/transport/RemoteClusterCredentialsManager.java +++ /dev/null @@ -1,52 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.transport; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.settings.SecureString; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.core.Nullable; - -import java.util.Map; - -import static org.elasticsearch.transport.RemoteClusterService.REMOTE_CLUSTER_CREDENTIALS; - -public class RemoteClusterCredentialsManager { - - private static final Logger logger = LogManager.getLogger(RemoteClusterCredentialsManager.class); - - private volatile Map clusterCredentials; - - public RemoteClusterCredentialsManager(Settings settings) { - updateClusterCredentials(settings); - } - - public void updateClusterCredentials(Settings settings) { - clusterCredentials = REMOTE_CLUSTER_CREDENTIALS.getAsMap(settings); - logger.debug( - () -> Strings.format( - "Updated remote cluster credentials for clusters: [%s]", - Strings.collectionToCommaDelimitedString(clusterCredentials.keySet()) - ) - ); - } - - @Nullable - public SecureString resolveCredentials(String clusterAlias) { - return clusterCredentials.get(clusterAlias); - } - - public boolean hasCredentials(String clusterAlias) { - return clusterCredentials.containsKey(clusterAlias); - } - - public static final RemoteClusterCredentialsManager EMPTY = new RemoteClusterCredentialsManager(Settings.EMPTY); -} diff --git a/server/src/main/java/org/elasticsearch/transport/RemoteClusterService.java b/server/src/main/java/org/elasticsearch/transport/RemoteClusterService.java index 6bfbb95cbcfe9..c38f4b26c665f 100644 --- a/server/src/main/java/org/elasticsearch/transport/RemoteClusterService.java +++ b/server/src/main/java/org/elasticsearch/transport/RemoteClusterService.java @@ -147,14 +147,15 @@ public boolean isRemoteClusterServerEnabled() { private final TransportService transportService; private final Map remoteClusters = ConcurrentCollections.newConcurrentMap(); - private final RemoteClusterCredentialsManager remoteClusterCredentialsManager; + private final Set credentialsProtectedRemoteClusters; RemoteClusterService(Settings settings, TransportService transportService) { super(settings); this.enabled = DiscoveryNode.isRemoteClusterClient(settings); this.remoteClusterServerEnabled = REMOTE_CLUSTER_SERVER_ENABLED.get(settings); this.transportService = transportService; - this.remoteClusterCredentialsManager = new RemoteClusterCredentialsManager(settings); + this.credentialsProtectedRemoteClusters = REMOTE_CLUSTER_CREDENTIALS.getAsMap(settings).keySet(); + if (remoteClusterServerEnabled) { registerRemoteClusterHandshakeRequestHandler(transportService); } @@ -304,14 +305,6 @@ private synchronized void updateSkipUnavailable(String clusterAlias, Boolean ski } } - public void updateRemoteClusterCredentials(Settings settings) { - remoteClusterCredentialsManager.updateClusterCredentials(settings); - } - - public RemoteClusterCredentialsManager getRemoteClusterCredentialsManager() { - return remoteClusterCredentialsManager; - } - @Override protected void updateRemoteCluster(String clusterAlias, Settings settings) { CountDownLatch latch = new CountDownLatch(1); @@ -370,7 +363,12 @@ synchronized void updateRemoteCluster( if (remote == null) { // this is a new cluster we have to add a new representation Settings finalSettings = Settings.builder().put(this.settings, false).put(newSettings, false).build(); - remote = new RemoteClusterConnection(finalSettings, clusterAlias, transportService, remoteClusterCredentialsManager); + remote = new RemoteClusterConnection( + finalSettings, + clusterAlias, + transportService, + credentialsProtectedRemoteClusters.contains(clusterAlias) + ); remoteClusters.put(clusterAlias, remote); remote.ensureConnected(listener.map(ignored -> RemoteClusterConnectionStatus.CONNECTED)); } else if (remote.shouldRebuildConnection(newSettings)) { @@ -382,7 +380,12 @@ synchronized void updateRemoteCluster( } remoteClusters.remove(clusterAlias); Settings finalSettings = Settings.builder().put(this.settings, false).put(newSettings, false).build(); - remote = new RemoteClusterConnection(finalSettings, clusterAlias, transportService, remoteClusterCredentialsManager); + remote = new RemoteClusterConnection( + finalSettings, + clusterAlias, + transportService, + credentialsProtectedRemoteClusters.contains(clusterAlias) + ); remoteClusters.put(clusterAlias, remote); remote.ensureConnected(listener.map(ignored -> RemoteClusterConnectionStatus.RECONNECTED)); } else { diff --git a/server/src/main/java/org/elasticsearch/transport/RemoteConnectionManager.java b/server/src/main/java/org/elasticsearch/transport/RemoteConnectionManager.java index 3b531d54fb033..b16734b273376 100644 --- a/server/src/main/java/org/elasticsearch/transport/RemoteConnectionManager.java +++ b/server/src/main/java/org/elasticsearch/transport/RemoteConnectionManager.java @@ -12,7 +12,6 @@ import org.elasticsearch.TransportVersion; import org.elasticsearch.action.ActionListener; import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.common.util.CollectionUtils; import org.elasticsearch.core.Nullable; import org.elasticsearch.core.Releasable; @@ -26,19 +25,18 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicLong; +import static org.elasticsearch.transport.RemoteClusterPortSettings.REMOTE_CLUSTER_PROFILE; import static org.elasticsearch.transport.RemoteClusterService.REMOTE_CLUSTER_HANDSHAKE_ACTION_NAME; public class RemoteConnectionManager implements ConnectionManager { private final String clusterAlias; - private final RemoteClusterCredentialsManager credentialsManager; private final ConnectionManager delegate; private final AtomicLong counter = new AtomicLong(); private volatile List connectedNodes = Collections.emptyList(); - RemoteConnectionManager(String clusterAlias, RemoteClusterCredentialsManager credentialsManager, ConnectionManager delegate) { + RemoteConnectionManager(String clusterAlias, ConnectionManager delegate) { this.clusterAlias = clusterAlias; - this.credentialsManager = credentialsManager; this.delegate = delegate; this.delegate.addListener(new TransportConnectionListener() { @Override @@ -53,10 +51,6 @@ public void onNodeDisconnected(DiscoveryNode node, Transport.Connection connecti }); } - public RemoteClusterCredentialsManager getCredentialsManager() { - return credentialsManager; - } - /** * Remote cluster connections have a different lifecycle from intra-cluster connections. Use {@link #connectToRemoteClusterNode} * instead of this method. @@ -101,7 +95,13 @@ public void openConnection(DiscoveryNode node, @Nullable ConnectionProfile profi node, profile, listener.delegateFailureAndWrap( - (l, connection) -> l.onResponse(wrapConnectionWithRemoteClusterInfo(connection, clusterAlias, credentialsManager)) + (l, connection) -> l.onResponse( + new InternalRemoteConnection( + connection, + clusterAlias, + profile != null ? profile.getTransportProfile() : getConnectionProfile().getTransportProfile() + ) + ) ) ); } @@ -182,35 +182,16 @@ public void closeNoBlock() { * @return a cluster alias if the connection target a node in the remote cluster, otherwise an empty result */ public static Optional resolveRemoteClusterAlias(Transport.Connection connection) { - return resolveRemoteClusterAliasWithCredentials(connection).map(RemoteClusterAliasWithCredentials::clusterAlias); - } - - public record RemoteClusterAliasWithCredentials(String clusterAlias, @Nullable SecureString credentials) { - @Override - public String toString() { - return "RemoteClusterAliasWithCredentials{clusterAlias='" + clusterAlias + "', credentials='::es_redacted::'}"; - } - } - - /** - * This method returns information (alias and credentials) for remote cluster for the given transport connection. - * Either or both of alias and credentials can be null depending on the connection. - * - * @param connection the transport connection for which to resolve a remote cluster alias - */ - public static Optional resolveRemoteClusterAliasWithCredentials(Transport.Connection connection) { Transport.Connection unwrapped = TransportService.unwrapConnection(connection); if (unwrapped instanceof InternalRemoteConnection remoteConnection) { - return Optional.of( - new RemoteClusterAliasWithCredentials(remoteConnection.getClusterAlias(), remoteConnection.getClusterCredentials()) - ); + return Optional.of(remoteConnection.getClusterAlias()); } return Optional.empty(); } private Transport.Connection getConnectionInternal(DiscoveryNode node) throws NodeNotConnectedException { Transport.Connection connection = delegate.getConnection(node); - return wrapConnectionWithRemoteClusterInfo(connection, clusterAlias, credentialsManager); + return new InternalRemoteConnection(connection, clusterAlias, getConnectionProfile().getTransportProfile()); } private synchronized void addConnectedNode(DiscoveryNode addedNode) { @@ -316,27 +297,21 @@ private static final class InternalRemoteConnection implements Transport.Connect private static final Logger logger = LogManager.getLogger(InternalRemoteConnection.class); private final Transport.Connection connection; private final String clusterAlias; - @Nullable - private final SecureString clusterCredentials; + private final boolean isRemoteClusterProfile; - private InternalRemoteConnection(Transport.Connection connection, String clusterAlias, @Nullable SecureString clusterCredentials) { + InternalRemoteConnection(Transport.Connection connection, String clusterAlias, String transportProfile) { assert false == connection instanceof InternalRemoteConnection : "should not double wrap"; assert false == connection instanceof ProxyConnection : "proxy connection should wrap internal remote connection, not the other way around"; - this.connection = Objects.requireNonNull(connection); this.clusterAlias = Objects.requireNonNull(clusterAlias); - this.clusterCredentials = clusterCredentials; + this.connection = Objects.requireNonNull(connection); + this.isRemoteClusterProfile = REMOTE_CLUSTER_PROFILE.equals(Objects.requireNonNull(transportProfile)); } public String getClusterAlias() { return clusterAlias; } - @Nullable - public SecureString getClusterCredentials() { - return clusterCredentials; - } - @Override public DiscoveryNode getNode() { return connection.getNode(); @@ -346,7 +321,7 @@ public DiscoveryNode getNode() { public void sendRequest(long requestId, String action, TransportRequest request, TransportRequestOptions options) throws IOException, TransportException { final String effectiveAction; - if (clusterCredentials != null && TransportService.HANDSHAKE_ACTION_NAME.equals(action)) { + if (isRemoteClusterProfile && TransportService.HANDSHAKE_ACTION_NAME.equals(action)) { logger.trace("sending remote cluster specific handshake to node [{}] of remote cluster [{}]", getNode(), clusterAlias); effectiveAction = REMOTE_CLUSTER_HANDSHAKE_ACTION_NAME; } else { @@ -414,8 +389,8 @@ public boolean hasReferences() { static InternalRemoteConnection wrapConnectionWithRemoteClusterInfo( Transport.Connection connection, String clusterAlias, - RemoteClusterCredentialsManager credentialsManager + String transportProfile ) { - return new InternalRemoteConnection(connection, clusterAlias, credentialsManager.resolveCredentials(clusterAlias)); + return new InternalRemoteConnection(connection, clusterAlias, transportProfile); } } diff --git a/server/src/main/java/org/elasticsearch/transport/SniffConnectionStrategy.java b/server/src/main/java/org/elasticsearch/transport/SniffConnectionStrategy.java index 0f68a58faf463..0dcad9cf6864c 100644 --- a/server/src/main/java/org/elasticsearch/transport/SniffConnectionStrategy.java +++ b/server/src/main/java/org/elasticsearch/transport/SniffConnectionStrategy.java @@ -357,11 +357,7 @@ private ConnectionManager.ConnectionValidator getConnectionValidator(DiscoveryNo : "transport profile must be consistent between the connection manager and the actual profile"; transportService.connectionValidator(node) .validate( - RemoteConnectionManager.wrapConnectionWithRemoteClusterInfo( - connection, - clusterAlias, - connectionManager.getCredentialsManager() - ), + RemoteConnectionManager.wrapConnectionWithRemoteClusterInfo(connection, clusterAlias, profile.getTransportProfile()), profile, listener ); diff --git a/server/src/test/java/org/elasticsearch/transport/ProxyConnectionStrategyTests.java b/server/src/test/java/org/elasticsearch/transport/ProxyConnectionStrategyTests.java index b3c7c5adac95d..ead43d0bac05e 100644 --- a/server/src/test/java/org/elasticsearch/transport/ProxyConnectionStrategyTests.java +++ b/server/src/test/java/org/elasticsearch/transport/ProxyConnectionStrategyTests.java @@ -130,11 +130,7 @@ public void testProxyStrategyWillOpenExpectedNumberOfConnectionsToAddress() { ); int numOfConnections = randomIntBetween(4, 8); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); ProxyConnectionStrategy strategy = new ProxyConnectionStrategy( clusterAlias, localService, @@ -192,11 +188,7 @@ public void testProxyStrategyWillOpenNewConnectionsOnDisconnect() throws Excepti AtomicBoolean useAddress1 = new AtomicBoolean(true); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); ProxyConnectionStrategy strategy = new ProxyConnectionStrategy( clusterAlias, localService, @@ -271,11 +263,7 @@ public void testConnectFailsWithIncompatibleNodes() { ); int numOfConnections = randomIntBetween(4, 8); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); ProxyConnectionStrategy strategy = new ProxyConnectionStrategy( clusterAlias, localService, @@ -340,11 +328,7 @@ public void testConnectFailsWithNonRetryableException() { ); int numOfConnections = randomIntBetween(4, 8); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); ProxyConnectionStrategy strategy = new ProxyConnectionStrategy( clusterAlias, localService, @@ -404,11 +388,7 @@ public void testClusterNameValidationPreventConnectingToDifferentClusters() thro AtomicBoolean useAddress1 = new AtomicBoolean(true); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); ProxyConnectionStrategy strategy = new ProxyConnectionStrategy( clusterAlias, localService, @@ -479,11 +459,7 @@ public void testProxyStrategyWillResolveAddressesEachConnect() throws Exception ); int numOfConnections = randomIntBetween(4, 8); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); ProxyConnectionStrategy strategy = new ProxyConnectionStrategy( clusterAlias, localService, @@ -535,11 +511,7 @@ public void onNodeConnected(DiscoveryNode node, Transport.Connection connection) }); try ( - var remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + var remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); var strategy = new ProxyConnectionStrategy( clusterAlias, localService, @@ -582,11 +554,7 @@ public void testProxyStrategyWillNeedToBeRebuiltIfNumOfSocketsOrAddressesOrServe ); int numOfConnections = randomIntBetween(4, 8); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); ProxyConnectionStrategy strategy = new ProxyConnectionStrategy( clusterAlias, localService, @@ -704,11 +672,7 @@ public void testServerNameAttributes() { ); int numOfConnections = randomIntBetween(4, 8); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); ProxyConnectionStrategy strategy = new ProxyConnectionStrategy( clusterAlias, localService, diff --git a/server/src/test/java/org/elasticsearch/transport/RemoteClusterConnectionTests.java b/server/src/test/java/org/elasticsearch/transport/RemoteClusterConnectionTests.java index cbe15cc9664f4..d4f03f1027838 100644 --- a/server/src/test/java/org/elasticsearch/transport/RemoteClusterConnectionTests.java +++ b/server/src/test/java/org/elasticsearch/transport/RemoteClusterConnectionTests.java @@ -62,7 +62,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Objects; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; @@ -253,14 +252,7 @@ public void run() { AtomicReference exceptionReference = new AtomicReference<>(); String clusterAlias = "test-cluster"; Settings settings = buildRandomSettings(clusterAlias, addresses(seedNode)); - try ( - RemoteClusterConnection connection = new RemoteClusterConnection( - settings, - clusterAlias, - service, - randomFrom(RemoteClusterCredentialsManager.EMPTY, buildCredentialsManager(clusterAlias)) - ) - ) { + try (RemoteClusterConnection connection = new RemoteClusterConnection(settings, clusterAlias, service, randomBoolean())) { ActionListener listener = ActionListener.wrap(x -> { listenerCalled.countDown(); fail("expected exception"); @@ -330,14 +322,7 @@ public void testCloseWhileConcurrentlyConnecting() throws IOException, Interrupt service.acceptIncomingRequests(); String clusterAlias = "test-cluster"; Settings settings = buildRandomSettings(clusterAlias, seedNodes); - try ( - RemoteClusterConnection connection = new RemoteClusterConnection( - settings, - clusterAlias, - service, - RemoteClusterCredentialsManager.EMPTY - ) - ) { + try (RemoteClusterConnection connection = new RemoteClusterConnection(settings, clusterAlias, service, false)) { int numThreads = randomIntBetween(4, 10); Thread[] threads = new Thread[numThreads]; CyclicBarrier barrier = new CyclicBarrier(numThreads + 1); @@ -485,12 +470,7 @@ private void doTestGetConnectionInfo(boolean hasClusterCredentials) throws Excep settings = Settings.builder().put(settings).setSecureSettings(secureSettings).build(); } try ( - RemoteClusterConnection connection = new RemoteClusterConnection( - settings, - clusterAlias, - service, - hasClusterCredentials ? buildCredentialsManager(clusterAlias) : RemoteClusterCredentialsManager.EMPTY - ) + RemoteClusterConnection connection = new RemoteClusterConnection(settings, clusterAlias, service, hasClusterCredentials) ) { // test no nodes connected RemoteConnectionInfo remoteConnectionInfo = assertSerialization(connection.getConnectionInfo()); @@ -682,12 +662,7 @@ private void doTestCollectNodes(boolean hasClusterCredentials) throws Exception } try ( - RemoteClusterConnection connection = new RemoteClusterConnection( - settings, - clusterAlias, - service, - hasClusterCredentials ? buildCredentialsManager(clusterAlias) : RemoteClusterCredentialsManager.EMPTY - ) + RemoteClusterConnection connection = new RemoteClusterConnection(settings, clusterAlias, service, hasClusterCredentials) ) { CountDownLatch responseLatch = new CountDownLatch(1); AtomicReference> reference = new AtomicReference<>(); @@ -738,14 +713,7 @@ public void testNoChannelsExceptREG() throws Exception { String clusterAlias = "test-cluster"; Settings settings = buildRandomSettings(clusterAlias, addresses(seedNode)); - try ( - RemoteClusterConnection connection = new RemoteClusterConnection( - settings, - clusterAlias, - service, - RemoteClusterCredentialsManager.EMPTY - ) - ) { + try (RemoteClusterConnection connection = new RemoteClusterConnection(settings, clusterAlias, service, false)) { PlainActionFuture plainActionFuture = new PlainActionFuture<>(); connection.ensureConnected(plainActionFuture); plainActionFuture.get(10, TimeUnit.SECONDS); @@ -811,14 +779,7 @@ public void testConnectedNodesConcurrentAccess() throws IOException, Interrupted String clusterAlias = "test-cluster"; Settings settings = buildRandomSettings(clusterAlias, seedNodes); - try ( - RemoteClusterConnection connection = new RemoteClusterConnection( - settings, - clusterAlias, - service, - randomFrom(RemoteClusterCredentialsManager.EMPTY, buildCredentialsManager(clusterAlias)) - ) - ) { + try (RemoteClusterConnection connection = new RemoteClusterConnection(settings, clusterAlias, service, randomBoolean())) { final int numGetThreads = randomIntBetween(4, 10); final Thread[] getThreads = new Thread[numGetThreads]; final int numModifyingThreads = randomIntBetween(4, 10); @@ -912,14 +873,7 @@ public void testGetConnection() throws Exception { service.acceptIncomingRequests(); String clusterAlias = "test-cluster"; Settings settings = buildRandomSettings(clusterAlias, addresses(seedNode)); - try ( - RemoteClusterConnection connection = new RemoteClusterConnection( - settings, - clusterAlias, - service, - RemoteClusterCredentialsManager.EMPTY - ) - ) { + try (RemoteClusterConnection connection = new RemoteClusterConnection(settings, clusterAlias, service, false)) { PlainActionFuture.get(fut -> connection.ensureConnected(fut.map(x -> null))); for (int i = 0; i < 10; i++) { // always a direct connection as the remote node is already connected @@ -967,13 +921,4 @@ private static Settings buildSniffSettings(String clusterAlias, List see ); return builder.build(); } - - private static RemoteClusterCredentialsManager buildCredentialsManager(String clusterAlias) { - Objects.requireNonNull(clusterAlias); - final Settings.Builder builder = Settings.builder(); - final MockSecureSettings secureSettings = new MockSecureSettings(); - secureSettings.setString("cluster.remote." + clusterAlias + ".credentials", randomAlphaOfLength(20)); - builder.setSecureSettings(secureSettings); - return new RemoteClusterCredentialsManager(builder.build()); - } } diff --git a/server/src/test/java/org/elasticsearch/transport/RemoteClusterCredentialsManagerTests.java b/server/src/test/java/org/elasticsearch/transport/RemoteClusterCredentialsManagerTests.java deleted file mode 100644 index f02148a40e47e..0000000000000 --- a/server/src/test/java/org/elasticsearch/transport/RemoteClusterCredentialsManagerTests.java +++ /dev/null @@ -1,43 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.transport; - -import org.elasticsearch.common.settings.MockSecureSettings; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.test.ESTestCase; - -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; - -public class RemoteClusterCredentialsManagerTests extends ESTestCase { - public void testResolveRemoteClusterCredentials() { - final String clusterAlias = randomAlphaOfLength(9); - final String otherClusterAlias = randomAlphaOfLength(10); - - final String secret = randomAlphaOfLength(20); - final Settings settings = buildSettingsWithCredentials(clusterAlias, secret); - RemoteClusterCredentialsManager credentialsManager = new RemoteClusterCredentialsManager(settings); - assertThat(credentialsManager.resolveCredentials(clusterAlias).toString(), equalTo(secret)); - assertThat(credentialsManager.hasCredentials(otherClusterAlias), is(false)); - - final String updatedSecret = randomAlphaOfLength(21); - credentialsManager.updateClusterCredentials(buildSettingsWithCredentials(clusterAlias, updatedSecret)); - assertThat(credentialsManager.resolveCredentials(clusterAlias).toString(), equalTo(updatedSecret)); - - credentialsManager.updateClusterCredentials(Settings.EMPTY); - assertThat(credentialsManager.hasCredentials(clusterAlias), is(false)); - } - - private Settings buildSettingsWithCredentials(String clusterAlias, String secret) { - final Settings.Builder builder = Settings.builder(); - final MockSecureSettings secureSettings = new MockSecureSettings(); - secureSettings.setString("cluster.remote." + clusterAlias + ".credentials", secret); - return builder.setSecureSettings(secureSettings).build(); - } -} diff --git a/server/src/test/java/org/elasticsearch/transport/RemoteConnectionManagerTests.java b/server/src/test/java/org/elasticsearch/transport/RemoteConnectionManagerTests.java index b1ffda669e6a1..839138d3c7c34 100644 --- a/server/src/test/java/org/elasticsearch/transport/RemoteConnectionManagerTests.java +++ b/server/src/test/java/org/elasticsearch/transport/RemoteConnectionManagerTests.java @@ -13,7 +13,6 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.node.DiscoveryNodeUtils; import org.elasticsearch.common.Strings; -import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.common.util.concurrent.ThreadContext; @@ -24,20 +23,17 @@ import java.io.IOException; import java.net.InetAddress; import java.util.HashSet; -import java.util.Optional; import java.util.Set; import java.util.concurrent.ExecutionException; import static org.elasticsearch.transport.RemoteClusterService.REMOTE_CLUSTER_HANDSHAKE_ACTION_NAME; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; public class RemoteConnectionManagerTests extends ESTestCase { @@ -53,7 +49,6 @@ public void setUp() throws Exception { transport = mock(Transport.class); remoteConnectionManager = new RemoteConnectionManager( "remote-cluster", - RemoteClusterCredentialsManager.EMPTY, new ClusterConnectionManager(Settings.EMPTY, transport, new ThreadContext(Settings.EMPTY)) ); @@ -125,13 +120,10 @@ public void testResolveRemoteClusterAlias() throws ExecutionException, Interrupt public void testRewriteHandshakeAction() throws IOException { final Transport.Connection connection = mock(Transport.Connection.class); - final String clusterAlias = randomAlphaOfLengthBetween(3, 8); - final RemoteClusterCredentialsManager credentialsResolver = mock(RemoteClusterCredentialsManager.class); - when(credentialsResolver.resolveCredentials(clusterAlias)).thenReturn(new SecureString(randomAlphaOfLength(42))); final Transport.Connection wrappedConnection = RemoteConnectionManager.wrapConnectionWithRemoteClusterInfo( connection, - clusterAlias, - credentialsResolver + randomAlphaOfLengthBetween(3, 8), + RemoteClusterPortSettings.REMOTE_CLUSTER_PROFILE ); final long requestId = randomLong(); final TransportRequest request = mock(TransportRequest.class); @@ -150,26 +142,6 @@ public void testRewriteHandshakeAction() throws IOException { verify(connection).sendRequest(requestId, anotherAction, request, options); } - public void testWrapAndResolveConnectionRoundTrip() { - final Transport.Connection connection = mock(Transport.Connection.class); - final String clusterAlias = randomAlphaOfLengthBetween(3, 8); - final RemoteClusterCredentialsManager credentialsResolver = mock(RemoteClusterCredentialsManager.class); - final SecureString credentials = new SecureString(randomAlphaOfLength(42)); - // second credential will never be resolved - when(credentialsResolver.resolveCredentials(clusterAlias)).thenReturn(credentials, (SecureString) null); - final Transport.Connection wrappedConnection = RemoteConnectionManager.wrapConnectionWithRemoteClusterInfo( - connection, - clusterAlias, - credentialsResolver - ); - - final Optional actual = RemoteConnectionManager - .resolveRemoteClusterAliasWithCredentials(wrappedConnection); - - assertThat(actual.isPresent(), is(true)); - assertThat(actual.get(), equalTo(new RemoteConnectionManager.RemoteClusterAliasWithCredentials(clusterAlias, credentials))); - } - private static class TestRemoteConnection extends CloseableConnection { private final DiscoveryNode node; diff --git a/server/src/test/java/org/elasticsearch/transport/RemoteConnectionStrategyTests.java b/server/src/test/java/org/elasticsearch/transport/RemoteConnectionStrategyTests.java index ca9986ba5eb1f..5d461e906a266 100644 --- a/server/src/test/java/org/elasticsearch/transport/RemoteConnectionStrategyTests.java +++ b/server/src/test/java/org/elasticsearch/transport/RemoteConnectionStrategyTests.java @@ -26,11 +26,7 @@ public void testStrategyChangeMeansThatStrategyMustBeRebuilt() { mock(Transport.class), threadContext ); - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - "cluster-alias", - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager("cluster-alias", connectionManager); FakeConnectionStrategy first = new FakeConnectionStrategy( "cluster-alias", mock(TransportService.class), @@ -50,11 +46,7 @@ public void testSameStrategyChangeMeansThatStrategyDoesNotNeedToBeRebuilt() { mock(Transport.class), threadContext ); - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - "cluster-alias", - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager("cluster-alias", connectionManager); FakeConnectionStrategy first = new FakeConnectionStrategy( "cluster-alias", mock(TransportService.class), @@ -77,11 +69,7 @@ public void testChangeInConnectionProfileMeansTheStrategyMustBeRebuilt() { assertEquals(TimeValue.MINUS_ONE, connectionManager.getConnectionProfile().getPingInterval()); assertEquals(Compression.Enabled.INDEXING_DATA, connectionManager.getConnectionProfile().getCompressionEnabled()); assertEquals(Compression.Scheme.LZ4, connectionManager.getConnectionProfile().getCompressionScheme()); - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - "cluster-alias", - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager("cluster-alias", connectionManager); FakeConnectionStrategy first = new FakeConnectionStrategy( "cluster-alias", mock(TransportService.class), diff --git a/server/src/test/java/org/elasticsearch/transport/SniffConnectionStrategyTests.java b/server/src/test/java/org/elasticsearch/transport/SniffConnectionStrategyTests.java index ddee1ff4d690a..3c955258d45c8 100644 --- a/server/src/test/java/org/elasticsearch/transport/SniffConnectionStrategyTests.java +++ b/server/src/test/java/org/elasticsearch/transport/SniffConnectionStrategyTests.java @@ -192,11 +192,7 @@ public void testSniffStrategyWillConnectToAndDiscoverNodes() { threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - hasClusterCredentials ? new RemoteClusterCredentialsManager(clientSettings) : RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -266,11 +262,7 @@ public void testSniffStrategyWillResolveDiscoveryNodesEachConnect() throws Excep threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -344,11 +336,7 @@ public void testSniffStrategyWillConnectToMaxAllowedNodesAndOpenNewConnectionsOn threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -436,11 +424,7 @@ public void testDiscoverWithSingleIncompatibleSeedNode() { threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -502,11 +486,7 @@ public void testConnectFailsWithIncompatibleNodes() { threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -569,11 +549,7 @@ public void testFilterNodesWithNodePredicate() { threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -641,11 +617,7 @@ public void testConnectFailsIfNoConnectionsOpened() { threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -722,11 +694,7 @@ public void testClusterNameValidationPreventConnectingToDifferentClusters() thro threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -815,11 +783,7 @@ public void testMultipleCallsToConnectEnsuresConnection() { threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -931,11 +895,7 @@ public void testConfiguredProxyAddressModeWillReplaceNodeAddress() { threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, @@ -1004,11 +964,7 @@ public void testSniffStrategyWillNeedToBeRebuiltIfNumOfConnectionsOrSeedsOrProxy threadPool.getThreadContext() ); try ( - RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager( - clusterAlias, - RemoteClusterCredentialsManager.EMPTY, - connectionManager - ); + RemoteConnectionManager remoteConnectionManager = new RemoteConnectionManager(clusterAlias, connectionManager); SniffConnectionStrategy strategy = new SniffConnectionStrategy( clusterAlias, localService, diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/settings/ReloadRemoteClusterCredentialsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/settings/ReloadRemoteClusterCredentialsAction.java deleted file mode 100644 index 27b9460dd67cb..0000000000000 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/settings/ReloadRemoteClusterCredentialsAction.java +++ /dev/null @@ -1,50 +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.core.security.action.settings; - -import org.elasticsearch.action.ActionRequest; -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.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Writeable; -import org.elasticsearch.common.settings.Settings; - -import java.io.IOException; - -public class ReloadRemoteClusterCredentialsAction extends ActionType { - public static final String NAME = "cluster:admin/xpack/security/remote_cluster_credentials/reload"; - public static final ReloadRemoteClusterCredentialsAction INSTANCE = new ReloadRemoteClusterCredentialsAction(); - - private ReloadRemoteClusterCredentialsAction() { - super(NAME, Writeable.Reader.localOnly()); - } - - public static class Request extends ActionRequest { - private final Settings settings; - - public Request(Settings settings) { - this.settings = settings; - } - - @Override - public ActionRequestValidationException validate() { - return null; - } - - public Settings getSettings() { - return settings; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - TransportAction.localOnly(); - } - } -} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/SystemPrivilege.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/SystemPrivilege.java index 4d24a757537e2..bc42632507256 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/SystemPrivilege.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/SystemPrivilege.java @@ -12,7 +12,6 @@ import org.elasticsearch.index.seqno.RetentionLeaseSyncAction; import org.elasticsearch.persistent.CompletionPersistentTaskAction; import org.elasticsearch.transport.TransportActionProxy; -import org.elasticsearch.xpack.core.security.action.settings.ReloadRemoteClusterCredentialsAction; import org.elasticsearch.xpack.core.security.support.StringMatcher; import java.util.Collections; @@ -44,8 +43,7 @@ public final class SystemPrivilege extends Privilege { "indices:data/read/*", // needed for SystemIndexMigrator "indices:admin/refresh", // needed for SystemIndexMigrator "indices:admin/aliases", // needed for SystemIndexMigrator - TransportSearchShardsAction.TYPE.name(), // added so this API can be called with the system user by other APIs - ReloadRemoteClusterCredentialsAction.NAME // needed for Security plugin reload of remote cluster credentials + TransportSearchShardsAction.TYPE.name() // added so this API can be called with the system user by other APIs ); private static final Predicate PREDICATE = (action) -> { 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 ea27eb9406d09..6e78eb2fb5b83 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 @@ -255,7 +255,6 @@ public class Constants { "cluster:admin/xpack/security/profile/suggest", "cluster:admin/xpack/security/profile/set_enabled", "cluster:admin/xpack/security/realm/cache/clear", - "cluster:admin/xpack/security/remote_cluster_credentials/reload", "cluster:admin/xpack/security/role/delete", "cluster:admin/xpack/security/role/get", "cluster:admin/xpack/security/role/put", diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/ReloadRemoteClusterCredentialsIT.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/ReloadRemoteClusterCredentialsIT.java deleted file mode 100644 index 6042d0072270d..0000000000000 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/ReloadRemoteClusterCredentialsIT.java +++ /dev/null @@ -1,314 +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.security; - -import org.apache.lucene.search.TotalHits; -import org.elasticsearch.TransportVersion; -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.admin.cluster.node.reload.NodesReloadSecureSettingsResponse; -import org.elasticsearch.action.admin.cluster.remote.RemoteClusterNodesAction; -import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest; -import org.elasticsearch.action.admin.cluster.state.ClusterStateAction; -import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest; -import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse; -import org.elasticsearch.action.search.SearchRequest; -import org.elasticsearch.action.search.SearchResponse; -import org.elasticsearch.action.search.SearchShardsRequest; -import org.elasticsearch.action.search.SearchShardsResponse; -import org.elasticsearch.action.search.ShardSearchFailure; -import org.elasticsearch.action.search.TransportSearchAction; -import org.elasticsearch.action.search.TransportSearchShardsAction; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.cluster.ClusterState; -import org.elasticsearch.cluster.node.VersionInformation; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.settings.KeyStoreWrapper; -import org.elasticsearch.common.settings.SecureString; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.transport.TransportAddress; -import org.elasticsearch.common.util.concurrent.ConcurrentCollections; -import org.elasticsearch.common.util.concurrent.EsExecutors; -import org.elasticsearch.env.Environment; -import org.elasticsearch.search.SearchHit; -import org.elasticsearch.search.SearchHits; -import org.elasticsearch.search.aggregations.InternalAggregations; -import org.elasticsearch.search.internal.InternalSearchResponse; -import org.elasticsearch.test.SecuritySingleNodeTestCase; -import org.elasticsearch.test.transport.MockTransportService; -import org.elasticsearch.threadpool.TestThreadPool; -import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.transport.RemoteClusterCredentialsManager; -import org.elasticsearch.transport.TransportService; -import org.elasticsearch.xpack.security.authc.ApiKeyService; -import org.elasticsearch.xpack.security.authc.CrossClusterAccessHeaders; -import org.junit.BeforeClass; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; - -import static org.hamcrest.Matchers.empty; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasKey; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; - -public class ReloadRemoteClusterCredentialsIT extends SecuritySingleNodeTestCase { - private static final String CLUSTER_ALIAS = "my_remote_cluster"; - - @BeforeClass - public static void disableInFips() { - assumeFalse( - "Cannot run in FIPS mode since the keystore will be password protected and sending a password in the reload" - + "settings api call, require TLS to be configured for the transport layer", - inFipsJvm() - ); - } - - @Override - public String configRoles() { - return org.elasticsearch.core.Strings.format(""" - user: - cluster: [ "ALL" ] - indices: - - names: '*' - privileges: [ "ALL" ] - remote_indices: - - names: '*' - privileges: [ "ALL" ] - clusters: ["*"] - """); - } - - @Override - public void tearDown() throws Exception { - try { - clearRemoteCluster(); - super.tearDown(); - } finally { - ThreadPool.terminate(threadPool, 10, TimeUnit.SECONDS); - } - } - - private final ThreadPool threadPool = new TestThreadPool(getClass().getName()); - - public void testReloadRemoteClusterCredentials() throws Exception { - final String credentials = randomAlphaOfLength(42); - writeCredentialsToKeyStore(credentials); - final RemoteClusterCredentialsManager clusterCredentialsManager = getInstanceFromNode(TransportService.class) - .getRemoteClusterService() - .getRemoteClusterCredentialsManager(); - // Until we reload, credentials written to keystore are not loaded into the credentials manager - assertThat(clusterCredentialsManager.hasCredentials(CLUSTER_ALIAS), is(false)); - reloadSecureSettings(); - assertThat(clusterCredentialsManager.resolveCredentials(CLUSTER_ALIAS), equalTo(credentials)); - - // Check that credentials get used for a remote connection, once we configure it - final BlockingQueue> capturedHeaders = ConcurrentCollections.newBlockingQueue(); - try (MockTransportService remoteTransport = startTransport("remoteNodeA", threadPool, capturedHeaders)) { - final TransportAddress remoteAddress = remoteTransport.getOriginalTransport() - .profileBoundAddresses() - .get("_remote_cluster") - .publishAddress(); - - configureRemoteCluster(remoteAddress); - - // Run search to trigger header capturing on the receiving side - client().search(new SearchRequest(CLUSTER_ALIAS + ":index-a")).get(); - - assertHeadersContainCredentialsThenClear(credentials, capturedHeaders); - - // Update credentials and ensure they are used - final String updatedCredentials = randomAlphaOfLength(41); - writeCredentialsToKeyStore(updatedCredentials); - reloadSecureSettings(); - - client().search(new SearchRequest(CLUSTER_ALIAS + ":index-a")).get(); - - assertHeadersContainCredentialsThenClear(updatedCredentials, capturedHeaders); - } - } - - private void assertHeadersContainCredentialsThenClear(String credentials, BlockingQueue> capturedHeaders) { - assertThat(capturedHeaders, is(not(empty()))); - for (Map actualHeaders : capturedHeaders) { - assertThat(actualHeaders, hasKey(CrossClusterAccessHeaders.CROSS_CLUSTER_ACCESS_CREDENTIALS_HEADER_KEY)); - assertThat( - actualHeaders.get(CrossClusterAccessHeaders.CROSS_CLUSTER_ACCESS_CREDENTIALS_HEADER_KEY), - equalTo(ApiKeyService.withApiKeyPrefix(credentials)) - ); - } - capturedHeaders.clear(); - assertThat(capturedHeaders, is(empty())); - } - - private void clearRemoteCluster() throws InterruptedException, ExecutionException { - final var builder = Settings.builder() - .putNull("cluster.remote." + CLUSTER_ALIAS + ".mode") - .putNull("cluster.remote." + CLUSTER_ALIAS + ".seeds") - .putNull("cluster.remote." + CLUSTER_ALIAS + ".proxy_address"); - clusterAdmin().updateSettings(new ClusterUpdateSettingsRequest().persistentSettings(builder)).get(); - } - - @Override - protected Settings nodeSettings() { - return Settings.builder().put(super.nodeSettings()).put("xpack.security.remote_cluster_client.ssl.enabled", false).build(); - } - - private void configureRemoteCluster(TransportAddress remoteAddress) throws InterruptedException, ExecutionException { - final Settings.Builder builder = Settings.builder(); - if (randomBoolean()) { - builder.put("cluster.remote." + CLUSTER_ALIAS + ".mode", "sniff") - .put("cluster.remote." + CLUSTER_ALIAS + ".seeds", remoteAddress.toString()) - .putNull("cluster.remote." + CLUSTER_ALIAS + ".proxy_address"); - } else { - builder.put("cluster.remote." + CLUSTER_ALIAS + ".mode", "proxy") - .put("cluster.remote." + CLUSTER_ALIAS + ".proxy_address", remoteAddress.toString()) - .putNull("cluster.remote." + CLUSTER_ALIAS + ".seeds"); - } - clusterAdmin().updateSettings(new ClusterUpdateSettingsRequest().persistentSettings(builder)).get(); - } - - private void writeCredentialsToKeyStore(String credentials) throws Exception { - final Environment environment = getInstanceFromNode(Environment.class); - final KeyStoreWrapper keyStoreWrapper = KeyStoreWrapper.create(); - keyStoreWrapper.setString("cluster.remote." + CLUSTER_ALIAS + ".credentials", credentials.toCharArray()); - keyStoreWrapper.save(environment.configFile(), new char[0], false); - } - - public static MockTransportService startTransport( - final String nodeName, - final ThreadPool threadPool, - final BlockingQueue> capturedHeaders - ) { - boolean success = false; - final Settings settings = Settings.builder() - .put("node.name", nodeName) - .put("remote_cluster_server.enabled", "true") - .put("remote_cluster.port", "0") - .put("xpack.security.remote_cluster_server.ssl.enabled", "false") - .build(); - final MockTransportService service = MockTransportService.createNewService( - settings, - VersionInformation.CURRENT, - TransportVersion.current(), - threadPool, - null - ); - try { - service.registerRequestHandler( - ClusterStateAction.NAME, - EsExecutors.DIRECT_EXECUTOR_SERVICE, - ClusterStateRequest::new, - (request, channel, task) -> { - capturedHeaders.add(Map.copyOf(threadPool.getThreadContext().getHeaders())); - channel.sendResponse( - new ClusterStateResponse(ClusterName.DEFAULT, ClusterState.builder(ClusterName.DEFAULT).build(), false) - ); - } - ); - service.registerRequestHandler( - RemoteClusterNodesAction.TYPE.name(), - EsExecutors.DIRECT_EXECUTOR_SERVICE, - RemoteClusterNodesAction.Request::new, - (request, channel, task) -> { - capturedHeaders.add(Map.copyOf(threadPool.getThreadContext().getHeaders())); - channel.sendResponse(new RemoteClusterNodesAction.Response(List.of())); - } - ); - service.registerRequestHandler( - TransportSearchShardsAction.TYPE.name(), - EsExecutors.DIRECT_EXECUTOR_SERVICE, - SearchShardsRequest::new, - (request, channel, task) -> { - capturedHeaders.add(Map.copyOf(threadPool.getThreadContext().getHeaders())); - channel.sendResponse(new SearchShardsResponse(List.of(), List.of(), Collections.emptyMap())); - } - ); - service.registerRequestHandler( - TransportSearchAction.TYPE.name(), - EsExecutors.DIRECT_EXECUTOR_SERVICE, - SearchRequest::new, - (request, channel, task) -> { - capturedHeaders.add(Map.copyOf(threadPool.getThreadContext().getHeaders())); - channel.sendResponse( - new SearchResponse( - new InternalSearchResponse( - new SearchHits(new SearchHit[0], new TotalHits(0, TotalHits.Relation.EQUAL_TO), Float.NaN), - InternalAggregations.EMPTY, - null, - null, - false, - null, - 1 - ), - null, - 1, - 1, - 0, - 100, - ShardSearchFailure.EMPTY_ARRAY, - SearchResponse.Clusters.EMPTY - ) - ); - } - ); - service.start(); - service.acceptIncomingRequests(); - success = true; - return service; - } finally { - if (success == false) { - service.close(); - } - } - } - - private void reloadSecureSettings() throws InterruptedException { - final AtomicReference reloadSettingsError = new AtomicReference<>(); - final CountDownLatch latch = new CountDownLatch(1); - final SecureString emptyPassword = randomBoolean() ? new SecureString(new char[0]) : null; - clusterAdmin().prepareReloadSecureSettings() - .setSecureStorePassword(emptyPassword) - .setNodesIds(Strings.EMPTY_ARRAY) - .execute(new ActionListener<>() { - @Override - public void onResponse(NodesReloadSecureSettingsResponse nodesReloadResponse) { - try { - assertThat(nodesReloadResponse, notNullValue()); - final Map nodesMap = nodesReloadResponse.getNodesMap(); - assertThat(nodesMap.size(), equalTo(1)); - for (final NodesReloadSecureSettingsResponse.NodeResponse nodeResponse : nodesReloadResponse.getNodes()) { - assertThat(nodeResponse.reloadException(), nullValue()); - } - } catch (final AssertionError e) { - reloadSettingsError.set(e); - } finally { - latch.countDown(); - } - } - - @Override - public void onFailure(Exception e) { - reloadSettingsError.set(new AssertionError("Nodes request failed", e)); - latch.countDown(); - } - }); - latch.await(); - if (reloadSettingsError.get() != null) { - throw reloadSettingsError.get(); - } - } -} diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java index 349cebe7f705f..6d7f6fcd3822b 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java @@ -13,7 +13,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.lucene.util.SetOnce; -import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.TransportVersion; @@ -157,7 +156,6 @@ import org.elasticsearch.xpack.core.security.action.service.GetServiceAccountCredentialsAction; import org.elasticsearch.xpack.core.security.action.service.GetServiceAccountNodesCredentialsAction; import org.elasticsearch.xpack.core.security.action.settings.GetSecuritySettingsAction; -import org.elasticsearch.xpack.core.security.action.settings.ReloadRemoteClusterCredentialsAction; import org.elasticsearch.xpack.core.security.action.settings.UpdateSecuritySettingsAction; import org.elasticsearch.xpack.core.security.action.token.CreateTokenAction; import org.elasticsearch.xpack.core.security.action.token.InvalidateTokenAction; @@ -249,7 +247,6 @@ import org.elasticsearch.xpack.security.action.service.TransportGetServiceAccountCredentialsAction; import org.elasticsearch.xpack.security.action.service.TransportGetServiceAccountNodesCredentialsAction; import org.elasticsearch.xpack.security.action.settings.TransportGetSecuritySettingsAction; -import org.elasticsearch.xpack.security.action.settings.TransportReloadRemoteClusterCredentialsAction; import org.elasticsearch.xpack.security.action.settings.TransportUpdateSecuritySettingsAction; import org.elasticsearch.xpack.security.action.token.TransportCreateTokenAction; import org.elasticsearch.xpack.security.action.token.TransportInvalidateTokenAction; @@ -370,6 +367,7 @@ import org.elasticsearch.xpack.security.support.CacheInvalidatorRegistry; import org.elasticsearch.xpack.security.support.ExtensionComponents; import org.elasticsearch.xpack.security.support.SecuritySystemIndices; +import org.elasticsearch.xpack.security.transport.RemoteClusterCredentialsResolver; import org.elasticsearch.xpack.security.transport.SecurityHttpSettings; import org.elasticsearch.xpack.security.transport.SecurityServerTransportInterceptor; import org.elasticsearch.xpack.security.transport.filter.IPFilter; @@ -559,7 +557,6 @@ public class Security extends Plugin private final SetOnce reservedRoleMappingAction = new SetOnce<>(); private final SetOnce workflowService = new SetOnce<>(); private final SetOnce realms = new SetOnce<>(); - private final SetOnce client = new SetOnce<>(); public Security(Settings settings) { this(settings, Collections.emptyList()); @@ -579,30 +576,25 @@ public Security(Settings settings) { runStartupChecks(settings); Automatons.updateConfiguration(settings); } else { - ensureNoRemoteClusterCredentialsOnDisabledSecurity(settings); + final List remoteClusterCredentialsSettingKeys = RemoteClusterService.REMOTE_CLUSTER_CREDENTIALS.getAllConcreteSettings( + settings + ).map(Setting::getKey).sorted().toList(); + if (false == remoteClusterCredentialsSettingKeys.isEmpty()) { + throw new IllegalArgumentException( + format( + "Found [%s] remote clusters with credentials [%s]. Security [%s] must be enabled to connect to them. " + + "Please either enable security or remove these settings from the keystore.", + remoteClusterCredentialsSettingKeys.size(), + Strings.collectionToCommaDelimitedString(remoteClusterCredentialsSettingKeys), + XPackSettings.SECURITY_ENABLED.getKey() + ) + ); + } this.bootstrapChecks.set(Collections.emptyList()); } this.securityExtensions.addAll(extensions); } - private void ensureNoRemoteClusterCredentialsOnDisabledSecurity(Settings settings) { - assert false == enabled; - final List remoteClusterCredentialsSettingKeys = RemoteClusterService.REMOTE_CLUSTER_CREDENTIALS.getAllConcreteSettings( - settings - ).map(Setting::getKey).sorted().toList(); - if (false == remoteClusterCredentialsSettingKeys.isEmpty()) { - throw new IllegalArgumentException( - format( - "Found [%s] remote clusters with credentials [%s]. Security [%s] must be enabled to connect to them. " - + "Please either enable security or remove these settings from the keystore.", - remoteClusterCredentialsSettingKeys.size(), - Strings.collectionToCommaDelimitedString(remoteClusterCredentialsSettingKeys), - XPackSettings.SECURITY_ENABLED.getKey() - ) - ); - } - } - private static void runStartupChecks(Settings settings) { validateRealmSettings(settings); if (XPackSettings.FIPS_MODE_ENABLED.get(settings)) { @@ -627,14 +619,6 @@ protected XPackLicenseState getLicenseState() { return XPackPlugin.getSharedLicenseState(); } - protected Client getClient() { - return client.get(); - } - - protected Realms getRealms() { - return realms.get(); - } - @Override public Collection createComponents(PluginServices services) { try { @@ -673,8 +657,6 @@ Collection createComponents( return Collections.singletonList(new SecurityUsageServices(null, null, null, null, null, null)); } - this.client.set(client); - // The settings in `environment` may have additional values over what was provided during construction // See Plugin#additionalSettings() this.settings = environment.settings(); @@ -1001,6 +983,8 @@ Collection createComponents( ipFilter.set(new IPFilter(settings, auditTrailService, clusterService.getClusterSettings(), getLicenseState())); components.add(ipFilter.get()); + final RemoteClusterCredentialsResolver remoteClusterCredentialsResolver = new RemoteClusterCredentialsResolver(settings); + DestructiveOperations destructiveOperations = new DestructiveOperations(settings, clusterService.getClusterSettings()); crossClusterAccessAuthcService.set(new CrossClusterAccessAuthenticationService(clusterService, apiKeyService, authcService.get())); components.add(crossClusterAccessAuthcService.get()); @@ -1014,6 +998,7 @@ Collection createComponents( securityContext.get(), destructiveOperations, crossClusterAccessAuthcService.get(), + remoteClusterCredentialsResolver, getLicenseState() ) ); @@ -1366,7 +1351,6 @@ public void onIndexModule(IndexModule module) { new ActionHandler<>(SetProfileEnabledAction.INSTANCE, TransportSetProfileEnabledAction.class), new ActionHandler<>(GetSecuritySettingsAction.INSTANCE, TransportGetSecuritySettingsAction.class), new ActionHandler<>(UpdateSecuritySettingsAction.INSTANCE, TransportUpdateSecuritySettingsAction.class), - new ActionHandler<>(ReloadRemoteClusterCredentialsAction.INSTANCE, TransportReloadRemoteClusterCredentialsAction.class), usageAction, infoAction ).filter(Objects::nonNull).toList(); @@ -1906,54 +1890,16 @@ public BiConsumer getJoinValidator() { @Override public void reload(Settings settings) throws Exception { if (enabled) { - final List reloadExceptions = new ArrayList<>(); - try { - reloadRemoteClusterCredentials(settings); - } catch (Exception ex) { - reloadExceptions.add(ex); - } - - try { - reloadSharedSecretsForJwtRealms(settings); - } catch (Exception ex) { - reloadExceptions.add(ex); - } - - if (false == reloadExceptions.isEmpty()) { - final var combinedException = new ElasticsearchException( - "secure settings reload failed for one or more security components" - ); - reloadExceptions.forEach(combinedException::addSuppressed); - throw combinedException; - } - } else { - ensureNoRemoteClusterCredentialsOnDisabledSecurity(settings); + realms.get().stream().filter(r -> JwtRealmSettings.TYPE.equals(r.realmRef().getType())).forEach(realm -> { + if (realm instanceof JwtRealm jwtRealm) { + jwtRealm.rotateClientSecret( + CLIENT_AUTHENTICATION_SHARED_SECRET.getConcreteSettingForNamespace(realm.realmRef().getName()).get(settings) + ); + } + }); } } - private void reloadSharedSecretsForJwtRealms(Settings settingsWithKeystore) { - getRealms().stream().filter(r -> JwtRealmSettings.TYPE.equals(r.realmRef().getType())).forEach(realm -> { - if (realm instanceof JwtRealm jwtRealm) { - jwtRealm.rotateClientSecret( - CLIENT_AUTHENTICATION_SHARED_SECRET.getConcreteSettingForNamespace(realm.realmRef().getName()).get(settingsWithKeystore) - ); - } - }); - } - - /** - * This method uses a transport action internally to access classes that are injectable but not part of the plugin contract. - * See {@link TransportReloadRemoteClusterCredentialsAction} for more context. - */ - private void reloadRemoteClusterCredentials(Settings settingsWithKeystore) { - // Accepting a blocking call here since the underlying action is local-only and only performs fast in-memory ops - // (extracts a subset of passed in `settingsWithKeystore` and stores them in a map) - getClient().execute( - ReloadRemoteClusterCredentialsAction.INSTANCE, - new ReloadRemoteClusterCredentialsAction.Request(settingsWithKeystore) - ).actionGet(); - } - static final class ValidateLicenseForFIPS implements BiConsumer { private final boolean inFipsMode; private final LicenseService licenseService; diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/settings/TransportReloadRemoteClusterCredentialsAction.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/settings/TransportReloadRemoteClusterCredentialsAction.java deleted file mode 100644 index de696a3e0353f..0000000000000 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/settings/TransportReloadRemoteClusterCredentialsAction.java +++ /dev/null @@ -1,54 +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.security.action.settings; - -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.ActionResponse; -import org.elasticsearch.action.support.ActionFilters; -import org.elasticsearch.action.support.TransportAction; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.tasks.Task; -import org.elasticsearch.transport.RemoteClusterService; -import org.elasticsearch.transport.TransportService; -import org.elasticsearch.xpack.core.security.action.settings.ReloadRemoteClusterCredentialsAction; -import org.elasticsearch.xpack.security.Security; - -/** - * This is a local-only action which updates remote cluster credentials for remote cluster connections, from keystore settings reloaded via - * a call to {@link org.elasticsearch.rest.action.admin.cluster.RestReloadSecureSettingsAction}. - * - * It's invoked as part of the {@link Security#reload(Settings)} call. - * - * This action is largely an implementation detail to work around the fact that Security is a plugin without direct access to many core - * classes, including the {@link RemoteClusterService} which is required for credentials update. A transport action gives us access to - * the {@link RemoteClusterService} which is injectable but not part of the plugin contract. - */ -public class TransportReloadRemoteClusterCredentialsAction extends TransportAction< - ReloadRemoteClusterCredentialsAction.Request, - ActionResponse.Empty> { - - private final RemoteClusterService remoteClusterService; - - @Inject - public TransportReloadRemoteClusterCredentialsAction(TransportService transportService, ActionFilters actionFilters) { - super(ReloadRemoteClusterCredentialsAction.NAME, actionFilters, transportService.getTaskManager()); - this.remoteClusterService = transportService.getRemoteClusterService(); - } - - @Override - protected void doExecute( - Task task, - ReloadRemoteClusterCredentialsAction.Request request, - ActionListener listener - ) { - // We avoid stashing and marking context as system to keep the action as minimal as possible (i.e., avoid copying context) - remoteClusterService.updateRemoteClusterCredentials(request.getSettings()); - listener.onResponse(ActionResponse.Empty.INSTANCE); - } -} diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/RemoteClusterCredentialsResolver.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/RemoteClusterCredentialsResolver.java new file mode 100644 index 0000000000000..93735a700bf92 --- /dev/null +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/RemoteClusterCredentialsResolver.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.security.transport; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.settings.SecureString; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.xpack.security.authc.ApiKeyService; + +import java.util.Map; +import java.util.Optional; + +import static org.elasticsearch.transport.RemoteClusterService.REMOTE_CLUSTER_CREDENTIALS; + +public class RemoteClusterCredentialsResolver { + + private static final Logger logger = LogManager.getLogger(RemoteClusterCredentialsResolver.class); + + private final Map clusterCredentials; + + public RemoteClusterCredentialsResolver(final Settings settings) { + this.clusterCredentials = REMOTE_CLUSTER_CREDENTIALS.getAsMap(settings); + logger.debug( + "Read cluster credentials for remote clusters [{}]", + Strings.collectionToCommaDelimitedString(clusterCredentials.keySet()) + ); + } + + public Optional resolve(final String clusterAlias) { + final SecureString apiKey = clusterCredentials.get(clusterAlias); + if (apiKey == null) { + return Optional.empty(); + } else { + return Optional.of(new RemoteClusterCredentials(clusterAlias, ApiKeyService.withApiKeyPrefix(apiKey.toString()))); + } + } + + record RemoteClusterCredentials(String clusterAlias, String credentials) { + @Override + public String toString() { + return "RemoteClusterCredentials{clusterAlias='" + clusterAlias + "', credentials='::es_redacted::'}"; + } + } +} diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportInterceptor.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportInterceptor.java index 162cabf5297ce..53dd31fe46793 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportInterceptor.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportInterceptor.java @@ -12,7 +12,6 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.admin.cluster.state.ClusterStateAction; import org.elasticsearch.action.support.DestructiveOperations; -import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.ssl.SslConfiguration; import org.elasticsearch.common.util.Maps; @@ -25,7 +24,6 @@ import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.RemoteConnectionManager; -import org.elasticsearch.transport.RemoteConnectionManager.RemoteClusterAliasWithCredentials; import org.elasticsearch.transport.SendRequestTransportException; import org.elasticsearch.transport.Transport; import org.elasticsearch.transport.TransportChannel; @@ -48,7 +46,6 @@ import org.elasticsearch.xpack.core.ssl.SSLService; import org.elasticsearch.xpack.security.Security; import org.elasticsearch.xpack.security.audit.AuditUtil; -import org.elasticsearch.xpack.security.authc.ApiKeyService; import org.elasticsearch.xpack.security.authc.AuthenticationService; import org.elasticsearch.xpack.security.authc.CrossClusterAccessAuthenticationService; import org.elasticsearch.xpack.security.authc.CrossClusterAccessHeaders; @@ -66,6 +63,7 @@ import static org.elasticsearch.transport.RemoteClusterPortSettings.REMOTE_CLUSTER_PROFILE; import static org.elasticsearch.transport.RemoteClusterPortSettings.REMOTE_CLUSTER_SERVER_ENABLED; import static org.elasticsearch.transport.RemoteClusterPortSettings.TRANSPORT_VERSION_ADVANCED_REMOTE_CLUSTER_SECURITY; +import static org.elasticsearch.xpack.security.transport.RemoteClusterCredentialsResolver.RemoteClusterCredentials; public class SecurityServerTransportInterceptor implements TransportInterceptor { @@ -87,7 +85,8 @@ public class SecurityServerTransportInterceptor implements TransportInterceptor private final Settings settings; private final SecurityContext securityContext; private final CrossClusterAccessAuthenticationService crossClusterAccessAuthcService; - private final Function> remoteClusterCredentialsResolver; + private final RemoteClusterCredentialsResolver remoteClusterCredentialsResolver; + private final Function> remoteClusterAliasResolver; private final XPackLicenseState licenseState; public SecurityServerTransportInterceptor( @@ -99,6 +98,7 @@ public SecurityServerTransportInterceptor( SecurityContext securityContext, DestructiveOperations destructiveOperations, CrossClusterAccessAuthenticationService crossClusterAccessAuthcService, + RemoteClusterCredentialsResolver remoteClusterCredentialsResolver, XPackLicenseState licenseState ) { this( @@ -110,8 +110,9 @@ public SecurityServerTransportInterceptor( securityContext, destructiveOperations, crossClusterAccessAuthcService, + remoteClusterCredentialsResolver, licenseState, - RemoteConnectionManager::resolveRemoteClusterAliasWithCredentials + RemoteConnectionManager::resolveRemoteClusterAlias ); } @@ -124,9 +125,10 @@ public SecurityServerTransportInterceptor( SecurityContext securityContext, DestructiveOperations destructiveOperations, CrossClusterAccessAuthenticationService crossClusterAccessAuthcService, + RemoteClusterCredentialsResolver remoteClusterCredentialsResolver, XPackLicenseState licenseState, // Inject for simplified testing - Function> remoteClusterCredentialsResolver + Function> remoteClusterAliasResolver ) { this.settings = settings; this.threadPool = threadPool; @@ -137,6 +139,7 @@ public SecurityServerTransportInterceptor( this.crossClusterAccessAuthcService = crossClusterAccessAuthcService; this.licenseState = licenseState; this.remoteClusterCredentialsResolver = remoteClusterCredentialsResolver; + this.remoteClusterAliasResolver = remoteClusterAliasResolver; this.profileFilters = initializeProfileFilters(destructiveOperations); } @@ -156,8 +159,7 @@ public void sendRequest( TransportResponseHandler handler ) { assertNoCrossClusterAccessHeadersInContext(); - final Optional remoteClusterAlias = remoteClusterCredentialsResolver.apply(connection) - .map(RemoteClusterAliasWithCredentials::clusterAlias); + final Optional remoteClusterAlias = remoteClusterAliasResolver.apply(connection); if (PreAuthorizationUtils.shouldRemoveParentAuthorizationFromThreadContext(remoteClusterAlias, action, securityContext)) { securityContext.executeAfterRemovingParentAuthorization(original -> { sendRequestInner( @@ -276,23 +278,22 @@ public void sendRequest( * Returns cluster credentials if the connection is remote, and cluster credentials are set up for the target cluster. */ private Optional getRemoteClusterCredentials(Transport.Connection connection) { - final Optional remoteClusterAliasWithCredentials = remoteClusterCredentialsResolver - .apply(connection); - if (remoteClusterAliasWithCredentials.isEmpty()) { + final Optional optionalRemoteClusterAlias = remoteClusterAliasResolver.apply(connection); + if (optionalRemoteClusterAlias.isEmpty()) { logger.trace("Connection is not remote"); return Optional.empty(); } - final String remoteClusterAlias = remoteClusterAliasWithCredentials.get().clusterAlias(); - final SecureString remoteClusterCredentials = remoteClusterAliasWithCredentials.get().credentials(); - if (remoteClusterCredentials == null) { + final String remoteClusterAlias = optionalRemoteClusterAlias.get(); + final Optional remoteClusterCredentials = remoteClusterCredentialsResolver.resolve( + remoteClusterAlias + ); + if (remoteClusterCredentials.isEmpty()) { logger.trace("No cluster credentials are configured for remote cluster [{}]", remoteClusterAlias); return Optional.empty(); } - return Optional.of( - new RemoteClusterCredentials(remoteClusterAlias, ApiKeyService.withApiKeyPrefix(remoteClusterCredentials.toString())) - ); + return remoteClusterCredentials; } private void sendWithCrossClusterAccessHeaders( @@ -441,7 +442,7 @@ private void sendWithUser( throw new IllegalStateException("there should always be a user when sending a message for action [" + action + "]"); } - assert securityContext.getParentAuthorization() == null || remoteClusterCredentialsResolver.apply(connection).isEmpty() + assert securityContext.getParentAuthorization() == null || remoteClusterAliasResolver.apply(connection).isPresent() == false : "parent authorization header should not be set for remote cluster requests"; try { @@ -662,12 +663,4 @@ public void onFailure(Exception e) { } } } - - record RemoteClusterCredentials(String clusterAlias, String credentials) { - - @Override - public String toString() { - return "RemoteClusterCredentials{clusterAlias='" + clusterAlias + "', credentials='::es_redacted::'}"; - } - } } diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/LocalStateSecurity.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/LocalStateSecurity.java index a2aa04e0f56c3..d44e7c27d760e 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/LocalStateSecurity.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/LocalStateSecurity.java @@ -16,7 +16,6 @@ import org.elasticsearch.license.LicenseService; import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.plugins.ReloadablePlugin; import org.elasticsearch.protocol.xpack.XPackInfoRequest; import org.elasticsearch.protocol.xpack.XPackInfoResponse; import org.elasticsearch.protocol.xpack.XPackUsageRequest; @@ -37,7 +36,7 @@ import java.util.Collections; import java.util.List; -public class LocalStateSecurity extends LocalStateCompositeXPackPlugin implements ReloadablePlugin { +public class LocalStateSecurity extends LocalStateCompositeXPackPlugin { public static class SecurityTransportXPackUsageAction extends TransportXPackUsageAction { @Inject @@ -131,15 +130,4 @@ protected Class> public List plugins() { return plugins; } - - @Override - public void reload(Settings settings) throws Exception { - plugins.stream().filter(p -> p instanceof ReloadablePlugin).forEach(p -> { - try { - ((ReloadablePlugin) p).reload(settings); - } catch (Exception e) { - throw new RuntimeException(e); - } - }); - } } diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java index 75e134691225d..6773da137ac96 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java @@ -9,13 +9,10 @@ import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.Version; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionModule; -import org.elasticsearch.action.ActionResponse; -import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterState; @@ -75,7 +72,6 @@ import org.elasticsearch.xpack.core.security.SecurityContext; import org.elasticsearch.xpack.core.security.SecurityExtension; import org.elasticsearch.xpack.core.security.SecurityField; -import org.elasticsearch.xpack.core.security.action.settings.ReloadRemoteClusterCredentialsAction; import org.elasticsearch.xpack.core.security.authc.Authentication; import org.elasticsearch.xpack.core.security.authc.AuthenticationTestHelper; import org.elasticsearch.xpack.core.security.authc.Realm; @@ -120,7 +116,6 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; -import java.util.stream.Stream; import static java.util.Collections.emptyMap; import static org.elasticsearch.xpack.core.security.authc.RealmSettings.getFullSettingKey; @@ -138,9 +133,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class SecurityTests extends ESTestCase { @@ -884,23 +877,6 @@ public void testSecurityMustBeEnableToConnectRemoteClusterWithCredentials() { + "Please either enable security or remove these settings from the keystore." ) ); - - // Security off, remote cluster with credentials on reload call - final MockSecureSettings secureSettings5 = new MockSecureSettings(); - secureSettings5.setString("cluster.remote.my1.credentials", randomAlphaOfLength(20)); - secureSettings5.setString("cluster.remote.my2.credentials", randomAlphaOfLength(20)); - final Settings.Builder builder5 = Settings.builder().setSecureSettings(secureSettings5); - // Use builder with security disabled to construct valid Security instance - final var security = new Security(builder2.build()); - final IllegalArgumentException e5 = expectThrows(IllegalArgumentException.class, () -> security.reload(builder5.build())); - assertThat( - e5.getMessage(), - containsString( - "Found [2] remote clusters with credentials [cluster.remote.my1.credentials,cluster.remote.my2.credentials]. " - + "Security [xpack.security.enabled] must be enabled to connect to them. " - + "Please either enable security or remove these settings from the keystore." - ) - ); } public void testLoadExtensions() throws Exception { @@ -929,84 +905,6 @@ public List loadExtensions(Class extensionPointType) { assertThat(registry, instanceOf(DummyOperatorOnlyRegistry.class)); } - public void testReload() throws Exception { - final Settings settings = Settings.builder().put("xpack.security.enabled", true).put("path.home", createTempDir()).build(); - - final PlainActionFuture value = new PlainActionFuture<>(); - value.onResponse(ActionResponse.Empty.INSTANCE); - final Client mockedClient = mock(Client.class); - - final Realms mockedRealms = mock(Realms.class); - when(mockedRealms.stream()).thenReturn(Stream.of()); - when(mockedClient.execute(eq(ReloadRemoteClusterCredentialsAction.INSTANCE), any())).thenReturn(value); - security = new Security(settings, Collections.emptyList()) { - @Override - protected Client getClient() { - return mockedClient; - } - - @Override - protected Realms getRealms() { - return mockedRealms; - } - }; - - final Settings inputSettings = Settings.EMPTY; - security.reload(inputSettings); - - verify(mockedClient).execute(eq(ReloadRemoteClusterCredentialsAction.INSTANCE), any()); - verify(mockedRealms).stream(); - } - - public void testReloadWithFailures() { - final Settings settings = Settings.builder().put("xpack.security.enabled", true).put("path.home", createTempDir()).build(); - - final boolean failRemoteClusterCredentialsReload = randomBoolean(); - final PlainActionFuture value = new PlainActionFuture<>(); - if (failRemoteClusterCredentialsReload) { - value.onFailure(new RuntimeException("failed remote cluster credentials reload")); - } else { - value.onResponse(ActionResponse.Empty.INSTANCE); - } - final Client mockedClient = mock(Client.class); - when(mockedClient.execute(eq(ReloadRemoteClusterCredentialsAction.INSTANCE), any())).thenReturn(value); - - final Realms mockedRealms = mock(Realms.class); - final boolean failRealmsReload = (false == failRemoteClusterCredentialsReload) || randomBoolean(); - if (failRealmsReload) { - when(mockedRealms.stream()).thenThrow(new RuntimeException("failed jwt realms reload")); - } else { - when(mockedRealms.stream()).thenReturn(Stream.of()); - } - security = new Security(settings, Collections.emptyList()) { - @Override - protected Client getClient() { - return mockedClient; - } - - @Override - protected Realms getRealms() { - return mockedRealms; - } - }; - - final Settings inputSettings = Settings.EMPTY; - final var exception = expectThrows(ElasticsearchException.class, () -> security.reload(inputSettings)); - - assertThat(exception.getMessage(), containsString("secure settings reload failed for one or more security component")); - if (failRemoteClusterCredentialsReload) { - assertThat(exception.getSuppressed()[0].getMessage(), containsString("failed remote cluster credentials reload")); - if (failRealmsReload) { - assertThat(exception.getSuppressed()[1].getMessage(), containsString("failed jwt realms reload")); - } - } else { - assertThat(exception.getSuppressed()[0].getMessage(), containsString("failed jwt realms reload")); - } - // Verify both called despite failure - verify(mockedClient).execute(eq(ReloadRemoteClusterCredentialsAction.INSTANCE), any()); - verify(mockedRealms).stream(); - } - public void testLoadNoExtensions() throws Exception { Settings settings = Settings.builder() .put("xpack.security.enabled", true) diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/RemoteClusterCredentialsResolverTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/RemoteClusterCredentialsResolverTests.java new file mode 100644 index 0000000000000..debb50384e217 --- /dev/null +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/RemoteClusterCredentialsResolverTests.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.security.transport; + +import org.elasticsearch.common.settings.MockSecureSettings; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.security.authc.ApiKeyService; + +import java.util.Optional; + +import static org.elasticsearch.xpack.security.transport.RemoteClusterCredentialsResolver.RemoteClusterCredentials; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; + +public class RemoteClusterCredentialsResolverTests extends ESTestCase { + + public void testResolveRemoteClusterCredentials() { + final String clusterNameA = "clusterA"; + final String clusterDoesNotExist = randomAlphaOfLength(10); + final Settings.Builder builder = Settings.builder(); + + final String secret = randomAlphaOfLength(20); + final MockSecureSettings secureSettings = new MockSecureSettings(); + secureSettings.setString("cluster.remote." + clusterNameA + ".credentials", secret); + final Settings settings = builder.setSecureSettings(secureSettings).build(); + RemoteClusterCredentialsResolver remoteClusterAuthorizationResolver = new RemoteClusterCredentialsResolver(settings); + final Optional remoteClusterCredentials = remoteClusterAuthorizationResolver.resolve(clusterNameA); + assertThat(remoteClusterCredentials.isPresent(), is(true)); + assertThat(remoteClusterCredentials.get().clusterAlias(), equalTo(clusterNameA)); + assertThat(remoteClusterCredentials.get().credentials(), equalTo(ApiKeyService.withApiKeyPrefix(secret))); + assertThat(remoteClusterAuthorizationResolver.resolve(clusterDoesNotExist), is(Optional.empty())); + } +} 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 822c04be4363f..9bd5d416940d3 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 @@ -18,7 +18,6 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.settings.ClusterSettings; -import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.ssl.SslClientAuthenticationMode; import org.elasticsearch.common.ssl.SslConfiguration; @@ -34,7 +33,6 @@ import org.elasticsearch.threadpool.TestThreadPool; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.RemoteClusterPortSettings; -import org.elasticsearch.transport.RemoteConnectionManager.RemoteClusterAliasWithCredentials; import org.elasticsearch.transport.SendRequestTransportException; import org.elasticsearch.transport.Transport; import org.elasticsearch.transport.Transport.Connection; @@ -79,7 +77,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; -import java.util.function.Function; import static org.elasticsearch.cluster.metadata.DataStreamLifecycle.DATA_STREAM_LIFECYCLE_ORIGIN; import static org.elasticsearch.test.ActionListenerUtils.anyActionListener; @@ -90,6 +87,7 @@ import static org.elasticsearch.xpack.core.security.authc.CrossClusterAccessSubjectInfo.CROSS_CLUSTER_ACCESS_SUBJECT_INFO_HEADER_KEY; import static org.elasticsearch.xpack.core.security.authz.RoleDescriptorTests.randomUniquelyNamedRoleDescriptors; import static org.elasticsearch.xpack.security.authc.CrossClusterAccessHeaders.CROSS_CLUSTER_ACCESS_CREDENTIALS_HEADER_KEY; +import static org.elasticsearch.xpack.security.transport.RemoteClusterCredentialsResolver.RemoteClusterCredentials; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.equalTo; @@ -155,6 +153,7 @@ public void testSendAsync() throws Exception { new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), + new RemoteClusterCredentialsResolver(settings), mockLicenseState ); ClusterServiceUtils.setState(clusterService, clusterService.state()); // force state update to trigger listener @@ -206,6 +205,7 @@ public void testSendAsyncSwitchToSystem() throws Exception { new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), + new RemoteClusterCredentialsResolver(settings), mockLicenseState ); ClusterServiceUtils.setState(clusterService, clusterService.state()); // force state update to trigger listener @@ -250,6 +250,7 @@ public void testSendWithoutUser() throws Exception { new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), + new RemoteClusterCredentialsResolver(settings), mockLicenseState ) { @Override @@ -312,6 +313,7 @@ public void testSendToNewerVersionSetsCorrectVersion() throws Exception { new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), + new RemoteClusterCredentialsResolver(settings), mockLicenseState ); ClusterServiceUtils.setState(clusterService, clusterService.state()); // force state update to trigger listener @@ -380,6 +382,7 @@ public void testSendToOlderVersionSetsCorrectVersion() throws Exception { new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), + new RemoteClusterCredentialsResolver(settings), mockLicenseState ); ClusterServiceUtils.setState(clusterService, clusterService.state()); // force state update to trigger listener @@ -446,6 +449,7 @@ public void testSetUserBasedOnActionOrigin() { new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), + new RemoteClusterCredentialsResolver(settings), mockLicenseState ); @@ -600,6 +604,7 @@ public void testSendWithCrossClusterAccessHeadersWithUnsupportedLicense() throws AuthenticationTestHelper.builder().build().writeToContext(threadContext); final String remoteClusterAlias = randomAlphaOfLengthBetween(5, 10); + final RemoteClusterCredentialsResolver remoteClusterCredentialsResolver = mockRemoteClusterCredentialsResolver(remoteClusterAlias); final SecurityServerTransportInterceptor interceptor = new SecurityServerTransportInterceptor( settings, @@ -613,8 +618,9 @@ public void testSendWithCrossClusterAccessHeadersWithUnsupportedLicense() throws new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), + remoteClusterCredentialsResolver, unsupportedLicenseState, - mockRemoteClusterCredentialsResolver(remoteClusterAlias) + ignored -> Optional.of(remoteClusterAlias) ); final AsyncSender sender = interceptor.interceptSender(mock(AsyncSender.class, ignored -> { @@ -655,16 +661,18 @@ public TransportResponse read(StreamInput in) { actualException.get().getCause().getMessage(), equalTo("current license is non-compliant for [" + Security.ADVANCED_REMOTE_CLUSTER_SECURITY_FEATURE.getName() + "]") ); + verify(remoteClusterCredentialsResolver, times(1)).resolve(eq(remoteClusterAlias)); assertThat(securityContext.getThreadContext().getHeader(CROSS_CLUSTER_ACCESS_SUBJECT_INFO_HEADER_KEY), nullValue()); assertThat(securityContext.getThreadContext().getHeader(CROSS_CLUSTER_ACCESS_CREDENTIALS_HEADER_KEY), nullValue()); } - private Function> mockRemoteClusterCredentialsResolver( - String remoteClusterAlias - ) { - return connection -> Optional.of( - new RemoteClusterAliasWithCredentials(remoteClusterAlias, new SecureString(randomAlphaOfLengthBetween(10, 42).toCharArray())) + private RemoteClusterCredentialsResolver mockRemoteClusterCredentialsResolver(String remoteClusterAlias) { + final RemoteClusterCredentialsResolver remoteClusterCredentialsResolver = mock(RemoteClusterCredentialsResolver.class); + final String remoteClusterCredential = ApiKeyService.withApiKeyPrefix(randomAlphaOfLengthBetween(10, 42)); + when(remoteClusterCredentialsResolver.resolve(any())).thenReturn( + Optional.of(new RemoteClusterCredentials(remoteClusterAlias, remoteClusterCredential)) ); + return remoteClusterCredentialsResolver; } public void testSendWithCrossClusterAccessHeadersForSystemUserRegularAction() throws Exception { @@ -728,9 +736,12 @@ private void doTestSendWithCrossClusterAccessHeaders( ) throws IOException { authentication.writeToContext(threadContext); final String expectedRequestId = AuditUtil.getOrGenerateRequestId(threadContext); + final RemoteClusterCredentialsResolver remoteClusterCredentialsResolver = mock(RemoteClusterCredentialsResolver.class); final String remoteClusterAlias = randomAlphaOfLengthBetween(5, 10); - final String encodedApiKey = randomAlphaOfLengthBetween(10, 42); - final String remoteClusterCredential = ApiKeyService.withApiKeyPrefix(encodedApiKey); + final String remoteClusterCredential = ApiKeyService.withApiKeyPrefix(randomAlphaOfLengthBetween(10, 42)); + when(remoteClusterCredentialsResolver.resolve(any())).thenReturn( + Optional.of(new RemoteClusterCredentials(remoteClusterAlias, remoteClusterCredential)) + ); final AuthorizationService authzService = mock(AuthorizationService.class); // We capture the listener so that we can complete the full flow, by calling onResponse further down @SuppressWarnings("unchecked") @@ -749,8 +760,9 @@ private void doTestSendWithCrossClusterAccessHeaders( new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), + remoteClusterCredentialsResolver, mockLicenseState, - ignored -> Optional.of(new RemoteClusterAliasWithCredentials(remoteClusterAlias, new SecureString(encodedApiKey.toCharArray()))) + ignored -> Optional.of(remoteClusterAlias) ); final AtomicBoolean calledWrappedSender = new AtomicBoolean(false); @@ -849,6 +861,7 @@ public TransportResponse read(StreamInput in) { } assertThat(sentCredential.get(), equalTo(remoteClusterCredential)); verify(securityContext, never()).executeAsInternalUser(any(), any(), anyConsumer()); + verify(remoteClusterCredentialsResolver, times(1)).resolve(eq(remoteClusterAlias)); assertThat(securityContext.getThreadContext().getHeader(CROSS_CLUSTER_ACCESS_SUBJECT_INFO_HEADER_KEY), nullValue()); assertThat(securityContext.getThreadContext().getHeader(CROSS_CLUSTER_ACCESS_CREDENTIALS_HEADER_KEY), nullValue()); assertThat(AuditUtil.extractRequestId(securityContext.getThreadContext()), equalTo(expectedRequestId)); @@ -861,9 +874,15 @@ public void testSendWithUserIfCrossClusterAccessHeadersConditionNotMet() throws if (false == (notRemoteConnection || noCredential)) { noCredential = true; } - final boolean finalNoCredential = noCredential; final String remoteClusterAlias = randomAlphaOfLengthBetween(5, 10); - final String encodedApiKey = randomAlphaOfLengthBetween(10, 42); + final RemoteClusterCredentialsResolver remoteClusterCredentialsResolver = mock(RemoteClusterCredentialsResolver.class); + when(remoteClusterCredentialsResolver.resolve(any())).thenReturn( + noCredential + ? Optional.empty() + : Optional.of( + new RemoteClusterCredentials(remoteClusterAlias, ApiKeyService.withApiKeyPrefix(randomAlphaOfLengthBetween(10, 42))) + ) + ); final AuthenticationTestHelper.AuthenticationTestBuilder builder = AuthenticationTestHelper.builder(); final Authentication authentication = randomFrom( builder.apiKey().build(), @@ -885,12 +904,9 @@ public void testSendWithUserIfCrossClusterAccessHeadersConditionNotMet() throws new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), + remoteClusterCredentialsResolver, mockLicenseState, - ignored -> notRemoteConnection - ? Optional.empty() - : (finalNoCredential - ? Optional.of(new RemoteClusterAliasWithCredentials(remoteClusterAlias, null)) - : Optional.of(new RemoteClusterAliasWithCredentials(remoteClusterAlias, new SecureString(encodedApiKey.toCharArray())))) + ignored -> notRemoteConnection ? Optional.empty() : Optional.of(remoteClusterAlias) ); final AtomicBoolean calledWrappedSender = new AtomicBoolean(false); @@ -928,9 +944,12 @@ public void testSendWithCrossClusterAccessHeadersThrowsOnOldConnection() throws .realm() .build(); authentication.writeToContext(threadContext); + final RemoteClusterCredentialsResolver remoteClusterCredentialsResolver = mock(RemoteClusterCredentialsResolver.class); final String remoteClusterAlias = randomAlphaOfLengthBetween(5, 10); - final String encodedApiKey = randomAlphaOfLengthBetween(10, 42); - final String remoteClusterCredential = ApiKeyService.withApiKeyPrefix(encodedApiKey); + final String remoteClusterCredential = ApiKeyService.withApiKeyPrefix(randomAlphaOfLengthBetween(10, 42)); + when(remoteClusterCredentialsResolver.resolve(any())).thenReturn( + Optional.of(new RemoteClusterCredentials(remoteClusterAlias, remoteClusterCredential)) + ); final SecurityServerTransportInterceptor interceptor = new SecurityServerTransportInterceptor( settings, @@ -944,8 +963,9 @@ public void testSendWithCrossClusterAccessHeadersThrowsOnOldConnection() throws new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), + remoteClusterCredentialsResolver, mockLicenseState, - ignored -> Optional.of(new RemoteClusterAliasWithCredentials(remoteClusterAlias, new SecureString(encodedApiKey.toCharArray()))) + ignored -> Optional.of(remoteClusterAlias) ); final AsyncSender sender = interceptor.interceptSender(new AsyncSender() { @@ -1009,6 +1029,7 @@ public TransportResponse read(StreamInput in) { + "] does not support receiving them" ) ); + verify(remoteClusterCredentialsResolver, times(1)).resolve(eq(remoteClusterAlias)); assertThat(securityContext.getThreadContext().getHeader(CROSS_CLUSTER_ACCESS_SUBJECT_INFO_HEADER_KEY), nullValue()); assertThat(securityContext.getThreadContext().getHeader(CROSS_CLUSTER_ACCESS_CREDENTIALS_HEADER_KEY), nullValue()); } @@ -1019,9 +1040,12 @@ public void testSendRemoteRequestFailsIfUserHasNoRemoteIndicesPrivileges() throw .realm() .build(); authentication.writeToContext(threadContext); + final RemoteClusterCredentialsResolver remoteClusterCredentialsResolver = mock(RemoteClusterCredentialsResolver.class); final String remoteClusterAlias = randomAlphaOfLengthBetween(5, 10); - final String encodedApiKey = randomAlphaOfLengthBetween(10, 42); - final String remoteClusterCredential = ApiKeyService.withApiKeyPrefix(encodedApiKey); + final String remoteClusterCredential = ApiKeyService.withApiKeyPrefix(randomAlphaOfLengthBetween(10, 42)); + when(remoteClusterCredentialsResolver.resolve(any())).thenReturn( + Optional.of(new RemoteClusterCredentials(remoteClusterAlias, remoteClusterCredential)) + ); final AuthorizationService authzService = mock(AuthorizationService.class); doAnswer(invocation -> { @@ -1043,8 +1067,9 @@ public void testSendRemoteRequestFailsIfUserHasNoRemoteIndicesPrivileges() throw new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), + remoteClusterCredentialsResolver, mockLicenseState, - ignored -> Optional.of(new RemoteClusterAliasWithCredentials(remoteClusterAlias, new SecureString(encodedApiKey.toCharArray()))) + ignored -> Optional.of(remoteClusterAlias) ); final AsyncSender sender = interceptor.interceptSender(new AsyncSender() { @@ -1146,6 +1171,7 @@ public void testProfileFiltersCreatedDifferentlyForDifferentTransportAndRemoteCl new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), + new RemoteClusterCredentialsResolver(settings), mockLicenseState ); @@ -1199,6 +1225,7 @@ public void testNoProfileFilterForRemoteClusterWhenTheFeatureIsDisabled() { new ClusterSettings(Settings.EMPTY, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)) ), mock(CrossClusterAccessAuthenticationService.class), + new RemoteClusterCredentialsResolver(settings), mockLicenseState ); From cf7941f23bcb367ff9676953fce4d7209ed3dc38 Mon Sep 17 00:00:00 2001 From: Mark Tozzi Date: Fri, 8 Dec 2023 13:24:57 -0500 Subject: [PATCH 20/22] [ES|QL] tests auto decode unsigned longs (#103164) This extracts the type handling sugar around unsigned longs I added in #102830. Turns out, fixing that was a little bigger than intended, and I wanted to break it out into a distinct PR. The strategy here is to let the framework convert from the encoded unsigned long into a normal BigInteger, so test case writers can just phrase their expected values as normal BigIntegers rather than having to think about the encoding. Feedback welcome, happy to discuss if folks don't think this is a good direction for the tests. Co-authored-by: Bogdan Pintea --- .../function/AbstractFunctionTestCase.java | 25 ++++++++++++++++--- .../expression/function/TestCaseSupplier.java | 9 +++++++ .../scalar/convert/ToUnsignedLongTests.java | 20 ++++++--------- .../function/scalar/math/AbsTests.java | 19 +++++++------- .../function/scalar/math/CeilTests.java | 24 +++++++++++------- .../function/scalar/math/FloorTests.java | 3 +-- .../scalar/multivalue/MvMaxTests.java | 8 +----- .../scalar/multivalue/MvMedianTests.java | 5 ++-- .../scalar/multivalue/MvMinTests.java | 8 +----- .../xpack/ql/util/NumericUtilsTests.java | 6 +++++ 10 files changed, 74 insertions(+), 53 deletions(-) diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractFunctionTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractFunctionTestCase.java index 8b4a126d8a0c7..d6f3b61cb19dd 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractFunctionTestCase.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractFunctionTestCase.java @@ -49,6 +49,7 @@ import org.elasticsearch.xpack.ql.type.DataType; import org.elasticsearch.xpack.ql.type.DataTypes; import org.elasticsearch.xpack.ql.type.EsField; +import org.elasticsearch.xpack.ql.util.NumericUtils; import org.elasticsearch.xpack.ql.util.StringUtils; import org.elasticsearch.xpack.versionfield.Version; import org.hamcrest.Matcher; @@ -92,6 +93,7 @@ import static org.elasticsearch.xpack.ql.util.SpatialCoordinateTypes.GEO; import static org.hamcrest.Matchers.either; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.sameInstance; @@ -241,7 +243,7 @@ private void testEvaluate(boolean readFloating) { Object result; try (ExpressionEvaluator evaluator = evaluator(expression).get(driverContext())) { try (Block block = evaluator.eval(row(testCase.getDataValues()))) { - result = toJavaObject(block, 0); + result = toJavaObjectUnsignedLongAware(block, 0); } } assertThat(result, not(equalTo(Double.NaN))); @@ -255,6 +257,16 @@ private void testEvaluate(boolean readFloating) { } } + private Object toJavaObjectUnsignedLongAware(Block block, int position) { + Object result; + result = toJavaObject(block, position); + if (result != null && testCase.expectedType == DataTypes.UNSIGNED_LONG) { + assertThat(result, instanceOf(Long.class)); + result = NumericUtils.unsignedLongAsBigInteger((Long) result); + } + return result; + } + /** * Evaluates a {@link Block} of values, all copied from the input pattern, read directly from the page. *

@@ -398,7 +410,7 @@ private void testEvaluateBlock(BlockFactory inputBlockFactory, DriverContext con assertThat(toJavaObject(block, p), allNullsMatcher()); continue; } - assertThat(toJavaObject(block, p), testCase.getMatcher()); + assertThat(toJavaObjectUnsignedLongAware(block, p), testCase.getMatcher()); } assertThat( "evaluates to tracked block", @@ -472,7 +484,7 @@ public final void testEvaluateInManyThreads() throws ExecutionException, Interru try (EvalOperator.ExpressionEvaluator eval = evalSupplier.get(driverContext())) { for (int c = 0; c < count; c++) { try (Block block = eval.eval(page)) { - assertThat(toJavaObject(block, 0), testCase.getMatcher()); + assertThat(toJavaObjectUnsignedLongAware(block, 0), testCase.getMatcher()); } } } @@ -513,7 +525,12 @@ public final void testFold() { expression = new FoldNull().rule(expression); assertThat(expression.dataType(), equalTo(testCase.expectedType)); assertTrue(expression.foldable()); - assertThat(expression.fold(), testCase.getMatcher()); + Object result = expression.fold(); + // Decode unsigned longs into BigIntegers + if (testCase.expectedType == DataTypes.UNSIGNED_LONG && result != null) { + result = NumericUtils.unsignedLongAsBigInteger((Long) result); + } + assertThat(result, testCase.getMatcher()); if (testCase.getExpectedWarnings() != null) { assertWarnings(testCase.getExpectedWarnings()); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java index faf10d499127a..9eab8cbef5fed 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java @@ -10,6 +10,8 @@ import org.apache.lucene.document.InetAddressPoint; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.network.InetAddresses; +import org.elasticsearch.logging.LogManager; +import org.elasticsearch.logging.Logger; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction; import org.elasticsearch.xpack.esql.type.EsqlDataTypes; @@ -48,6 +50,8 @@ public record TestCaseSupplier(String name, List types, Supplier supplier) implements Supplier { + + private static Logger logger = LogManager.getLogger(TestCaseSupplier.class); /** * Build a test case without types. * @@ -530,6 +534,8 @@ public static void unary( supplier.type(), "value" ); + logger.info("Value is " + value + " of type " + value.getClass()); + logger.info("expectedValue is " + expectedValue.apply(value)); TestCase testCase = new TestCase( List.of(typed), expectedEvaluatorToString, @@ -949,6 +955,9 @@ public TypedData(Object data, String name) { @Override public String toString() { + if (type == DataTypes.UNSIGNED_LONG && data instanceof Long longData) { + return type.toString() + "(" + NumericUtils.unsignedLongAsBigInteger(longData).toString() + ")"; + } return type.toString() + "(" + (data == null ? "null" : data.toString()) + ")"; } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongTests.java index 080424602703d..8d5ee002a8f78 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongTests.java @@ -16,7 +16,6 @@ import org.elasticsearch.xpack.ql.expression.Expression; import org.elasticsearch.xpack.ql.tree.Source; import org.elasticsearch.xpack.ql.type.DataTypes; -import org.elasticsearch.xpack.ql.util.NumericUtils; import java.math.BigDecimal; import java.math.BigInteger; @@ -26,10 +25,7 @@ import java.util.function.Supplier; import static org.elasticsearch.xpack.ql.type.DataTypeConverter.safeToUnsignedLong; -import static org.elasticsearch.xpack.ql.util.NumericUtils.ONE_AS_UNSIGNED_LONG; import static org.elasticsearch.xpack.ql.util.NumericUtils.UNSIGNED_LONG_MAX_AS_DOUBLE; -import static org.elasticsearch.xpack.ql.util.NumericUtils.ZERO_AS_UNSIGNED_LONG; -import static org.elasticsearch.xpack.ql.util.NumericUtils.asLongUnsigned; public class ToUnsignedLongTests extends AbstractFunctionTestCase { public ToUnsignedLongTests(@Name("TestCase") Supplier testCaseSupplier) { @@ -47,7 +43,7 @@ public static Iterable parameters() { suppliers, read, DataTypes.UNSIGNED_LONG, - NumericUtils::asLongUnsigned, + n -> n, BigInteger.ZERO, UNSIGNED_LONG_MAX, List.of() @@ -57,7 +53,7 @@ public static Iterable parameters() { suppliers, evaluatorName.apply("Boolean"), DataTypes.UNSIGNED_LONG, - b -> b ? ONE_AS_UNSIGNED_LONG : ZERO_AS_UNSIGNED_LONG, + b -> b ? BigInteger.ONE : BigInteger.ZERO, List.of() ); @@ -66,7 +62,7 @@ public static Iterable parameters() { suppliers, evaluatorName.apply("Long"), DataTypes.UNSIGNED_LONG, - instant -> asLongUnsigned(instant.toEpochMilli()), + instant -> BigInteger.valueOf(instant.toEpochMilli()), List.of() ); // random strings that don't look like an unsigned_long @@ -85,7 +81,7 @@ public static Iterable parameters() { suppliers, evaluatorName.apply("Double"), DataTypes.UNSIGNED_LONG, - d -> asLongUnsigned(BigDecimal.valueOf(d).toBigInteger()), // note: not: new BigDecimal(d).toBigInteger + d -> BigDecimal.valueOf(d).toBigInteger(), // note: not: new BigDecimal(d).toBigInteger 0d, UNSIGNED_LONG_MAX_AS_DOUBLE, List.of() @@ -122,7 +118,7 @@ public static Iterable parameters() { suppliers, evaluatorName.apply("Long"), DataTypes.UNSIGNED_LONG, - NumericUtils::asLongUnsigned, + BigInteger::valueOf, 0L, Long.MAX_VALUE, List.of() @@ -146,7 +142,7 @@ public static Iterable parameters() { suppliers, evaluatorName.apply("Int"), DataTypes.UNSIGNED_LONG, - NumericUtils::asLongUnsigned, + BigInteger::valueOf, 0, Integer.MAX_VALUE, List.of() @@ -180,7 +176,7 @@ public static Iterable parameters() { ) .toList(), DataTypes.UNSIGNED_LONG, - bytesRef -> asLongUnsigned(safeToUnsignedLong(((BytesRef) bytesRef).utf8ToString())), + bytesRef -> safeToUnsignedLong(((BytesRef) bytesRef).utf8ToString()), List.of() ); // strings of random doubles within unsigned_long's range @@ -198,7 +194,7 @@ public static Iterable parameters() { ) .toList(), DataTypes.UNSIGNED_LONG, - bytesRef -> asLongUnsigned(safeToUnsignedLong(((BytesRef) bytesRef).utf8ToString())), + bytesRef -> safeToUnsignedLong(((BytesRef) bytesRef).utf8ToString()), List.of() ); // strings of random doubles outside unsigned_long's range, negative diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AbsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AbsTests.java index e6621fdf78408..491680d537f37 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AbsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AbsTests.java @@ -17,6 +17,7 @@ import org.elasticsearch.xpack.ql.type.DataType; import org.elasticsearch.xpack.ql.type.DataTypes; +import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; @@ -36,15 +37,15 @@ public static Iterable parameters() { equalTo(Math.abs(arg)) ); })); - suppliers.add(new TestCaseSupplier(List.of(DataTypes.UNSIGNED_LONG), () -> { - long arg = randomLong(); - return new TestCaseSupplier.TestCase( - List.of(new TestCaseSupplier.TypedData(arg, DataTypes.UNSIGNED_LONG, "arg")), - "Attribute[channel=0]", - DataTypes.UNSIGNED_LONG, - equalTo(arg) - ); - })); + TestCaseSupplier.forUnaryUnsignedLong( + suppliers, + "Attribute[channel=0]", + DataTypes.UNSIGNED_LONG, + (n) -> n, + BigInteger.ZERO, + UNSIGNED_LONG_MAX, + List.of() + ); suppliers.add(new TestCaseSupplier(List.of(DataTypes.LONG), () -> { long arg = randomLong(); return new TestCaseSupplier.TestCase( diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CeilTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CeilTests.java index f4e03de146c54..cbc7e99bf6c09 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CeilTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CeilTests.java @@ -17,6 +17,8 @@ import org.elasticsearch.xpack.ql.type.DataType; import org.elasticsearch.xpack.ql.type.DataTypes; +import java.math.BigInteger; +import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; @@ -29,7 +31,8 @@ public CeilTests(@Name("TestCase") Supplier testCaseS @ParametersFactory public static Iterable parameters() { - return parameterSuppliersFromTypedData(List.of(new TestCaseSupplier("large double value", () -> { + List suppliers = new ArrayList<>(); + suppliers.addAll(List.of(new TestCaseSupplier("large double value", () -> { double arg = 1 / randomDouble(); return new TestCaseSupplier.TestCase( List.of(new TestCaseSupplier.TypedData(arg, DataTypes.DOUBLE, "arg")), @@ -53,15 +56,18 @@ public static Iterable parameters() { DataTypes.LONG, equalTo(arg) ); - }), new TestCaseSupplier("unsigned long value", () -> { - long arg = randomLong(); - return new TestCaseSupplier.TestCase( - List.of(new TestCaseSupplier.TypedData(arg, DataTypes.UNSIGNED_LONG, "arg")), - "Attribute[channel=0]", - DataTypes.UNSIGNED_LONG, - equalTo(arg) - ); }))); + + TestCaseSupplier.forUnaryUnsignedLong( + suppliers, + "Attribute[channel=0]", + DataTypes.UNSIGNED_LONG, + (n) -> n, + BigInteger.ZERO, + UNSIGNED_LONG_MAX, + List.of() + ); + return parameterSuppliersFromTypedData(suppliers); } @Override diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/FloorTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/FloorTests.java index f41b7c5de38ad..9a185172c9972 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/FloorTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/FloorTests.java @@ -15,7 +15,6 @@ import org.elasticsearch.xpack.ql.expression.Expression; import org.elasticsearch.xpack.ql.tree.Source; import org.elasticsearch.xpack.ql.type.DataTypes; -import org.elasticsearch.xpack.ql.util.NumericUtils; import java.math.BigInteger; import java.util.ArrayList; @@ -37,7 +36,7 @@ public static Iterable parameters() { suppliers, read, DataTypes.UNSIGNED_LONG, - ul -> NumericUtils.asLongUnsigned(ul), + ul -> ul, BigInteger.ZERO, UNSIGNED_LONG_MAX, List.of() diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMaxTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMaxTests.java index 25764a9029bfd..c477cad17904d 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMaxTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMaxTests.java @@ -14,7 +14,6 @@ import org.elasticsearch.xpack.ql.expression.Expression; import org.elasticsearch.xpack.ql.tree.Source; import org.elasticsearch.xpack.ql.type.DataType; -import org.elasticsearch.xpack.ql.util.NumericUtils; import java.math.BigInteger; import java.util.ArrayList; @@ -37,12 +36,7 @@ public static Iterable parameters() { doubles(cases, "mv_max", "MvMax", (size, values) -> equalTo(values.max().getAsDouble())); ints(cases, "mv_max", "MvMax", (size, values) -> equalTo(values.max().getAsInt())); longs(cases, "mv_max", "MvMax", (size, values) -> equalTo(values.max().getAsLong())); - unsignedLongs( - cases, - "mv_max", - "MvMax", - (size, values) -> equalTo(NumericUtils.asLongUnsigned(values.reduce(BigInteger::max).get())) - ); + unsignedLongs(cases, "mv_max", "MvMax", (size, values) -> equalTo(values.reduce(BigInteger::max).get())); dateTimes(cases, "mv_max", "MvMax", (size, values) -> equalTo(values.max().getAsLong())); return parameterSuppliersFromTypedData(errorsForCasesWithoutExamples(anyNullIsNull(false, cases))); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMedianTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMedianTests.java index ce83c4bb8f786..43e8467147279 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMedianTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMedianTests.java @@ -15,7 +15,6 @@ import org.elasticsearch.xpack.ql.tree.Source; import org.elasticsearch.xpack.ql.type.DataType; import org.elasticsearch.xpack.ql.type.DataTypes; -import org.elasticsearch.xpack.ql.util.NumericUtils; import java.math.BigInteger; import java.util.ArrayList; @@ -62,12 +61,12 @@ public static Iterable parameters() { unsignedLongs(cases, "mv_median", "MvMedian", (size, values) -> { int middle = size / 2; if (size % 2 == 1) { - return equalTo(NumericUtils.asLongUnsigned(values.sorted().skip(middle).findFirst().get())); + return equalTo(values.sorted().skip(middle).findFirst().get()); } var s = values.sorted().skip(middle - 1).limit(2).iterator(); BigInteger a = s.next(); BigInteger b = s.next(); - return equalTo(NumericUtils.asLongUnsigned(a.add(b.subtract(a).divide(BigInteger.valueOf(2))))); + return equalTo(a.add(b.subtract(a).divide(BigInteger.valueOf(2)))); }); cases.add( diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMinTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMinTests.java index 5556755cfe125..2e47f7c24bb54 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMinTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMinTests.java @@ -14,7 +14,6 @@ import org.elasticsearch.xpack.ql.expression.Expression; import org.elasticsearch.xpack.ql.tree.Source; import org.elasticsearch.xpack.ql.type.DataType; -import org.elasticsearch.xpack.ql.util.NumericUtils; import java.math.BigInteger; import java.util.ArrayList; @@ -37,12 +36,7 @@ public static Iterable parameters() { doubles(cases, "mv_min", "MvMin", (size, values) -> equalTo(values.min().getAsDouble())); ints(cases, "mv_min", "MvMin", (size, values) -> equalTo(values.min().getAsInt())); longs(cases, "mv_min", "MvMin", (size, values) -> equalTo(values.min().getAsLong())); - unsignedLongs( - cases, - "mv_min", - "MvMin", - (size, values) -> equalTo(NumericUtils.asLongUnsigned(values.reduce(BigInteger::min).get())) - ); + unsignedLongs(cases, "mv_min", "MvMin", (size, values) -> equalTo(values.reduce(BigInteger::min).get())); dateTimes(cases, "mv_min", "MvMin", (size, values) -> equalTo(values.min().getAsLong())); return parameterSuppliersFromTypedData(errorsForCasesWithoutExamples(anyNullIsNull(false, cases))); } diff --git a/x-pack/plugin/ql/src/test/java/org/elasticsearch/xpack/ql/util/NumericUtilsTests.java b/x-pack/plugin/ql/src/test/java/org/elasticsearch/xpack/ql/util/NumericUtilsTests.java index 45ab0e732305c..80be578ed2647 100644 --- a/x-pack/plugin/ql/src/test/java/org/elasticsearch/xpack/ql/util/NumericUtilsTests.java +++ b/x-pack/plugin/ql/src/test/java/org/elasticsearch/xpack/ql/util/NumericUtilsTests.java @@ -13,6 +13,7 @@ import java.util.function.BiFunction; import static org.elasticsearch.xpack.ql.util.NumericUtils.asLongUnsigned; +import static org.elasticsearch.xpack.ql.util.NumericUtils.unsignedLongAsBigInteger; import static org.elasticsearch.xpack.ql.util.NumericUtils.unsignedLongAsNumber; import static org.elasticsearch.xpack.ql.util.StringUtils.parseIntegral; import static org.hamcrest.Matchers.equalTo; @@ -115,6 +116,11 @@ public void testUnsignedLongMultiplyExact() { assertThat(mulExact("0", "0"), equalTo("0")); } + public void testRoundTripConversion() { + BigInteger b = randomUnsignedLongBetween(BigInteger.ZERO, UNSIGNED_LONG_MAX); + assertThat(b, equalTo(unsignedLongAsBigInteger(asLongUnsigned(b)))); + } + private static String addExact(String x, String y) { return exactOperation(x, y, NumericUtils::unsignedLongAddExact); } From 690a8a2ef8f0b686c75f0e9094b814fc5ecd3051 Mon Sep 17 00:00:00 2001 From: Mark Tozzi Date: Fri, 8 Dec 2023 14:27:22 -0500 Subject: [PATCH 21/22] [ES|QL] Trig & hyperbolic function finishing pass (#103205) Relates to #100558 These functions were mostly done already. I added descriptions and argument descriptions for most of them, otherwise not much work. --- docs/reference/esql/functions/cos.asciidoc | 2 +- docs/reference/esql/functions/sin.asciidoc | 2 +- docs/reference/esql/functions/tan.asciidoc | 2 +- .../qa/testFixtures/src/main/resources/show.csv-spec | 12 ++++++------ .../esql/expression/function/scalar/math/Cos.java | 7 +++++-- .../esql/expression/function/scalar/math/Cosh.java | 11 +++++++++-- .../esql/expression/function/scalar/math/Sinh.java | 11 +++++++++-- .../esql/expression/function/scalar/math/Tan.java | 7 +++++-- .../esql/expression/function/scalar/math/Tanh.java | 11 +++++++++-- .../expression/function/scalar/math/CoshTests.java | 3 +-- .../expression/function/scalar/math/SinhTests.java | 3 +-- 11 files changed, 48 insertions(+), 23 deletions(-) diff --git a/docs/reference/esql/functions/cos.asciidoc b/docs/reference/esql/functions/cos.asciidoc index 5dcbb7bea37f4..7227f57e28120 100644 --- a/docs/reference/esql/functions/cos.asciidoc +++ b/docs/reference/esql/functions/cos.asciidoc @@ -4,7 +4,7 @@ [.text-center] image::esql/functions/signature/cos.svg[Embedded,opts=inline] -https://en.wikipedia.org/wiki/Sine_and_cosine[Cosine] trigonometric function. +https://en.wikipedia.org/wiki/Sine_and_cosine[Cosine] trigonometric function. Input expected in radians. [source.merge.styled,esql] ---- diff --git a/docs/reference/esql/functions/sin.asciidoc b/docs/reference/esql/functions/sin.asciidoc index 5fa33a315392d..d948bf2ec39a3 100644 --- a/docs/reference/esql/functions/sin.asciidoc +++ b/docs/reference/esql/functions/sin.asciidoc @@ -4,7 +4,7 @@ [.text-center] image::esql/functions/signature/sin.svg[Embedded,opts=inline] -https://en.wikipedia.org/wiki/Sine_and_cosine[Sine] trigonometric function. +https://en.wikipedia.org/wiki/Sine_and_cosine[Sine] trigonometric function. Input expected in radians. [source.merge.styled,esql] ---- diff --git a/docs/reference/esql/functions/tan.asciidoc b/docs/reference/esql/functions/tan.asciidoc index 1c66562eada7a..03e450ff23b0e 100644 --- a/docs/reference/esql/functions/tan.asciidoc +++ b/docs/reference/esql/functions/tan.asciidoc @@ -4,7 +4,7 @@ [.text-center] image::esql/functions/signature/tan.svg[Embedded,opts=inline] -https://en.wikipedia.org/wiki/Sine_and_cosine[Tangent] trigonometric function. +https://en.wikipedia.org/wiki/Sine_and_cosine[Tangent] trigonometric function. Input expected in radians. [source.merge.styled,esql] ---- 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 ffad468790998..083bd1eaf8417 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 @@ -6,7 +6,7 @@ v:long ; # TODO: switch this test to ``&format=csv&delimiter=|` output -showFunctions#[skip:-8.11.99] +showFunctions#[skip:-8.12.99] show functions; name:keyword | synopsis:keyword | argNames:keyword | argTypes:keyword | argDescriptions:keyword |returnType:keyword | description:keyword | optionalArgs:boolean | variadic:boolean @@ -22,8 +22,8 @@ ceil |"? ceil(n:integer|long|double|unsigned_long)" |n cidr_match |? cidr_match(arg1:?, arg2...:?) |[arg1, arg2] |[?, ?] |["", ""] |? | "" | [false, false] | true coalesce |? coalesce(arg1:?, arg2...:?) |[arg1, arg2] |[?, ?] |["", ""] |? | "" | [false, false] | true concat |? concat(arg1:?, arg2...:?) |[arg1, arg2] |[?, ?] |["", ""] |? | "" | [false, false] | true -cos |"double cos(n:integer|long|double|unsigned_long)" |n |"integer|long|double|unsigned_long" | "" |double | "" | false | false -cosh |"double cosh(n:integer|long|double|unsigned_long)" |n |"integer|long|double|unsigned_long" | "" |double | "" | false | false +cos |"double cos(n:integer|long|double|unsigned_long)" |n |"integer|long|double|unsigned_long" | "An angle, in radians" |double | "Returns the trigonometric cosine of an angle" | false | false +cosh |"double cosh(n:integer|long|double|unsigned_long)" |n |"integer|long|double|unsigned_long" | "The number who's hyperbolic cosine is to be returned" |double | "Returns the hyperbolic cosine of a number" | false | false count |? count(arg1:?) |arg1 |? | "" |? | "" | false | false count_distinct |? count_distinct(arg1:?, arg2:?) |[arg1, arg2] |[?, ?] |["", ""] |? | "" | [false, false] | false date_extract |? date_extract(arg1:?, arg2:?) |[arg1, arg2] |[?, ?] |["", ""] |? | "" | [false, false] | false @@ -63,14 +63,14 @@ right |"? right(string:keyword, length:integer)" |[string round |? round(arg1:?, arg2:?) |[arg1, arg2] |[?, ?] |["", ""] |? | "" | [false, false] | false rtrim |"keyword|text rtrim(str:keyword|text)" |str |"keyword|text" | "" |"keyword|text" |Removes trailing whitespaces from a string.| false | false sin |"double sin(n:integer|long|double|unsigned_long)" |n |"integer|long|double|unsigned_long" |An angle, in radians |double |Returns the trigonometric sine of an angle | false | false -sinh |"double sinh(n:integer|long|double|unsigned_long)"|n |"integer|long|double|unsigned_long" | "" |double | "" | false | false +sinh |"double sinh(n:integer|long|double|unsigned_long)"|n |"integer|long|double|unsigned_long" | "The number to return the hyperbolic sine of" |double | "Returns the hyperbolic sine of a number" | false | false split |? split(arg1:?, arg2:?) |[arg1, arg2] |[?, ?] |["", ""] |? | "" | [false, false] | false sqrt |"? sqrt(n:integer|long|double|unsigned_long)" |n |"integer|long|double|unsigned_long" | "" |? | "" | false | false starts_with |? starts_with(arg1:?, arg2:?) |[arg1, arg2] |[?, ?] |["", ""] |? | "" | [false, false] | false substring |? substring(arg1:?, arg2:?, arg3:?) |[arg1, arg2, arg3] |[?, ?, ?] |["", "", ""] |? | "" | [false, false, false]| false sum |? sum(arg1:?) |arg1 |? | "" |? | "" | false | false -tan |"double tan(n:integer|long|double|unsigned_long)" |n |"integer|long|double|unsigned_long" | "" |double | "" | false | false -tanh |"double tanh(n:integer|long|double|unsigned_long)" |n |"integer|long|double|unsigned_long" | "" |double | "" | false | false +tan |"double tan(n:integer|long|double|unsigned_long)" |n |"integer|long|double|unsigned_long" | "An angle, in radians" |double | "Returns the trigonometric tangent of an angle" | false | false +tanh |"double tanh(n:integer|long|double|unsigned_long)" |n |"integer|long|double|unsigned_long" | "The number to return the hyperbolic tangent of" |double | "Returns the hyperbolic tangent of a number" | false | false tau |? tau() | null | null | null |? | "" | null | false to_bool |"boolean to_bool(v:boolean|keyword|text|double|long|unsigned_long|integer)" |v |"boolean|keyword|text|double|long|unsigned_long|integer" | |boolean | |false |false to_boolean |"boolean to_boolean(v:boolean|keyword|text|double|long|unsigned_long|integer)" |v |"boolean|keyword|text|double|long|unsigned_long|integer" | |boolean | |false |false diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cos.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cos.java index c5edc0e0fd6c7..5f8661bb0ae7d 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cos.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cos.java @@ -21,8 +21,11 @@ * Cosine trigonometric function. */ public class Cos extends AbstractTrigonometricFunction { - @FunctionInfo(returnType = "double") - public Cos(Source source, @Param(name = "n", type = { "integer", "long", "double", "unsigned_long" }) Expression n) { + @FunctionInfo(returnType = "double", description = "Returns the trigonometric cosine of an angle") + public Cos( + Source source, + @Param(name = "n", type = { "integer", "long", "double", "unsigned_long" }, description = "An angle, in radians") Expression n + ) { super(source, n); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cosh.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cosh.java index cc315c3e9569c..6cc49cec0c32d 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cosh.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cosh.java @@ -21,8 +21,15 @@ * Cosine hyperbolic function. */ public class Cosh extends AbstractTrigonometricFunction { - @FunctionInfo(returnType = "double") - public Cosh(Source source, @Param(name = "n", type = { "integer", "long", "double", "unsigned_long" }) Expression n) { + @FunctionInfo(returnType = "double", description = "Returns the hyperbolic cosine of a number") + public Cosh( + Source source, + @Param( + name = "n", + type = { "integer", "long", "double", "unsigned_long" }, + description = "The number who's hyperbolic cosine is to be returned" + ) Expression n + ) { super(source, n); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Sinh.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Sinh.java index 07228dd1743dd..4b2adef5a2d6f 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Sinh.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Sinh.java @@ -21,8 +21,15 @@ * Sine hyperbolic function. */ public class Sinh extends AbstractTrigonometricFunction { - @FunctionInfo(returnType = "double") - public Sinh(Source source, @Param(name = "n", type = { "integer", "long", "double", "unsigned_long" }) Expression n) { + @FunctionInfo(returnType = "double", description = "Returns the hyperbolic sine of a number") + public Sinh( + Source source, + @Param( + name = "n", + type = { "integer", "long", "double", "unsigned_long" }, + description = "The number to return the hyperbolic sine of" + ) Expression n + ) { super(source, n); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Tan.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Tan.java index e6c7bd8c6e530..5596c9098c034 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Tan.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Tan.java @@ -21,8 +21,11 @@ * Tangent trigonometric function. */ public class Tan extends AbstractTrigonometricFunction { - @FunctionInfo(returnType = "double") - public Tan(Source source, @Param(name = "n", type = { "integer", "long", "double", "unsigned_long" }) Expression n) { + @FunctionInfo(returnType = "double", description = "Returns the trigonometric tangent of an angle") + public Tan( + Source source, + @Param(name = "n", type = { "integer", "long", "double", "unsigned_long" }, description = "An angle, in radians") Expression n + ) { super(source, n); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Tanh.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Tanh.java index a9720d6d65c11..ce59cec50bcca 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Tanh.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Tanh.java @@ -21,8 +21,15 @@ * Tangent hyperbolic function. */ public class Tanh extends AbstractTrigonometricFunction { - @FunctionInfo(returnType = "double") - public Tanh(Source source, @Param(name = "n", type = { "integer", "long", "double", "unsigned_long" }) Expression n) { + @FunctionInfo(returnType = "double", description = "Returns the hyperbolic tangent of a number") + public Tanh( + Source source, + @Param( + name = "n", + type = { "integer", "long", "double", "unsigned_long" }, + description = "The number to return the hyperbolic tangent of" + ) Expression n + ) { super(source, n); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CoshTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CoshTests.java index fe9578aea6480..be7e8e47a0754 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CoshTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CoshTests.java @@ -33,7 +33,6 @@ public static Iterable parameters() { 710d, // Hyperbolic Cosine grows extremely fast. Values outside this range return Double.POSITIVE_INFINITY List.of() ); - suppliers = anyNullIsNull(true, suppliers); // Out of range cases suppliers.addAll( @@ -62,7 +61,7 @@ public static Iterable parameters() { ) ) ); - return parameterSuppliersFromTypedData(errorsForCasesWithoutExamples(suppliers)); + return parameterSuppliersFromTypedData(errorsForCasesWithoutExamples(anyNullIsNull(true, suppliers))); } @Override diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/SinhTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/SinhTests.java index ede33838903de..465879b071542 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/SinhTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/SinhTests.java @@ -33,7 +33,6 @@ public static Iterable parameters() { 710d, // Hyperbolic sine grows extremely fast. Values outside this range return Double.POSITIVE_INFINITY List.of() ); - suppliers = anyNullIsNull(true, suppliers); // Out of range cases suppliers.addAll( @@ -62,7 +61,7 @@ public static Iterable parameters() { ) ) ); - return parameterSuppliersFromTypedData(errorsForCasesWithoutExamples(suppliers)); + return parameterSuppliersFromTypedData(errorsForCasesWithoutExamples(anyNullIsNull(true, suppliers))); } @Override From 47b57537aec5d49a829e84bf11b310f0f31310be Mon Sep 17 00:00:00 2001 From: Benjamin Trent Date: Fri, 8 Dec 2023 14:39:18 -0500 Subject: [PATCH 22/22] Add docs for the include_named_queries_score param (#103155) The only docs for this _search param were mentioned in the bool query docs. While it makes contextual sense to have it there, we should also add it as a _search parameter in the search API docs. It was introduced in 8.8. --- docs/reference/search/search.asciidoc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/reference/search/search.asciidoc b/docs/reference/search/search.asciidoc index 68d286b3f267b..96e3ae43f98dc 100644 --- a/docs/reference/search/search.asciidoc +++ b/docs/reference/search/search.asciidoc @@ -111,6 +111,13 @@ By default, you cannot page through more than 10,000 hits using the `from` and include::{es-repo-dir}/rest-api/common-parms.asciidoc[tag=ignore_throttled] +`include_named_queries_score`:: +(Optional, Boolean) If `true`, includes the score contribution from any named queries. +This functionality reruns each named query on every hit in a search +response. Typically, this adds a small overhead to a request. However, using +computationally expensive named queries on a large number of hits may add +significant overhead. Defaults to `false`. + include::{es-repo-dir}/rest-api/common-parms.asciidoc[tag=index-ignore-unavailable] include::{es-repo-dir}/rest-api/common-parms.asciidoc[tag=lenient]