From 5764a188a9fbadf2eec6098541174e9c62f50d0b Mon Sep 17 00:00:00 2001 From: Lee Hinman Date: Tue, 23 Mar 2021 15:31:38 -0600 Subject: [PATCH] Add REST scaffolding for node shutdown API (#70697) 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 | 71 ++++++++++++++++++ .../TransportDeleteShutdownNodeAction.java | 60 +++++++++++++++ .../TransportGetShutdownStatusAction.java | 62 +++++++++++++++ .../TransportPutShutdownNodeAction.java | 60 +++++++++++++++ .../xpack/shutdown/ShutdownTests.java | 16 ++++ .../api/shutdown.delete_node.json | 31 ++++++++ .../rest-api-spec/api/shutdown.get_node.json | 34 +++++++++ .../rest-api-spec/api/shutdown.put_node.json | 35 +++++++++ 17 files changed, 701 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..99cd25ffbcfa5 --- /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, "/_nodes/{nodeId}/shutdown")); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) { + String nodeId = request.param("nodeId"); + 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..041903f9f757c --- /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, "/_nodes/{nodeId}/shutdown"), + new Route(RestRequest.Method.GET, "/_nodes/shutdown") + ); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) { + String[] nodeIds = Strings.commaDelimitedListToStringArray(request.param("nodeId")); + 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..b1e27da9ca1fe --- /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, "/_nodes/{nodeId}/shutdown")); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) { + String nodeId = request.param("nodeId"); + 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..3cc74c4de604c --- /dev/null +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/ShutdownPlugin.java @@ -0,0 +1,71 @@ +/* + * 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..864bf44d8d3fa --- /dev/null +++ b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.delete_node.json @@ -0,0 +1,31 @@ +{ + "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":"/_nodes/{node_id}/shutdown", + "methods":[ + "DELETE" + ], + "parts":{ + "node_id":{ + "type":"string", + "description":"The node id of node to be removed from the shutdown state" + } + } + } + ] + }, + "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 new file mode 100644 index 0000000000000..02aec640d89ec --- /dev/null +++ b/x-pack/plugin/src/test/resources/rest-api-spec/api/shutdown.get_node.json @@ -0,0 +1,34 @@ +{ + "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":"/_nodes/shutdown", + "methods":["GET"], + "parts":{} + }, + { + "path":"/_nodes/{node_id}/shutdown", + "methods":["GET"], + "parts":{ + "node_id":{ + "type":"string", + "description":"Which node for which to retrieve the shutdown status" + } + } + } + ] + }, + "params":{} + } +} 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..257e7b628318b --- /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":"/_nodes/{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 + } + } +}