From fdffdd12250b15e0e01f77c6807dcc7764d4eea1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lorenzo=20Dematt=C3=A9?= Date: Fri, 17 Jan 2025 13:58:25 +0100 Subject: [PATCH 1/3] [8.x] [Entitlements] Network access checks for miscellanea (#120262) (#120353) * [Entitlements] Network access checks for miscellanea (#120262) * Move checks that use version-specific API --- .../server/cli/SystemJvmOptions.java | 4 +- .../bridge/src/main/java/module-info.java | 2 + .../bridge/EntitlementChecker.java | 37 ++++++++++ .../qa/common/src/main/java/module-info.java | 1 + .../qa/common/NetworkAccessCheckActions.java | 23 ++++++ .../common/RestEntitlementsCheckAction.java | 8 ++- .../common/VersionSpecificNetworkChecks.java | 24 +++++++ .../common/VersionSpecificNetworkChecks.java | 23 ++++++ .../common/VersionSpecificNetworkChecks.java | 70 +++++++++++++++++++ .../src/main/java/module-info.java | 1 + .../api/ElasticsearchEntitlementChecker.java | 57 +++++++++++++++ 11 files changed, 247 insertions(+), 3 deletions(-) create mode 100644 libs/entitlement/qa/common/src/main21/java/org/elasticsearch/entitlement/qa/common/VersionSpecificNetworkChecks.java diff --git a/distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/SystemJvmOptions.java b/distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/SystemJvmOptions.java index b5fff5e25eab2..bbff084dddb84 100644 --- a/distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/SystemJvmOptions.java +++ b/distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/SystemJvmOptions.java @@ -180,8 +180,8 @@ private static Stream maybeAttachEntitlementAgent(boolean useEntitlement throw new IllegalStateException("Failed to list entitlement jars in: " + dir, e); } // We instrument classes in these modules to call the bridge. Because the bridge gets patched - // into java.base, we must export the bridge from java.base to these modules. - String modulesContainingEntitlementInstrumentation = "java.logging"; + // into java.base, we must export the bridge from java.base to these modules, as a comma-separated list + String modulesContainingEntitlementInstrumentation = "java.logging,java.net.http,java.naming"; return Stream.of( "-Des.entitlements.enabled=true", "-XX:+EnableDynamicAgentLoading", diff --git a/libs/entitlement/bridge/src/main/java/module-info.java b/libs/entitlement/bridge/src/main/java/module-info.java index 93292109a726e..b9055ec5fbf67 100644 --- a/libs/entitlement/bridge/src/main/java/module-info.java +++ b/libs/entitlement/bridge/src/main/java/module-info.java @@ -10,5 +10,7 @@ // This module-info is used just to satisfy your IDE. // At build and run time, the bridge is patched into the java.base module. module org.elasticsearch.entitlement.bridge { + requires java.net.http; + exports org.elasticsearch.entitlement.bridge; } diff --git a/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java b/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java index 1e03c61df98e4..d6a8a01a7ab3f 100644 --- a/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java +++ b/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java @@ -30,6 +30,10 @@ import java.net.URL; import java.net.URLStreamHandler; import java.net.URLStreamHandlerFactory; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.security.cert.CertStoreParameters; import java.util.List; import javax.net.ssl.HostnameVerifier; @@ -254,4 +258,37 @@ public interface EntitlementChecker { void check$java_net_Socket$connect(Class callerClass, Socket that, SocketAddress endpoint); void check$java_net_Socket$connect(Class callerClass, Socket that, SocketAddress endpoint, int backlog); + + // Network miscellanea + void check$java_net_URL$openConnection(Class callerClass, java.net.URL that, Proxy proxy); + + // HttpClient.Builder is an interface, so we instrument its only (internal) implementation + void check$jdk_internal_net_http_HttpClientBuilderImpl$build(Class callerClass, HttpClient.Builder that); + + // HttpClient#send and sendAsync are abstract, so we instrument their internal implementation + void check$jdk_internal_net_http_HttpClientImpl$send( + Class callerClass, + HttpClient that, + HttpRequest request, + HttpResponse.BodyHandler responseBodyHandler + ); + + void check$jdk_internal_net_http_HttpClientImpl$sendAsync( + Class callerClass, + HttpClient that, + HttpRequest userRequest, + HttpResponse.BodyHandler responseHandler + ); + + void check$jdk_internal_net_http_HttpClientImpl$sendAsync( + Class callerClass, + HttpClient that, + HttpRequest userRequest, + HttpResponse.BodyHandler responseHandler, + HttpResponse.PushPromiseHandler pushPromiseHandler + ); + + // We need to check the LDAPCertStore, as this will connect, but this is internal/created via SPI, + // so we instrument the general factory instead and then filter in the check method implementation + void check$java_security_cert_CertStore$$getInstance(Class callerClass, String type, CertStoreParameters params); } diff --git a/libs/entitlement/qa/common/src/main/java/module-info.java b/libs/entitlement/qa/common/src/main/java/module-info.java index 211b7041e97ea..c40240f3dc1d5 100644 --- a/libs/entitlement/qa/common/src/main/java/module-info.java +++ b/libs/entitlement/qa/common/src/main/java/module-info.java @@ -14,6 +14,7 @@ // Modules we'll attempt to use in order to exercise entitlements requires java.logging; + requires java.net.http; exports org.elasticsearch.entitlement.qa.common; } diff --git a/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/NetworkAccessCheckActions.java b/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/NetworkAccessCheckActions.java index c88d4ce2b11a9..b92fb0b93a014 100644 --- a/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/NetworkAccessCheckActions.java +++ b/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/NetworkAccessCheckActions.java @@ -17,6 +17,12 @@ import java.net.Proxy; import java.net.ServerSocket; import java.net.Socket; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertStore; +import java.util.Arrays; class NetworkAccessCheckActions { @@ -59,4 +65,21 @@ static void socketConnect() throws IOException { socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); } } + + @SuppressForbidden(reason = "Testing entitlement check on forbidden action") + static void urlOpenConnectionWithProxy() throws URISyntaxException, IOException { + var url = new URI("http://localhost").toURL(); + var urlConnection = url.openConnection(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(0))); + assert urlConnection != null; + } + + static void createLDAPCertStore() throws NoSuchAlgorithmException { + try { + // We pass down null params to provoke a InvalidAlgorithmParameterException + CertStore.getInstance("LDAP", null); + } catch (InvalidAlgorithmParameterException ex) { + // Assert we actually hit the class we care about, LDAPCertStore (or its impl) + assert Arrays.stream(ex.getStackTrace()).anyMatch(e -> e.getClassName().endsWith("LDAPCertStore")); + } + } } diff --git a/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/RestEntitlementsCheckAction.java b/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/RestEntitlementsCheckAction.java index 9e7e6e33f3eda..32ebbe1ef89b3 100644 --- a/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/RestEntitlementsCheckAction.java +++ b/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/RestEntitlementsCheckAction.java @@ -157,7 +157,13 @@ static CheckAction alwaysDenied(CheckedRunnable action) { entry("socket_bind", forPlugins(NetworkAccessCheckActions::socketBind)), entry("socket_connect", forPlugins(NetworkAccessCheckActions::socketConnect)), entry("server_socket_bind", forPlugins(NetworkAccessCheckActions::serverSocketBind)), - entry("server_socket_accept", forPlugins(NetworkAccessCheckActions::serverSocketAccept)) + entry("server_socket_accept", forPlugins(NetworkAccessCheckActions::serverSocketAccept)), + + entry("url_open_connection_proxy", forPlugins(NetworkAccessCheckActions::urlOpenConnectionWithProxy)), + entry("http_client_builder_build", forPlugins(VersionSpecificNetworkChecks::httpClientBuilderBuild)), + entry("http_client_send", forPlugins(VersionSpecificNetworkChecks::httpClientSend)), + entry("http_client_send_async", forPlugins(VersionSpecificNetworkChecks::httpClientSendAsync)), + entry("create_ldap_cert_store", forPlugins(NetworkAccessCheckActions::createLDAPCertStore)) ) .filter(entry -> entry.getValue().fromJavaVersion() == null || Runtime.version().feature() >= entry.getValue().fromJavaVersion()) .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue)); diff --git a/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/VersionSpecificNetworkChecks.java b/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/VersionSpecificNetworkChecks.java index e1e0b9e52f510..cc0f679c38a9a 100644 --- a/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/VersionSpecificNetworkChecks.java +++ b/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/VersionSpecificNetworkChecks.java @@ -9,6 +9,30 @@ package org.elasticsearch.entitlement.qa.common; +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + class VersionSpecificNetworkChecks { static void createInetAddressResolverProvider() {} + + static void httpClientBuilderBuild() { + HttpClient.newBuilder().build(); + } + + static void httpClientSend() throws InterruptedException { + HttpClient httpClient = HttpClient.newBuilder().build(); + try { + httpClient.send(HttpRequest.newBuilder(URI.create("http://localhost")).build(), HttpResponse.BodyHandlers.discarding()); + } catch (IOException e) { + // Expected, the send action may fail with these parameters (but after it run the entitlement check in the prologue) + } + } + + static void httpClientSendAsync() { + HttpClient httpClient = HttpClient.newBuilder().build(); + httpClient.sendAsync(HttpRequest.newBuilder(URI.create("http://localhost")).build(), HttpResponse.BodyHandlers.discarding()); + } } diff --git a/libs/entitlement/qa/common/src/main18/java/org/elasticsearch/entitlement/qa/common/VersionSpecificNetworkChecks.java b/libs/entitlement/qa/common/src/main18/java/org/elasticsearch/entitlement/qa/common/VersionSpecificNetworkChecks.java index 0ead32ec480ee..8d3db76b81c71 100644 --- a/libs/entitlement/qa/common/src/main18/java/org/elasticsearch/entitlement/qa/common/VersionSpecificNetworkChecks.java +++ b/libs/entitlement/qa/common/src/main18/java/org/elasticsearch/entitlement/qa/common/VersionSpecificNetworkChecks.java @@ -9,6 +9,11 @@ package org.elasticsearch.entitlement.qa.common; +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.net.spi.InetAddressResolver; import java.net.spi.InetAddressResolverProvider; @@ -26,4 +31,22 @@ public String name() { } }; } + + static void httpClientBuilderBuild() { + HttpClient.newBuilder().build(); + } + + static void httpClientSend() throws InterruptedException { + HttpClient httpClient = HttpClient.newBuilder().build(); + try { + httpClient.send(HttpRequest.newBuilder(URI.create("http://localhost")).build(), HttpResponse.BodyHandlers.discarding()); + } catch (IOException e) { + // Expected, the send action may fail with these parameters (but after it run the entitlement check in the prologue) + } + } + + static void httpClientSendAsync() { + HttpClient httpClient = HttpClient.newBuilder().build(); + httpClient.sendAsync(HttpRequest.newBuilder(URI.create("http://localhost")).build(), HttpResponse.BodyHandlers.discarding()); + } } diff --git a/libs/entitlement/qa/common/src/main21/java/org/elasticsearch/entitlement/qa/common/VersionSpecificNetworkChecks.java b/libs/entitlement/qa/common/src/main21/java/org/elasticsearch/entitlement/qa/common/VersionSpecificNetworkChecks.java new file mode 100644 index 0000000000000..49102968ac7fd --- /dev/null +++ b/libs/entitlement/qa/common/src/main21/java/org/elasticsearch/entitlement/qa/common/VersionSpecificNetworkChecks.java @@ -0,0 +1,70 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +package org.elasticsearch.entitlement.qa.common; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.spi.InetAddressResolver; +import java.net.spi.InetAddressResolverProvider; + +class VersionSpecificNetworkChecks { + static void createInetAddressResolverProvider() { + var x = new InetAddressResolverProvider() { + @Override + public InetAddressResolver get(Configuration configuration) { + return null; + } + + @Override + public String name() { + return "TEST"; + } + }; + } + + static void httpClientBuilderBuild() { + try (HttpClient httpClient = HttpClient.newBuilder().build()) { + assert httpClient != null; + } + } + + static void httpClientSend() throws InterruptedException { + try (HttpClient httpClient = HttpClient.newBuilder().build()) { + // Shutdown the client, so the send action will shortcut before actually executing any network operation + // (but after it run our check in the prologue) + httpClient.shutdown(); + try { + httpClient.send(HttpRequest.newBuilder(URI.create("http://localhost")).build(), HttpResponse.BodyHandlers.discarding()); + } catch (IOException e) { + // Expected, since we shut down the client + } + } + } + + static void httpClientSendAsync() { + try (HttpClient httpClient = HttpClient.newBuilder().build()) { + // Shutdown the client, so the send action will return before actually executing any network operation + // (but after it run our check in the prologue) + httpClient.shutdown(); + var future = httpClient.sendAsync( + HttpRequest.newBuilder(URI.create("http://localhost")).build(), + HttpResponse.BodyHandlers.discarding() + ); + assert future.isCompletedExceptionally(); + future.exceptionally(ex -> { + assert ex instanceof IOException; + return null; + }); + } + } +} diff --git a/libs/entitlement/src/main/java/module-info.java b/libs/entitlement/src/main/java/module-info.java index b8a125b98e641..c0959f212558a 100644 --- a/libs/entitlement/src/main/java/module-info.java +++ b/libs/entitlement/src/main/java/module-info.java @@ -13,6 +13,7 @@ requires java.instrument; requires org.elasticsearch.base; requires jdk.attach; + requires java.net.http; requires static org.elasticsearch.entitlement.bridge; // At runtime, this will be in java.base diff --git a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java index 695d1c574c7c3..779ea103231a2 100644 --- a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java +++ b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java @@ -34,6 +34,10 @@ import java.net.URL; import java.net.URLStreamHandler; import java.net.URLStreamHandlerFactory; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.security.cert.CertStoreParameters; import java.util.List; import javax.net.ssl.HostnameVerifier; @@ -504,4 +508,57 @@ public ElasticsearchEntitlementChecker(PolicyManager policyManager) { public void check$java_net_Socket$connect(Class callerClass, Socket that, SocketAddress endpoint, int backlog) { policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.CONNECT_ACTION); } + + @Override + public void check$java_net_URL$openConnection(Class callerClass, URL that, Proxy proxy) { + if (proxy.type() != Proxy.Type.DIRECT) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.CONNECT_ACTION); + } + } + + @Override + public void check$jdk_internal_net_http_HttpClientBuilderImpl$build(Class callerClass, HttpClient.Builder that) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION); + } + + @Override + public void check$jdk_internal_net_http_HttpClientImpl$send( + Class callerClass, + HttpClient that, + HttpRequest request, + HttpResponse.BodyHandler responseBodyHandler + ) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.CONNECT_ACTION); + } + + @Override + public void check$jdk_internal_net_http_HttpClientImpl$sendAsync( + Class callerClass, + HttpClient that, + HttpRequest userRequest, + HttpResponse.BodyHandler responseHandler + ) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.CONNECT_ACTION); + } + + @Override + public void check$jdk_internal_net_http_HttpClientImpl$sendAsync( + Class callerClass, + HttpClient that, + HttpRequest userRequest, + HttpResponse.BodyHandler responseHandler, + HttpResponse.PushPromiseHandler pushPromiseHandler + ) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.CONNECT_ACTION); + } + + @Override + public void check$java_security_cert_CertStore$$getInstance(Class callerClass, String type, CertStoreParameters params) { + // We need to check "just" the LDAPCertStore instantiation: this is the CertStore that will try to perform a network operation + // (connect to an LDAP server). But LDAPCertStore is internal (created via SPI), so we instrument the general factory instead and + // then do the check only for the path that leads to sensitive code (by looking at the `type` parameter). + if ("LDAP".equals(type)) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.CONNECT_ACTION); + } + } } From 8f663ef8887e6118b71c2501eb6f05d3630c3b7a Mon Sep 17 00:00:00 2001 From: Dimitris Rempapis Date: Fri, 17 Jan 2025 15:13:57 +0200 Subject: [PATCH 2/3] unmute RetrySearchIntegTests.testRetryPointInTime (#120364) unmute test --- muted-tests.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/muted-tests.yml b/muted-tests.yml index 6188d71c0666b..4fc6724d5ce62 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -379,9 +379,6 @@ tests: - class: org.elasticsearch.discovery.ec2.DiscoveryEc2AvailabilityZoneAttributeNoImdsIT method: testAvailabilityZoneAttribute issue: https://github.com/elastic/elasticsearch/issues/118564 -- class: org.elasticsearch.xpack.searchablesnapshots.RetrySearchIntegTests - method: testRetryPointInTime - issue: https://github.com/elastic/elasticsearch/issues/118514 - class: org.elasticsearch.xpack.apmdata.APMYamlTestSuiteIT method: test {yaml=/20_metrics_ingest/Test metrics-apm.app-* setting event.ingested via ingest pipeline} issue: https://github.com/elastic/elasticsearch/issues/118875 From fad1ea1df23c24f65bee8f4b7f3048923463a92b Mon Sep 17 00:00:00 2001 From: Keith Massey Date: Fri, 17 Jan 2025 08:03:35 -0600 Subject: [PATCH 3/3] Removing unused ReindexDataStreamAction.Response class (#120321) (#120331) --- .../ReindexDataStreamTransportActionIT.java | 11 ++-- .../action/ReindexDataStreamAction.java | 47 +---------------- .../ReindexDataStreamTransportAction.java | 8 +-- .../rest/RestMigrationReindexAction.java | 6 +-- .../ReindexDataStreamResponseTests.java | 50 ------------------- 5 files changed, 13 insertions(+), 109 deletions(-) delete mode 100644 x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamResponseTests.java diff --git a/x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamTransportActionIT.java b/x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamTransportActionIT.java index b32a6efb854d7..04caf3dbaa9d1 100644 --- a/x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamTransportActionIT.java +++ b/x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamTransportActionIT.java @@ -28,7 +28,6 @@ import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xpack.migrate.MigratePlugin; import org.elasticsearch.xpack.migrate.action.ReindexDataStreamAction.ReindexDataStreamRequest; -import org.elasticsearch.xpack.migrate.action.ReindexDataStreamAction.ReindexDataStreamResponse; import org.elasticsearch.xpack.migrate.task.ReindexDataStreamEnrichedStatus; import org.elasticsearch.xpack.migrate.task.ReindexDataStreamTask; @@ -61,8 +60,7 @@ public void testNonExistentDataStream() { ); assertThrows( ResourceNotFoundException.class, - () -> client().execute(new ActionType(ReindexDataStreamAction.NAME), reindexDataStreamRequest) - .actionGet() + () -> client().execute(new ActionType(ReindexDataStreamAction.NAME), reindexDataStreamRequest).actionGet() ); } @@ -74,12 +72,11 @@ public void testAlreadyUpToDateDataStream() throws Exception { dataStreamName ); final int backingIndexCount = createDataStream(dataStreamName); - ReindexDataStreamResponse response = client().execute( - new ActionType(ReindexDataStreamAction.NAME), + AcknowledgedResponse response = client().execute( + new ActionType(ReindexDataStreamAction.NAME), reindexDataStreamRequest ).actionGet(); - String persistentTaskId = response.getTaskId(); - assertThat(persistentTaskId, equalTo("reindex-data-stream-" + dataStreamName)); + String persistentTaskId = "reindex-data-stream-" + dataStreamName; AtomicReference runningTask = new AtomicReference<>(); for (TransportService transportService : internalCluster().getInstances(TransportService.class)) { TaskManager taskManager = transportService.getTaskManager(); diff --git a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamAction.java b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamAction.java index 9e4cbb1082215..17925eb04851b 100644 --- a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamAction.java +++ b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamAction.java @@ -9,10 +9,10 @@ import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.ActionRequestValidationException; -import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.ActionType; import org.elasticsearch.action.IndicesRequest; import org.elasticsearch.action.support.IndicesOptions; +import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.util.FeatureFlag; @@ -20,7 +20,6 @@ import org.elasticsearch.xcontent.ConstructingObjectParser; import org.elasticsearch.xcontent.ParseField; import org.elasticsearch.xcontent.ToXContent; -import org.elasticsearch.xcontent.ToXContentObject; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentParser; @@ -29,7 +28,7 @@ import java.util.Objects; import java.util.function.Predicate; -public class ReindexDataStreamAction extends ActionType { +public class ReindexDataStreamAction extends ActionType { public static final FeatureFlag REINDEX_DATA_STREAM_FEATURE_FLAG = new FeatureFlag("reindex_data_stream"); public static final String TASK_ID_PREFIX = "reindex-data-stream-"; @@ -47,48 +46,6 @@ public enum Mode { UPGRADE } - public static class ReindexDataStreamResponse extends ActionResponse implements ToXContentObject { - private final String taskId; - - public ReindexDataStreamResponse(String taskId) { - super(); - this.taskId = taskId; - } - - public ReindexDataStreamResponse(StreamInput in) throws IOException { - super(in); - this.taskId = in.readString(); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeString(taskId); - } - - @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject(); - builder.field("acknowledged", true); - builder.endObject(); - return builder; - } - - public String getTaskId() { - return taskId; - } - - @Override - public int hashCode() { - return Objects.hashCode(taskId); - } - - @Override - public boolean equals(Object other) { - return other instanceof ReindexDataStreamResponse && taskId.equals(((ReindexDataStreamResponse) other).taskId); - } - - } - public static class ReindexDataStreamRequest extends ActionRequest implements IndicesRequest, ToXContent { private final Mode mode; private final String sourceDataStream; diff --git a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamTransportAction.java b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamTransportAction.java index cc648c1984544..2d7c17db054a9 100644 --- a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamTransportAction.java +++ b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamTransportAction.java @@ -12,6 +12,7 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.HandledTransportAction; +import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.cluster.metadata.DataStream; import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.service.ClusterService; @@ -22,7 +23,6 @@ import org.elasticsearch.transport.TransportService; import org.elasticsearch.xpack.core.ClientHelper; import org.elasticsearch.xpack.migrate.action.ReindexDataStreamAction.ReindexDataStreamRequest; -import org.elasticsearch.xpack.migrate.action.ReindexDataStreamAction.ReindexDataStreamResponse; import org.elasticsearch.xpack.migrate.task.ReindexDataStreamTask; import org.elasticsearch.xpack.migrate.task.ReindexDataStreamTaskParams; @@ -33,7 +33,7 @@ * This transport action creates a new persistent task for reindexing the source data stream given in the request. On successful creation * of the persistent task, it responds with the persistent task id so that the user can monitor the persistent task. */ -public class ReindexDataStreamTransportAction extends HandledTransportAction { +public class ReindexDataStreamTransportAction extends HandledTransportAction { private final PersistentTasksService persistentTasksService; private final TransportService transportService; private final ClusterService clusterService; @@ -59,7 +59,7 @@ public ReindexDataStreamTransportAction( } @Override - protected void doExecute(Task task, ReindexDataStreamRequest request, ActionListener listener) { + protected void doExecute(Task task, ReindexDataStreamRequest request, ActionListener listener) { String sourceDataStreamName = request.getSourceDataStream(); Metadata metadata = clusterService.state().metadata(); DataStream dataStream = metadata.dataStreams().get(sourceDataStreamName); @@ -82,7 +82,7 @@ protected void doExecute(Task task, ReindexDataStreamRequest request, ActionList ReindexDataStreamTask.TASK_NAME, params, null, - ActionListener.wrap(startedTask -> listener.onResponse(new ReindexDataStreamResponse(persistentTaskId)), listener::onFailure) + ActionListener.wrap(startedTask -> listener.onResponse(AcknowledgedResponse.TRUE), listener::onFailure) ); } diff --git a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/rest/RestMigrationReindexAction.java b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/rest/RestMigrationReindexAction.java index 19cb439495e9a..a89f056477d2c 100644 --- a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/rest/RestMigrationReindexAction.java +++ b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/rest/RestMigrationReindexAction.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.migrate.rest; +import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.client.internal.node.NodeClient; import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestChannel; @@ -17,7 +18,6 @@ import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentParser; import org.elasticsearch.xpack.migrate.action.ReindexDataStreamAction; -import org.elasticsearch.xpack.migrate.action.ReindexDataStreamAction.ReindexDataStreamResponse; import java.io.IOException; import java.util.Collections; @@ -63,14 +63,14 @@ public Set supportedCapabilities() { return Collections.unmodifiableSet(capabilities); } - static class ReindexDataStreamRestToXContentListener extends RestBuilderListener { + static class ReindexDataStreamRestToXContentListener extends RestBuilderListener { ReindexDataStreamRestToXContentListener(RestChannel channel) { super(channel); } @Override - public RestResponse buildResponse(ReindexDataStreamResponse response, XContentBuilder builder) throws Exception { + public RestResponse buildResponse(AcknowledgedResponse response, XContentBuilder builder) throws Exception { response.toXContent(builder, channel.request()); return new RestResponse(RestStatus.OK, builder); } diff --git a/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamResponseTests.java b/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamResponseTests.java deleted file mode 100644 index d886fc660d7a8..0000000000000 --- a/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamResponseTests.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.migrate.action; - -import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.io.stream.Writeable; -import org.elasticsearch.test.AbstractWireSerializingTestCase; -import org.elasticsearch.xcontent.XContentBuilder; -import org.elasticsearch.xcontent.XContentParser; -import org.elasticsearch.xcontent.json.JsonXContent; -import org.elasticsearch.xpack.migrate.action.ReindexDataStreamAction.ReindexDataStreamResponse; - -import java.io.IOException; -import java.util.Map; - -import static org.elasticsearch.xcontent.ToXContent.EMPTY_PARAMS; -import static org.hamcrest.Matchers.equalTo; - -public class ReindexDataStreamResponseTests extends AbstractWireSerializingTestCase { - @Override - protected Writeable.Reader instanceReader() { - return ReindexDataStreamResponse::new; - } - - @Override - protected ReindexDataStreamResponse createTestInstance() { - return new ReindexDataStreamResponse(randomAlphaOfLength(40)); - } - - @Override - protected ReindexDataStreamResponse mutateInstance(ReindexDataStreamResponse instance) { - return createTestInstance(); - } - - public void testToXContent() throws IOException { - ReindexDataStreamResponse response = createTestInstance(); - try (XContentBuilder builder = XContentBuilder.builder(JsonXContent.jsonXContent)) { - builder.humanReadable(true); - response.toXContent(builder, EMPTY_PARAMS); - try (XContentParser parser = createParser(JsonXContent.jsonXContent, BytesReference.bytes(builder))) { - assertThat(parser.map(), equalTo(Map.of("acknowledged", true))); - } - } - } -}