From cfc3c20209d03e30aae75958b15c8281f37120e4 Mon Sep 17 00:00:00 2001 From: Lee Hinman Date: Mon, 1 Mar 2021 16:27:52 -0700 Subject: [PATCH 1/5] Add REST scaffolding for node shutdown API This commit adds the rest endpoints for the node shutdown API. These APIs are behind the `es.shutdown_feature_flag_enabled` feature flag for now, as development is ongoing. Currently these APIs do not do anything, returning immediately. We plan to implement them for real in subsequent work. Relates to #70338 --- docs/build.gradle | 1 + gradle/run.gradle | 1 + x-pack/plugin/shutdown/build.gradle | 16 ++++ .../shutdown/DeleteShutdownNodeAction.java | 61 +++++++++++++++ .../shutdown/GetShutdownStatusAction.java | 75 +++++++++++++++++++ .../xpack/shutdown/PutShutdownNodeAction.java | 60 +++++++++++++++ .../RestDeleteShutdownNodeAction.java | 38 ++++++++++ .../shutdown/RestGetShutdownStatusAction.java | 42 +++++++++++ .../shutdown/RestPutShutdownNodeAction.java | 38 ++++++++++ .../xpack/shutdown/ShutdownPlugin.java | 73 ++++++++++++++++++ .../TransportDeleteShutdownNodeAction.java | 60 +++++++++++++++ .../TransportGetShutdownStatusAction.java | 62 +++++++++++++++ .../TransportPutShutdownNodeAction.java | 60 +++++++++++++++ .../xpack/shutdown/ShutdownTests.java | 16 ++++ .../api/shutdown.delete_node.json | 32 ++++++++ .../rest-api-spec/api/shutdown.get_node.json | 35 +++++++++ .../rest-api-spec/api/shutdown.put_node.json | 35 +++++++++ 17 files changed, 705 insertions(+) create mode 100644 x-pack/plugin/shutdown/build.gradle create mode 100644 x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/DeleteShutdownNodeAction.java create mode 100644 x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/GetShutdownStatusAction.java create mode 100644 x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/PutShutdownNodeAction.java create mode 100644 x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestDeleteShutdownNodeAction.java create mode 100644 x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestGetShutdownStatusAction.java create mode 100644 x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestPutShutdownNodeAction.java create mode 100644 x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/ShutdownPlugin.java create mode 100644 x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/TransportDeleteShutdownNodeAction.java create mode 100644 x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/TransportGetShutdownStatusAction.java create mode 100644 x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/TransportPutShutdownNodeAction.java create mode 100644 x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/ShutdownTests.java create mode 100644 x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.delete_node.json create mode 100644 x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.get_node.json create mode 100644 x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.put_node.json diff --git a/docs/build.gradle b/docs/build.gradle index 99cf9a23d9992..327b3902f447f 100644 --- a/docs/build.gradle +++ b/docs/build.gradle @@ -44,6 +44,7 @@ testClusters.matching { it.name == "integTest"}.configureEach { setting 'xpack.license.self_generated.type', 'trial' setting 'indices.lifecycle.history_index_enabled', 'false' systemProperty 'es.rollup_v2_feature_flag_enabled', 'true' + systemProperty 'es.shutdown_feature_flag_enabled', 'true' keystorePassword 'keystore-password' } diff --git a/gradle/run.gradle b/gradle/run.gradle index 13758bff4c55a..99d742af96773 100644 --- a/gradle/run.gradle +++ b/gradle/run.gradle @@ -25,6 +25,7 @@ testClusters { setting 'xpack.security.enabled', 'true' keystore 'bootstrap.password', 'password' user username: 'elastic-admin', password: 'elastic-password', role: 'superuser' + systemProperty 'es.shutdown_feature_flag_enabled', 'true' } } } diff --git a/x-pack/plugin/shutdown/build.gradle b/x-pack/plugin/shutdown/build.gradle new file mode 100644 index 0000000000000..d323fb6140424 --- /dev/null +++ b/x-pack/plugin/shutdown/build.gradle @@ -0,0 +1,16 @@ +apply plugin: 'elasticsearch.esplugin' + +esplugin { + name 'x-pack-shutdown' + description 'Elasticsearch Expanded Pack Plugin - Shutdown' + classname 'org.elasticsearch.xpack.shutdown.ShutdownPlugin' + extendedPlugins = ['x-pack-core'] +} +archivesBaseName = 'x-pack-shutdown' + +dependencies { + compileOnly project(path: xpackModule('core')) + testImplementation(testArtifact(project(xpackModule('core')))) +} + +addQaCheckDependencies() diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/DeleteShutdownNodeAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/DeleteShutdownNodeAction.java new file mode 100644 index 0000000000000..1574e888c6dca --- /dev/null +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/DeleteShutdownNodeAction.java @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.shutdown; + +import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.action.ActionType; +import org.elasticsearch.action.support.master.AcknowledgedResponse; +import org.elasticsearch.action.support.master.MasterNodeRequest; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; + +import java.io.IOException; + +public class DeleteShutdownNodeAction extends ActionType { + + public static final DeleteShutdownNodeAction INSTANCE = new DeleteShutdownNodeAction(); + public static final String NAME = "cluster:admin/shutdown/delete"; + + public DeleteShutdownNodeAction() { + super(NAME, AcknowledgedResponse::readFrom); + } + + public static class Request extends MasterNodeRequest { + + private final String nodeId; + + public Request(String nodeId) { + this.nodeId = nodeId; + } + + public Request(StreamInput in) throws IOException { + this.nodeId = in.readString(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(this.nodeId); + } + + public String getNodeId() { + return nodeId; + } + + @Override + public ActionRequestValidationException validate() { + if (Strings.hasText(nodeId) == false) { + ActionRequestValidationException arve = new ActionRequestValidationException(); + arve.addValidationError("the node id to remove from shutdown is required"); + return arve; + } + return null; + } + } + +} diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/GetShutdownStatusAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/GetShutdownStatusAction.java new file mode 100644 index 0000000000000..d892853a6308e --- /dev/null +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/GetShutdownStatusAction.java @@ -0,0 +1,75 @@ +/* + * 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.shutdown; + +import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.action.ActionType; +import org.elasticsearch.action.support.master.MasterNodeRequest; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.xcontent.ToXContentObject; +import org.elasticsearch.common.xcontent.XContentBuilder; + +import java.io.IOException; + +public class GetShutdownStatusAction extends ActionType { + + public static final GetShutdownStatusAction INSTANCE = new GetShutdownStatusAction(); + public static final String NAME = "cluster:admin/shutdown/get"; + + public GetShutdownStatusAction() { + super(NAME, Response::new); + } + + public static class Request extends MasterNodeRequest { + + private final String[] nodeIds; + + public Request(String... nodeIds) { + this.nodeIds = nodeIds; + } + + public static Request readFrom(StreamInput in) throws IOException { + return new Request(in.readStringArray()); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeStringArray(this.nodeIds); + } + + public String[] getNodeIds() { + return nodeIds; + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + } + + public static class Response extends ActionResponse implements ToXContentObject { + + public Response(StreamInput in) throws IOException { + + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.endObject(); + return builder; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + + } + } +} diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/PutShutdownNodeAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/PutShutdownNodeAction.java new file mode 100644 index 0000000000000..688d7dcd5ce33 --- /dev/null +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/PutShutdownNodeAction.java @@ -0,0 +1,60 @@ +/* + * 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.shutdown; + +import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.action.ActionType; +import org.elasticsearch.action.support.master.AcknowledgedResponse; +import org.elasticsearch.action.support.master.MasterNodeRequest; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; + +import java.io.IOException; + +public class PutShutdownNodeAction extends ActionType { + + public static final PutShutdownNodeAction INSTANCE = new PutShutdownNodeAction(); + public static final String NAME = "cluster:admin/shutdown/create"; + + public PutShutdownNodeAction() { + super(NAME, AcknowledgedResponse::readFrom); + } + + public static class Request extends MasterNodeRequest { + + private final String nodeId; + + public Request(String nodeId) { + this.nodeId = nodeId; + } + + public Request(StreamInput in) throws IOException { + this.nodeId = in.readString(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(this.nodeId); + } + + public String getNodeId() { + return nodeId; + } + + @Override + public ActionRequestValidationException validate() { + if (Strings.hasText(nodeId) == false) { + ActionRequestValidationException arve = new ActionRequestValidationException(); + arve.addValidationError("the node id to shutdown is required"); + return arve; + } + return null; + } + } +} diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestDeleteShutdownNodeAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestDeleteShutdownNodeAction.java new file mode 100644 index 0000000000000..c127b9a256a29 --- /dev/null +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestDeleteShutdownNodeAction.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.shutdown; + +import org.elasticsearch.client.node.NodeClient; +import org.elasticsearch.rest.BaseRestHandler; +import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.action.RestToXContentListener; + +import java.util.List; + +public class RestDeleteShutdownNodeAction extends BaseRestHandler { + + @Override + public String getName() { + return "delete_shutdown_node"; + } + + @Override + public List routes() { + return List.of(new Route(RestRequest.Method.DELETE, "/_node/{name}/shutdown")); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) { + String nodeId = request.param("name"); + return channel -> client.execute( + DeleteShutdownNodeAction.INSTANCE, + new DeleteShutdownNodeAction.Request(nodeId), + new RestToXContentListener<>(channel) + ); + } +} diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestGetShutdownStatusAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestGetShutdownStatusAction.java new file mode 100644 index 0000000000000..5dcfff9bf6c5b --- /dev/null +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestGetShutdownStatusAction.java @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.shutdown; + +import org.elasticsearch.client.node.NodeClient; +import org.elasticsearch.common.Strings; +import org.elasticsearch.rest.BaseRestHandler; +import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.action.RestToXContentListener; + +import java.util.List; + +public class RestGetShutdownStatusAction extends BaseRestHandler { + + @Override + public String getName() { + return "get_shutdown_status"; + } + + @Override + public List routes() { + return List.of( + new Route(RestRequest.Method.GET, "/_node/{name}/shutdown"), + new Route(RestRequest.Method.GET, "/_node/shutdown") + ); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) { + String[] nodeIds = Strings.commaDelimitedListToStringArray(request.param("name")); + return channel -> client.execute( + GetShutdownStatusAction.INSTANCE, + new GetShutdownStatusAction.Request(nodeIds), + new RestToXContentListener<>(channel) + ); + } +} diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestPutShutdownNodeAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestPutShutdownNodeAction.java new file mode 100644 index 0000000000000..82719308f8068 --- /dev/null +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestPutShutdownNodeAction.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.shutdown; + +import org.elasticsearch.client.node.NodeClient; +import org.elasticsearch.rest.BaseRestHandler; +import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.action.RestToXContentListener; + +import java.util.List; + +public class RestPutShutdownNodeAction extends BaseRestHandler { + + @Override + public String getName() { + return "put_shutdown_node"; + } + + @Override + public List routes() { + return List.of(new Route(RestRequest.Method.PUT, "/_node/{name}/shutdown")); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) { + String nodeId = request.param("name"); + return channel -> client.execute( + PutShutdownNodeAction.INSTANCE, + new PutShutdownNodeAction.Request(nodeId), + new RestToXContentListener<>(channel) + ); + } +} diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/ShutdownPlugin.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/ShutdownPlugin.java new file mode 100644 index 0000000000000..a86e45264806a --- /dev/null +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/ShutdownPlugin.java @@ -0,0 +1,73 @@ +/* + * 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.shutdown; + +import org.elasticsearch.action.ActionRequest; +import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.action.support.master.AcknowledgedResponse; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.node.DiscoveryNodes; +import org.elasticsearch.common.settings.ClusterSettings; +import org.elasticsearch.common.settings.IndexScopedSettings; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.settings.SettingsFilter; +import org.elasticsearch.plugins.ActionPlugin; +import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.rest.RestController; +import org.elasticsearch.rest.RestHandler; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.function.Supplier; + +public class ShutdownPlugin extends Plugin implements ActionPlugin { + + public static final boolean SHUTDOWN_FEATURE_FLAG_ENABLED = "true".equals( + System.getProperty("es.shutdown_feature_flag_enabled") + ); + + public static boolean isEnabled() { + return SHUTDOWN_FEATURE_FLAG_ENABLED; + } + + @Override + public List> getActions() { + if (isEnabled() == false) { + return Collections.emptyList(); + } + ActionHandler putShutdown = new ActionHandler<>( + PutShutdownNodeAction.INSTANCE, + TransportPutShutdownNodeAction.class + ); + ActionHandler deleteShutdown = new ActionHandler<>( + DeleteShutdownNodeAction.INSTANCE, + TransportDeleteShutdownNodeAction.class + ); + ActionHandler getStatus = new ActionHandler<>( + GetShutdownStatusAction.INSTANCE, + TransportGetShutdownStatusAction.class + ); + return Arrays.asList(putShutdown, deleteShutdown, getStatus); + } + + @Override + public List getRestHandlers( + Settings settings, + RestController restController, + ClusterSettings clusterSettings, + IndexScopedSettings indexScopedSettings, + SettingsFilter settingsFilter, + IndexNameExpressionResolver indexNameExpressionResolver, + Supplier nodesInCluster + ) { + if (isEnabled() == false) { + return Collections.emptyList(); + } + return Arrays.asList(new RestPutShutdownNodeAction(), new RestDeleteShutdownNodeAction(), new RestGetShutdownStatusAction()); + } +} diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/TransportDeleteShutdownNodeAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/TransportDeleteShutdownNodeAction.java new file mode 100644 index 0000000000000..8446e87b144d5 --- /dev/null +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/TransportDeleteShutdownNodeAction.java @@ -0,0 +1,60 @@ +/* + * 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.shutdown; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.action.support.master.AcknowledgedResponse; +import org.elasticsearch.action.support.master.AcknowledgedTransportMasterNodeAction; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.block.ClusterBlockException; +import org.elasticsearch.cluster.block.ClusterBlockLevel; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.tasks.Task; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.transport.TransportService; + +public class TransportDeleteShutdownNodeAction extends AcknowledgedTransportMasterNodeAction { + @Inject + public TransportDeleteShutdownNodeAction( + TransportService transportService, + ClusterService clusterService, + ThreadPool threadPool, + ActionFilters actionFilters, + IndexNameExpressionResolver indexNameExpressionResolver + ) { + super( + DeleteShutdownNodeAction.NAME, + transportService, + clusterService, + threadPool, + actionFilters, + DeleteShutdownNodeAction.Request::new, + indexNameExpressionResolver, + ThreadPool.Names.SAME + ); + } + + @Override + protected void masterOperation( + Task task, + DeleteShutdownNodeAction.Request request, + ClusterState state, + ActionListener listener + ) throws Exception { + // TODO: implement me! + listener.onResponse(AcknowledgedResponse.of(true)); + } + + @Override + protected ClusterBlockException checkBlock(DeleteShutdownNodeAction.Request request, ClusterState state) { + return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE); + } +} diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/TransportGetShutdownStatusAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/TransportGetShutdownStatusAction.java new file mode 100644 index 0000000000000..29d2a18ffab8f --- /dev/null +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/TransportGetShutdownStatusAction.java @@ -0,0 +1,62 @@ +/* + * 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.shutdown; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.action.support.master.TransportMasterNodeAction; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.block.ClusterBlockException; +import org.elasticsearch.cluster.block.ClusterBlockLevel; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.tasks.Task; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.transport.TransportService; + +public class TransportGetShutdownStatusAction extends TransportMasterNodeAction< + GetShutdownStatusAction.Request, + GetShutdownStatusAction.Response> { + @Inject + public TransportGetShutdownStatusAction( + TransportService transportService, + ClusterService clusterService, + ThreadPool threadPool, + ActionFilters actionFilters, + IndexNameExpressionResolver indexNameExpressionResolver + ) { + super( + GetShutdownStatusAction.NAME, + transportService, + clusterService, + threadPool, + actionFilters, + GetShutdownStatusAction.Request::readFrom, + indexNameExpressionResolver, + GetShutdownStatusAction.Response::new, + ThreadPool.Names.SAME + ); + } + + @Override + protected void masterOperation( + Task task, + GetShutdownStatusAction.Request request, + ClusterState state, + ActionListener listener + ) throws Exception { + // TODO: implement me! + listener.onResponse(new GetShutdownStatusAction.Response(null)); + } + + @Override + protected ClusterBlockException checkBlock(GetShutdownStatusAction.Request request, ClusterState state) { + return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE); + } +} diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/TransportPutShutdownNodeAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/TransportPutShutdownNodeAction.java new file mode 100644 index 0000000000000..3b395565ce53f --- /dev/null +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/TransportPutShutdownNodeAction.java @@ -0,0 +1,60 @@ +/* + * 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.shutdown; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.action.support.master.AcknowledgedResponse; +import org.elasticsearch.action.support.master.AcknowledgedTransportMasterNodeAction; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.block.ClusterBlockException; +import org.elasticsearch.cluster.block.ClusterBlockLevel; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.tasks.Task; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.transport.TransportService; + +public class TransportPutShutdownNodeAction extends AcknowledgedTransportMasterNodeAction { + @Inject + public TransportPutShutdownNodeAction( + TransportService transportService, + ClusterService clusterService, + ThreadPool threadPool, + ActionFilters actionFilters, + IndexNameExpressionResolver indexNameExpressionResolver + ) { + super( + PutShutdownNodeAction.NAME, + transportService, + clusterService, + threadPool, + actionFilters, + PutShutdownNodeAction.Request::new, + indexNameExpressionResolver, + ThreadPool.Names.SAME + ); + } + + @Override + protected void masterOperation( + Task task, + PutShutdownNodeAction.Request request, + ClusterState state, + ActionListener listener + ) throws Exception { + // TODO: implement me! + listener.onResponse(AcknowledgedResponse.of(true)); + } + + @Override + protected ClusterBlockException checkBlock(PutShutdownNodeAction.Request request, ClusterState state) { + return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE); + } +} diff --git a/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/ShutdownTests.java b/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/ShutdownTests.java new file mode 100644 index 0000000000000..ec483638e733d --- /dev/null +++ b/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/ShutdownTests.java @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.shutdown; + +import org.elasticsearch.test.ESTestCase; + +public class ShutdownTests extends ESTestCase { + public void testIt() { + // TODO: implement tests + } +} diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.delete_node.json b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.delete_node.json new file mode 100644 index 0000000000000..a8965a02329fb --- /dev/null +++ b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.delete_node.json @@ -0,0 +1,32 @@ +{ + "shutdown.delete_node":{ + "documentation":{ + "url":"https://www.elastic.co/guide/en/elasticsearch/reference/current", + "description":"Removes a node from the shutdown list" + }, + "stability":"experimental", + "visibility":"public", + "headers":{ + "accept": [ "application/json"], + "content_type": ["application/json"] + }, + "url":{ + "paths":[ + { + "path":"/_node/{node_id}/shutdown", + "methods":[ + "DELETE" + ], + "parts":{ + "node_id":{ + "type":"string", + "description":"The node id of node to be removed from the shutdown state" + } + } + } + ] + }, + "params":{}, + "body":{} + } +} diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.get_node.json b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.get_node.json new file mode 100644 index 0000000000000..c92f75bd6f94e --- /dev/null +++ b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.get_node.json @@ -0,0 +1,35 @@ +{ + "shutdown.get_node":{ + "documentation":{ + "url":"https://www.elastic.co/guide/en/elasticsearch/reference/current", + "description":"Retrieve status of a node or nodes that are currently marked as shutting down" + }, + "stability":"experimental", + "visibility":"public", + "headers":{ + "accept": [ "application/json"], + "content_type": ["application/json"] + }, + "url":{ + "paths":[ + { + "path":"/_node/shutdown", + "methods":["GET"], + "parts":{} + }, + { + "path":"/_node/{node_id}/shutdown", + "methods":["GET"], + "parts":{ + "node_id":{ + "type":"string", + "description":"Which node for which to retrieve the shutdown status" + } + } + } + ] + }, + "params":{}, + "body":{} + } +} diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.put_node.json b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.put_node.json new file mode 100644 index 0000000000000..76bd872f5f19a --- /dev/null +++ b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.put_node.json @@ -0,0 +1,35 @@ +{ + "shutdown.put_node":{ + "documentation":{ + "url":"https://www.elastic.co/guide/en/elasticsearch/reference/current", + "description":"Adds a node to be shut down" + }, + "stability":"experimental", + "visibility":"public", + "headers":{ + "accept": [ "application/json"], + "content_type": ["application/json"] + }, + "url":{ + "paths":[ + { + "path":"/_node/{node_id}/shutdown", + "methods":[ + "PUT" + ], + "parts":{ + "node_id":{ + "type":"string", + "description":"The node id of node to be shut down" + } + } + } + ] + }, + "params":{}, + "body":{ + "description":"The shutdown type definition to register", + "required": true + } + } +} From 7768dbf01851f634dbe8ba8c0370792fedbd99f9 Mon Sep 17 00:00:00 2001 From: Lee Hinman Date: Mon, 22 Mar 2021 16:14:47 -0600 Subject: [PATCH 2/5] Remove 'body' from rest spec for get/delete --- .../test/resources/rest-api-spec/api/shutdown.delete_node.json | 3 +-- .../test/resources/rest-api-spec/api/shutdown.get_node.json | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.delete_node.json b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.delete_node.json index a8965a02329fb..a2ffbd5ebbf40 100644 --- a/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.delete_node.json +++ b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.delete_node.json @@ -26,7 +26,6 @@ } ] }, - "params":{}, - "body":{} + "params":{} } } diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.get_node.json b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.get_node.json index c92f75bd6f94e..8e6d33af34d45 100644 --- a/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.get_node.json +++ b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.get_node.json @@ -29,7 +29,6 @@ } ] }, - "params":{}, - "body":{} + "params":{} } } From 858aa220a1319184190a7ae7cc6e710c9c25e19f Mon Sep 17 00:00:00 2001 From: Lee Hinman Date: Mon, 22 Mar 2021 16:18:39 -0600 Subject: [PATCH 3/5] Spotless ugh --- .../xpack/shutdown/RestGetShutdownStatusAction.java | 5 +---- .../org/elasticsearch/xpack/shutdown/ShutdownPlugin.java | 4 +--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestGetShutdownStatusAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestGetShutdownStatusAction.java index 5dcfff9bf6c5b..f6a2743f74b45 100644 --- a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestGetShutdownStatusAction.java +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestGetShutdownStatusAction.java @@ -24,10 +24,7 @@ public String getName() { @Override public List routes() { - return List.of( - new Route(RestRequest.Method.GET, "/_node/{name}/shutdown"), - new Route(RestRequest.Method.GET, "/_node/shutdown") - ); + return List.of(new Route(RestRequest.Method.GET, "/_node/{name}/shutdown"), new Route(RestRequest.Method.GET, "/_node/shutdown")); } @Override diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/ShutdownPlugin.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/ShutdownPlugin.java index a86e45264806a..3cc74c4de604c 100644 --- a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/ShutdownPlugin.java +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/ShutdownPlugin.java @@ -27,9 +27,7 @@ public class ShutdownPlugin extends Plugin implements ActionPlugin { - public static final boolean SHUTDOWN_FEATURE_FLAG_ENABLED = "true".equals( - System.getProperty("es.shutdown_feature_flag_enabled") - ); + public static final boolean SHUTDOWN_FEATURE_FLAG_ENABLED = "true".equals(System.getProperty("es.shutdown_feature_flag_enabled")); public static boolean isEnabled() { return SHUTDOWN_FEATURE_FLAG_ENABLED; From bbbf346aff26eae307e6f2fb2434b43e2f77d728 Mon Sep 17 00:00:00 2001 From: Lee Hinman Date: Tue, 23 Mar 2021 14:09:26 -0600 Subject: [PATCH 4/5] Use _nodes instead of _node (typo) --- .../xpack/shutdown/RestDeleteShutdownNodeAction.java | 2 +- .../xpack/shutdown/RestGetShutdownStatusAction.java | 2 +- .../xpack/shutdown/RestPutShutdownNodeAction.java | 2 +- .../resources/rest-api-spec/api/shutdown.delete_node.json | 2 +- .../test/resources/rest-api-spec/api/shutdown.get_node.json | 4 ++-- .../test/resources/rest-api-spec/api/shutdown.put_node.json | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestDeleteShutdownNodeAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestDeleteShutdownNodeAction.java index c127b9a256a29..be0832ea2c2fe 100644 --- a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestDeleteShutdownNodeAction.java +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestDeleteShutdownNodeAction.java @@ -23,7 +23,7 @@ public String getName() { @Override public List routes() { - return List.of(new Route(RestRequest.Method.DELETE, "/_node/{name}/shutdown")); + return List.of(new Route(RestRequest.Method.DELETE, "/_nodes/{name}/shutdown")); } @Override diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestGetShutdownStatusAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestGetShutdownStatusAction.java index f6a2743f74b45..a8a266b203bb6 100644 --- a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestGetShutdownStatusAction.java +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestGetShutdownStatusAction.java @@ -24,7 +24,7 @@ public String getName() { @Override public List routes() { - return List.of(new Route(RestRequest.Method.GET, "/_node/{name}/shutdown"), new Route(RestRequest.Method.GET, "/_node/shutdown")); + return List.of(new Route(RestRequest.Method.GET, "/_nodes/{name}/shutdown"), new Route(RestRequest.Method.GET, "/_nodes/shutdown")); } @Override diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestPutShutdownNodeAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestPutShutdownNodeAction.java index 82719308f8068..599b066eaf059 100644 --- a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestPutShutdownNodeAction.java +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestPutShutdownNodeAction.java @@ -23,7 +23,7 @@ public String getName() { @Override public List routes() { - return List.of(new Route(RestRequest.Method.PUT, "/_node/{name}/shutdown")); + return List.of(new Route(RestRequest.Method.PUT, "/_nodes/{name}/shutdown")); } @Override diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.delete_node.json b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.delete_node.json index a2ffbd5ebbf40..864bf44d8d3fa 100644 --- a/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.delete_node.json +++ b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.delete_node.json @@ -13,7 +13,7 @@ "url":{ "paths":[ { - "path":"/_node/{node_id}/shutdown", + "path":"/_nodes/{node_id}/shutdown", "methods":[ "DELETE" ], diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.get_node.json b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.get_node.json index 8e6d33af34d45..02aec640d89ec 100644 --- a/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.get_node.json +++ b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.get_node.json @@ -13,12 +13,12 @@ "url":{ "paths":[ { - "path":"/_node/shutdown", + "path":"/_nodes/shutdown", "methods":["GET"], "parts":{} }, { - "path":"/_node/{node_id}/shutdown", + "path":"/_nodes/{node_id}/shutdown", "methods":["GET"], "parts":{ "node_id":{ diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.put_node.json b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.put_node.json index 76bd872f5f19a..257e7b628318b 100644 --- a/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.put_node.json +++ b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.put_node.json @@ -13,7 +13,7 @@ "url":{ "paths":[ { - "path":"/_node/{node_id}/shutdown", + "path":"/_nodes/{node_id}/shutdown", "methods":[ "PUT" ], From 87eca1468b7cbbdec5e157c55be37c94d7d3870a Mon Sep 17 00:00:00 2001 From: Lee Hinman Date: Tue, 23 Mar 2021 14:15:24 -0600 Subject: [PATCH 5/5] Use nodeId instead of name for parameter --- .../xpack/shutdown/RestDeleteShutdownNodeAction.java | 4 ++-- .../xpack/shutdown/RestGetShutdownStatusAction.java | 7 +++++-- .../xpack/shutdown/RestPutShutdownNodeAction.java | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestDeleteShutdownNodeAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestDeleteShutdownNodeAction.java index be0832ea2c2fe..99cd25ffbcfa5 100644 --- a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestDeleteShutdownNodeAction.java +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestDeleteShutdownNodeAction.java @@ -23,12 +23,12 @@ public String getName() { @Override public List routes() { - return List.of(new Route(RestRequest.Method.DELETE, "/_nodes/{name}/shutdown")); + return List.of(new Route(RestRequest.Method.DELETE, "/_nodes/{nodeId}/shutdown")); } @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) { - String nodeId = request.param("name"); + String nodeId = request.param("nodeId"); return channel -> client.execute( DeleteShutdownNodeAction.INSTANCE, new DeleteShutdownNodeAction.Request(nodeId), diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestGetShutdownStatusAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestGetShutdownStatusAction.java index a8a266b203bb6..041903f9f757c 100644 --- a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestGetShutdownStatusAction.java +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestGetShutdownStatusAction.java @@ -24,12 +24,15 @@ public String getName() { @Override public List routes() { - return List.of(new Route(RestRequest.Method.GET, "/_nodes/{name}/shutdown"), new Route(RestRequest.Method.GET, "/_nodes/shutdown")); + return List.of( + new Route(RestRequest.Method.GET, "/_nodes/{nodeId}/shutdown"), + new Route(RestRequest.Method.GET, "/_nodes/shutdown") + ); } @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) { - String[] nodeIds = Strings.commaDelimitedListToStringArray(request.param("name")); + String[] nodeIds = Strings.commaDelimitedListToStringArray(request.param("nodeId")); return channel -> client.execute( GetShutdownStatusAction.INSTANCE, new GetShutdownStatusAction.Request(nodeIds), diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestPutShutdownNodeAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestPutShutdownNodeAction.java index 599b066eaf059..b1e27da9ca1fe 100644 --- a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestPutShutdownNodeAction.java +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/RestPutShutdownNodeAction.java @@ -23,12 +23,12 @@ public String getName() { @Override public List routes() { - return List.of(new Route(RestRequest.Method.PUT, "/_nodes/{name}/shutdown")); + return List.of(new Route(RestRequest.Method.PUT, "/_nodes/{nodeId}/shutdown")); } @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) { - String nodeId = request.param("name"); + String nodeId = request.param("nodeId"); return channel -> client.execute( PutShutdownNodeAction.INSTANCE, new PutShutdownNodeAction.Request(nodeId),