diff --git a/docs/reference/cluster.asciidoc b/docs/reference/cluster.asciidoc index 088de8d2ccf..4c823119daf 100644 --- a/docs/reference/cluster.asciidoc +++ b/docs/reference/cluster.asciidoc @@ -46,5 +46,3 @@ include::cluster/nodes-stats.asciidoc[] include::cluster/nodes-info.asciidoc[] include::cluster/nodes-hot-threads.asciidoc[] - -include::cluster/nodes-shutdown.asciidoc[] diff --git a/docs/reference/cluster/nodes-shutdown.asciidoc b/docs/reference/cluster/nodes-shutdown.asciidoc deleted file mode 100644 index 65030a384c8..00000000000 --- a/docs/reference/cluster/nodes-shutdown.asciidoc +++ /dev/null @@ -1,57 +0,0 @@ -[[cluster-nodes-shutdown]] -== Nodes Shutdown - -The nodes shutdown API allows to shutdown one or more (or all) nodes in -the cluster. Here is an example of shutting the `_local` node the -request is directed to: - -[source,js] --------------------------------------------------- -$ curl -XPOST 'http://localhost:9200/_cluster/nodes/_local/_shutdown' --------------------------------------------------- - -Specific node(s) can be shutdown as well using their respective node ids -(or other selective options as explained -<> .): - -[source,js] --------------------------------------------------- -$ curl -XPOST 'http://localhost:9200/_cluster/nodes/nodeId1,nodeId2/_shutdown' --------------------------------------------------- - -The master (of the cluster) can also be shutdown using: - -[source,js] --------------------------------------------------- -$ curl -XPOST 'http://localhost:9200/_cluster/nodes/_master/_shutdown' --------------------------------------------------- - -Finally, all nodes can be shutdown using one of the options below: - -[source,js] --------------------------------------------------- -$ curl -XPOST 'http://localhost:9200/_shutdown' - -$ curl -XPOST 'http://localhost:9200/_cluster/nodes/_shutdown' - -$ curl -XPOST 'http://localhost:9200/_cluster/nodes/_all/_shutdown' --------------------------------------------------- - -[float] -[[delay]] -=== Delay - -By default, the shutdown will be executed after a 1 second delay (`1s`). -The delay can be customized by setting the `delay` parameter in a time -value format. For example: - -[source,js] --------------------------------------------------- -$ curl -XPOST 'http://localhost:9200/_cluster/nodes/_local/_shutdown?delay=10s' --------------------------------------------------- - -[float] -=== Disable Shutdown - -The shutdown API can be disabled by setting `action.disable_shutdown` in -the node configuration. diff --git a/docs/reference/migration/migrate_2_0.asciidoc b/docs/reference/migration/migrate_2_0.asciidoc index 4d9ca005706..4988d05006c 100644 --- a/docs/reference/migration/migrate_2_0.asciidoc +++ b/docs/reference/migration/migrate_2_0.asciidoc @@ -405,3 +405,8 @@ The obsolete parameters `expand_wildcards_open` and `expand_wildcards_close` are supported by the snapshot and restore operations. These parameters have been replaced by a single `expand_wildcards` parameter. See <> for more. +=== `_shutdown` API + +The `_shutdown` API has been removed without a replacement. Nodes should be managed via operating +systems and the provided start/stop scripts. + diff --git a/docs/reference/setup/upgrade.asciidoc b/docs/reference/setup/upgrade.asciidoc index d2a33d9e477..3a87a049563 100644 --- a/docs/reference/setup/upgrade.asciidoc +++ b/docs/reference/setup/upgrade.asciidoc @@ -94,11 +94,6 @@ This syntax applies to Elasticsearch 1.0 and later: * Shut down a single node within the cluster. -[source,sh] --------------------------------------------- -curl -XPOST 'http://localhost:9200/_cluster/nodes/_local/_shutdown' --------------------------------------------- - * Confirm that all shards are correctly reallocated to the remaining running nodes. * Upgrade the stopped node. To upgrade using a zip or compressed tarball from elasticsearch.org: @@ -149,11 +144,6 @@ This syntax is from versions prior to 1.0: -------------------------------------------------- * Stop all Elasticsearch services on all nodes in the cluster. -[source,sh] ------------------------------------------------------- - curl -XPOST 'http://localhost:9200/_shutdown' ------------------------------------------------------- - * On the first node to be upgraded, extract the archive or install the new package as described above in the Rolling Upgrades section. Repeat for all nodes. * After upgrading Elasticsearch on all nodes is complete, the cluster can be started by starting each node individually. diff --git a/rest-api-spec/api/nodes.shutdown.json b/rest-api-spec/api/nodes.shutdown.json deleted file mode 100644 index 6c8bc42f0f4..00000000000 --- a/rest-api-spec/api/nodes.shutdown.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "nodes.shutdown": { - "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/master/cluster-nodes-shutdown.html", - "methods": ["POST"], - "url": { - "path": "/_shutdown", - "paths": ["/_shutdown", "/_cluster/nodes/_shutdown", "/_cluster/nodes/{node_id}/_shutdown"], - "parts": { - "node_id": { - "type" : "list", - "description" : "A comma-separated list of node IDs or names to perform the operation on; use `_local` to perform the operation on the node you're connected to, leave empty to perform the operation on all nodes" - } - }, - "params": { - "delay": { - "type" : "time", - "description" : "Set the delay for the operation (default: 1s)" - }, - "exit": { - "type" : "boolean", - "description" : "Exit the JVM as well (default: true)" - } - } - }, - "body": null - } -} diff --git a/src/main/java/org/elasticsearch/action/ActionModule.java b/src/main/java/org/elasticsearch/action/ActionModule.java index 49d841567b4..7e596dd5a93 100644 --- a/src/main/java/org/elasticsearch/action/ActionModule.java +++ b/src/main/java/org/elasticsearch/action/ActionModule.java @@ -28,8 +28,6 @@ import org.elasticsearch.action.admin.cluster.node.hotthreads.TransportNodesHotT import org.elasticsearch.action.admin.cluster.node.info.NodesInfoAction; import org.elasticsearch.action.admin.cluster.node.info.TransportNodesInfoAction; import org.elasticsearch.action.admin.cluster.node.liveness.TransportLivenessAction; -import org.elasticsearch.action.admin.cluster.node.shutdown.NodesShutdownAction; -import org.elasticsearch.action.admin.cluster.node.shutdown.TransportNodesShutdownAction; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsAction; import org.elasticsearch.action.admin.cluster.node.stats.TransportNodesStatsAction; import org.elasticsearch.action.admin.cluster.repositories.delete.DeleteRepositoryAction; @@ -222,7 +220,6 @@ public class ActionModule extends AbstractModule { bind(ActionFilters.class).asEagerSingleton(); registerAction(NodesInfoAction.INSTANCE, TransportNodesInfoAction.class); registerAction(NodesStatsAction.INSTANCE, TransportNodesStatsAction.class); - registerAction(NodesShutdownAction.INSTANCE, TransportNodesShutdownAction.class); registerAction(NodesHotThreadsAction.INSTANCE, TransportNodesHotThreadsAction.class); registerAction(ClusterStatsAction.INSTANCE, TransportClusterStatsAction.class); diff --git a/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/NodesShutdownAction.java b/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/NodesShutdownAction.java deleted file mode 100644 index 8906d658c47..00000000000 --- a/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/NodesShutdownAction.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.action.admin.cluster.node.shutdown; - -import org.elasticsearch.action.admin.cluster.ClusterAction; -import org.elasticsearch.client.ClusterAdminClient; - -/** - */ -public class NodesShutdownAction extends ClusterAction { - - public static final NodesShutdownAction INSTANCE = new NodesShutdownAction(); - public static final String NAME = "cluster:admin/nodes/shutdown"; - - private NodesShutdownAction() { - super(NAME); - } - - @Override - public NodesShutdownResponse newResponse() { - return new NodesShutdownResponse(); - } - - @Override - public NodesShutdownRequestBuilder newRequestBuilder(ClusterAdminClient client) { - return new NodesShutdownRequestBuilder(client); - } -} diff --git a/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/NodesShutdownRequest.java b/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/NodesShutdownRequest.java deleted file mode 100644 index aeaf5754f99..00000000000 --- a/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/NodesShutdownRequest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.action.admin.cluster.node.shutdown; - -import org.elasticsearch.action.ActionRequestValidationException; -import org.elasticsearch.action.support.master.MasterNodeOperationRequest; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.unit.TimeValue; - -import java.io.IOException; - -import static org.elasticsearch.common.unit.TimeValue.readTimeValue; - -/** - * - */ -public class NodesShutdownRequest extends MasterNodeOperationRequest { - - String[] nodesIds = Strings.EMPTY_ARRAY; - - TimeValue delay = TimeValue.timeValueSeconds(1); - - boolean exit = true; - - NodesShutdownRequest() { - } - - public NodesShutdownRequest(String... nodesIds) { - this.nodesIds = nodesIds; - } - - public NodesShutdownRequest nodesIds(String... nodesIds) { - this.nodesIds = nodesIds; - return this; - } - - /** - * The delay for the shutdown to occur. Defaults to 1s. - */ - public NodesShutdownRequest delay(TimeValue delay) { - this.delay = delay; - return this; - } - - public TimeValue delay() { - return this.delay; - } - - /** - * The delay for the shutdown to occur. Defaults to 1s. - */ - public NodesShutdownRequest delay(String delay) { - return delay(TimeValue.parseTimeValue(delay, null)); - } - - /** - * Should the JVM be exited as well or not. Defaults to true. - */ - public NodesShutdownRequest exit(boolean exit) { - this.exit = exit; - return this; - } - - /** - * Should the JVM be exited as well or not. Defaults to true. - */ - public boolean exit() { - return exit; - } - - @Override - public ActionRequestValidationException validate() { - return null; - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - delay = readTimeValue(in); - nodesIds = in.readStringArray(); - exit = in.readBoolean(); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - delay.writeTo(out); - out.writeStringArrayNullable(nodesIds); - out.writeBoolean(exit); - } -} diff --git a/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/NodesShutdownRequestBuilder.java b/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/NodesShutdownRequestBuilder.java deleted file mode 100644 index fc0f767f02c..00000000000 --- a/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/NodesShutdownRequestBuilder.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.action.admin.cluster.node.shutdown; - -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.support.master.MasterNodeOperationRequestBuilder; -import org.elasticsearch.client.ClusterAdminClient; -import org.elasticsearch.common.unit.TimeValue; - -/** - * - */ -public class NodesShutdownRequestBuilder extends MasterNodeOperationRequestBuilder { - - public NodesShutdownRequestBuilder(ClusterAdminClient clusterClient) { - super(clusterClient, new NodesShutdownRequest()); - } - - /** - * The nodes ids to restart. - */ - public NodesShutdownRequestBuilder setNodesIds(String... nodesIds) { - request.nodesIds(nodesIds); - return this; - } - - /** - * The delay for the restart to occur. Defaults to 1s. - */ - public NodesShutdownRequestBuilder setDelay(TimeValue delay) { - request.delay(delay); - return this; - } - - /** - * The delay for the restart to occur. Defaults to 1s. - */ - public NodesShutdownRequestBuilder setDelay(String delay) { - request.delay(delay); - return this; - } - - /** - * Should the JVM be exited as well or not. Defaults to true. - */ - public NodesShutdownRequestBuilder setExit(boolean exit) { - request.exit(exit); - return this; - } - - @Override - protected void doExecute(ActionListener listener) { - client.nodesShutdown(request, listener); - } -} diff --git a/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/NodesShutdownResponse.java b/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/NodesShutdownResponse.java deleted file mode 100644 index 7375038ddb6..00000000000 --- a/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/NodesShutdownResponse.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.action.admin.cluster.node.shutdown; - -import org.elasticsearch.action.ActionResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; - -/** - * - */ -public class NodesShutdownResponse extends ActionResponse { - - private ClusterName clusterName; - private DiscoveryNode[] nodes; - - NodesShutdownResponse() { - } - - public NodesShutdownResponse(ClusterName clusterName, DiscoveryNode[] nodes) { - this.clusterName = clusterName; - this.nodes = nodes; - } - - public ClusterName getClusterName() { - return this.clusterName; - } - - public DiscoveryNode[] getNodes() { - return this.nodes; - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - clusterName = ClusterName.readClusterName(in); - nodes = new DiscoveryNode[in.readVInt()]; - for (int i = 0; i < nodes.length; i++) { - nodes[i] = DiscoveryNode.readNode(in); - } - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - clusterName.writeTo(out); - out.writeVInt(nodes.length); - for (DiscoveryNode node : nodes) { - node.writeTo(out); - } - } -} diff --git a/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/TransportNodesShutdownAction.java b/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/TransportNodesShutdownAction.java deleted file mode 100644 index 422deb29b41..00000000000 --- a/src/main/java/org/elasticsearch/action/admin/cluster/node/shutdown/TransportNodesShutdownAction.java +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.action.admin.cluster.node.shutdown; - -import com.carrotsearch.hppc.ObjectOpenHashSet; -import com.carrotsearch.hppc.cursors.ObjectCursor; -import org.elasticsearch.ElasticsearchException; -import org.elasticsearch.ElasticsearchIllegalStateException; -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.support.ActionFilters; -import org.elasticsearch.action.support.master.TransportMasterNodeOperationAction; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.cluster.ClusterService; -import org.elasticsearch.cluster.ClusterState; -import org.elasticsearch.cluster.block.ClusterBlockException; -import org.elasticsearch.cluster.block.ClusterBlockLevel; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.node.Node; -import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.transport.*; - -import java.io.IOException; -import java.util.concurrent.CountDownLatch; - -/** - * - */ -public class TransportNodesShutdownAction extends TransportMasterNodeOperationAction { - - public static final String SHUTDOWN_NODE_ACTION_NAME = NodesShutdownAction.NAME + "[n]"; - - private final Node node; - private final ClusterName clusterName; - private final boolean disabled; - private final TimeValue delay; - - @Inject - public TransportNodesShutdownAction(Settings settings, TransportService transportService, ClusterService clusterService, ThreadPool threadPool, - Node node, ClusterName clusterName, ActionFilters actionFilters) { - super(settings, NodesShutdownAction.NAME, transportService, clusterService, threadPool, actionFilters, NodesShutdownRequest.class); - this.node = node; - this.clusterName = clusterName; - this.disabled = settings.getAsBoolean("action.disable_shutdown", this.settings.getAsBoolean("action.admin.cluster.node.shutdown.disabled", false)); - this.delay = this.settings.getAsTime("action.admin.cluster.node.shutdown.delay", TimeValue.timeValueMillis(200)); - - this.transportService.registerRequestHandler(SHUTDOWN_NODE_ACTION_NAME, NodeShutdownRequest.class, ThreadPool.Names.SAME, new NodeShutdownRequestHandler()); - } - - @Override - protected String executor() { - return ThreadPool.Names.GENERIC; - } - - @Override - protected ClusterBlockException checkBlock(NodesShutdownRequest request, ClusterState state) { - // Stopping a node impacts the cluster state, so we check for the METADATA_WRITE block here - return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE); - } - - @Override - protected NodesShutdownResponse newResponse() { - return new NodesShutdownResponse(); - } - - @Override - protected void processBeforeDelegationToMaster(NodesShutdownRequest request, ClusterState state) { - String[] nodesIds = request.nodesIds; - if (nodesIds != null) { - for (int i = 0; i < nodesIds.length; i++) { - // replace the _local one, since it looses its meaning when going over to the master... - if ("_local".equals(nodesIds[i])) { - nodesIds[i] = state.nodes().localNodeId(); - } - } - } - } - - @Override - protected void masterOperation(final NodesShutdownRequest request, final ClusterState state, final ActionListener listener) throws ElasticsearchException { - if (disabled) { - throw new ElasticsearchIllegalStateException("Shutdown is disabled"); - } - final ObjectOpenHashSet nodes = new ObjectOpenHashSet<>(); - if (state.nodes().isAllNodes(request.nodesIds)) { - logger.info("[cluster_shutdown]: requested, shutting down in [{}]", request.delay); - nodes.addAll(state.nodes().dataNodes().values()); - nodes.addAll(state.nodes().masterNodes().values()); - Thread t = new Thread(new Runnable() { - @Override - public void run() { - try { - Thread.sleep(request.delay.millis()); - } catch (InterruptedException e) { - // ignore - } - // first, stop the cluster service - logger.trace("[cluster_shutdown]: stopping the cluster service so no re-routing will occur"); - clusterService.stop(); - - final CountDownLatch latch = new CountDownLatch(nodes.size()); - for (ObjectCursor cursor : nodes) { - final DiscoveryNode node = cursor.value; - if (node.id().equals(state.nodes().masterNodeId())) { - // don't shutdown the master yet... - latch.countDown(); - } else { - logger.trace("[cluster_shutdown]: sending shutdown request to [{}]", node); - transportService.sendRequest(node, SHUTDOWN_NODE_ACTION_NAME, new NodeShutdownRequest(request), new EmptyTransportResponseHandler(ThreadPool.Names.SAME) { - @Override - public void handleResponse(TransportResponse.Empty response) { - logger.trace("[cluster_shutdown]: received shutdown response from [{}]", node); - latch.countDown(); - } - - @Override - public void handleException(TransportException exp) { - logger.warn("[cluster_shutdown]: received failed shutdown response from [{}]", exp, node); - latch.countDown(); - } - }); - } - } - try { - latch.await(); - } catch (InterruptedException e) { - // ignore - } - logger.info("[cluster_shutdown]: done shutting down all nodes except master, proceeding to master"); - - // now, kill the master - logger.trace("[cluster_shutdown]: shutting down the master [{}]", state.nodes().masterNode()); - transportService.sendRequest(state.nodes().masterNode(), SHUTDOWN_NODE_ACTION_NAME, new NodeShutdownRequest(request), new EmptyTransportResponseHandler(ThreadPool.Names.SAME) { - @Override - public void handleResponse(TransportResponse.Empty response) { - logger.trace("[cluster_shutdown]: received shutdown response from master"); - } - - @Override - public void handleException(TransportException exp) { - logger.warn("[cluster_shutdown]: received failed shutdown response master", exp); - } - }); - } - }); - t.start(); - } else { - final String[] nodesIds = state.nodes().resolveNodesIds(request.nodesIds); - logger.info("[partial_cluster_shutdown]: requested, shutting down [{}] in [{}]", nodesIds, request.delay); - - for (String nodeId : nodesIds) { - final DiscoveryNode node = state.nodes().get(nodeId); - if (node != null) { - nodes.add(node); - } - } - - Thread t = new Thread(new Runnable() { - @Override - public void run() { - try { - Thread.sleep(request.delay.millis()); - } catch (InterruptedException e) { - // ignore - } - - final CountDownLatch latch = new CountDownLatch(nodesIds.length); - for (String nodeId : nodesIds) { - final DiscoveryNode node = state.nodes().get(nodeId); - if (node == null) { - logger.warn("[partial_cluster_shutdown]: no node to shutdown for node_id [{}]", nodeId); - latch.countDown(); - continue; - } - - logger.trace("[partial_cluster_shutdown]: sending shutdown request to [{}]", node); - transportService.sendRequest(node, SHUTDOWN_NODE_ACTION_NAME, new NodeShutdownRequest(request), new EmptyTransportResponseHandler(ThreadPool.Names.SAME) { - @Override - public void handleResponse(TransportResponse.Empty response) { - logger.trace("[partial_cluster_shutdown]: received shutdown response from [{}]", node); - latch.countDown(); - } - - @Override - public void handleException(TransportException exp) { - logger.warn("[partial_cluster_shutdown]: received failed shutdown response from [{}]", exp, node); - latch.countDown(); - } - }); - } - - try { - latch.await(); - } catch (InterruptedException e) { - // ignore - } - - logger.info("[partial_cluster_shutdown]: done shutting down [{}]", ((Object) nodesIds)); - } - }); - t.start(); - } - listener.onResponse(new NodesShutdownResponse(clusterName, nodes.toArray(DiscoveryNode.class))); - } - - private class NodeShutdownRequestHandler implements TransportRequestHandler { - - @Override - public void messageReceived(final NodeShutdownRequest request, TransportChannel channel) throws Exception { - if (disabled) { - throw new ElasticsearchIllegalStateException("Shutdown is disabled"); - } - logger.info("shutting down in [{}]", delay); - Thread t = new Thread(new Runnable() { - @Override - public void run() { - try { - Thread.sleep(delay.millis()); - } catch (InterruptedException e) { - // ignore - } - if (!request.exit) { - logger.info("initiating requested shutdown (no exit)..."); - try { - node.close(); - } catch (Exception e) { - logger.warn("Failed to shutdown", e); - } - return; - } - boolean shutdownWithWrapper = false; - if (System.getProperty("elasticsearch-service") != null) { - try { - Class wrapperManager = settings.getClassLoader().loadClass("org.tanukisoftware.wrapper.WrapperManager"); - logger.info("initiating requested shutdown (using service)"); - wrapperManager.getMethod("stopAndReturn", int.class).invoke(null, 0); - shutdownWithWrapper = true; - } catch (Throwable e) { - logger.error("failed to initial shutdown on service wrapper", e); - } - } - if (!shutdownWithWrapper) { - logger.info("initiating requested shutdown..."); - try { - node.close(); - } catch (Exception e) { - logger.warn("Failed to shutdown", e); - } finally { - // make sure we initiate the shutdown hooks, so the Bootstrap#main thread will exit - System.exit(0); - } - } - } - }); - t.start(); - - channel.sendResponse(TransportResponse.Empty.INSTANCE); - } - } - - static class NodeShutdownRequest extends TransportRequest { - - boolean exit; - - NodeShutdownRequest() { - } - - NodeShutdownRequest(NodesShutdownRequest request) { - super(request); - this.exit = request.exit(); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - exit = in.readBoolean(); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeBoolean(exit); - } - } -} diff --git a/src/main/java/org/elasticsearch/client/ClusterAdminClient.java b/src/main/java/org/elasticsearch/client/ClusterAdminClient.java index 87ade248cd4..0169151fc93 100644 --- a/src/main/java/org/elasticsearch/client/ClusterAdminClient.java +++ b/src/main/java/org/elasticsearch/client/ClusterAdminClient.java @@ -29,9 +29,6 @@ import org.elasticsearch.action.admin.cluster.node.hotthreads.NodesHotThreadsRes import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequest; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequestBuilder; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse; -import org.elasticsearch.action.admin.cluster.node.shutdown.NodesShutdownRequest; -import org.elasticsearch.action.admin.cluster.node.shutdown.NodesShutdownRequestBuilder; -import org.elasticsearch.action.admin.cluster.node.shutdown.NodesShutdownResponse; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsRequest; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsRequestBuilder; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse; @@ -248,29 +245,6 @@ public interface ClusterAdminClient extends ElasticsearchClient nodesShutdown(NodesShutdownRequest request); - - /** - * Shutdown nodes in the cluster. - * - * @param request The nodes shutdown request - * @param listener A listener to be notified with a result - * @see org.elasticsearch.client.Requests#nodesShutdownRequest(String...) - */ - void nodesShutdown(NodesShutdownRequest request, ActionListener listener); - - /** - * Shutdown nodes in the cluster. - */ - NodesShutdownRequestBuilder prepareNodesShutdown(String... nodesIds); - /** * Returns list of shards the given search would be executed on. */ diff --git a/src/main/java/org/elasticsearch/client/Requests.java b/src/main/java/org/elasticsearch/client/Requests.java index d8717ffb095..6fad2682a2a 100644 --- a/src/main/java/org/elasticsearch/client/Requests.java +++ b/src/main/java/org/elasticsearch/client/Requests.java @@ -21,7 +21,6 @@ package org.elasticsearch.client; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequest; -import org.elasticsearch.action.admin.cluster.node.shutdown.NodesShutdownRequest; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsRequest; import org.elasticsearch.action.admin.cluster.repositories.delete.DeleteRepositoryRequest; import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesRequest; @@ -423,24 +422,6 @@ public class Requests { return new ClusterStatsRequest(); } - /** - * Shuts down all nodes in the cluster. - */ - public static NodesShutdownRequest nodesShutdownRequest() { - return new NodesShutdownRequest(); - } - - /** - * Shuts down the specified nodes in the cluster. - * - * @param nodesIds The nodes ids to get the status for - * @return The nodes info request - * @see org.elasticsearch.client.ClusterAdminClient#nodesShutdown(org.elasticsearch.action.admin.cluster.node.shutdown.NodesShutdownRequest) - */ - public static NodesShutdownRequest nodesShutdownRequest(String... nodesIds) { - return new NodesShutdownRequest(nodesIds); - } - /** * Registers snapshot repository * diff --git a/src/main/java/org/elasticsearch/client/support/AbstractClusterAdminClient.java b/src/main/java/org/elasticsearch/client/support/AbstractClusterAdminClient.java index 1ff8b42d7d4..f4a6e58e49a 100644 --- a/src/main/java/org/elasticsearch/client/support/AbstractClusterAdminClient.java +++ b/src/main/java/org/elasticsearch/client/support/AbstractClusterAdminClient.java @@ -33,10 +33,6 @@ import org.elasticsearch.action.admin.cluster.node.info.NodesInfoAction; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequest; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequestBuilder; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse; -import org.elasticsearch.action.admin.cluster.node.shutdown.NodesShutdownAction; -import org.elasticsearch.action.admin.cluster.node.shutdown.NodesShutdownRequest; -import org.elasticsearch.action.admin.cluster.node.shutdown.NodesShutdownRequestBuilder; -import org.elasticsearch.action.admin.cluster.node.shutdown.NodesShutdownResponse; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsAction; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsRequest; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsRequestBuilder; @@ -233,21 +229,6 @@ public abstract class AbstractClusterAdminClient implements ClusterAdminClient { return new NodesHotThreadsRequestBuilder(this).setNodesIds(nodesIds); } - @Override - public ActionFuture nodesShutdown(final NodesShutdownRequest request) { - return execute(NodesShutdownAction.INSTANCE, request); - } - - @Override - public void nodesShutdown(final NodesShutdownRequest request, final ActionListener listener) { - execute(NodesShutdownAction.INSTANCE, request, listener); - } - - @Override - public NodesShutdownRequestBuilder prepareNodesShutdown(String... nodesIds) { - return new NodesShutdownRequestBuilder(this).setNodesIds(nodesIds); - } - @Override public ActionFuture searchShards(final ClusterSearchShardsRequest request) { return execute(ClusterSearchShardsAction.INSTANCE, request); diff --git a/src/main/java/org/elasticsearch/rest/action/RestActionModule.java b/src/main/java/org/elasticsearch/rest/action/RestActionModule.java index b8724b8a75b..874a91f3af2 100644 --- a/src/main/java/org/elasticsearch/rest/action/RestActionModule.java +++ b/src/main/java/org/elasticsearch/rest/action/RestActionModule.java @@ -28,7 +28,6 @@ import org.elasticsearch.rest.action.admin.cluster.repositories.verify.RestVerif import org.elasticsearch.rest.action.admin.cluster.health.RestClusterHealthAction; import org.elasticsearch.rest.action.admin.cluster.node.hotthreads.RestNodesHotThreadsAction; import org.elasticsearch.rest.action.admin.cluster.node.info.RestNodesInfoAction; -import org.elasticsearch.rest.action.admin.cluster.node.shutdown.RestNodesShutdownAction; import org.elasticsearch.rest.action.admin.cluster.node.stats.RestNodesStatsAction; import org.elasticsearch.rest.action.admin.cluster.repositories.delete.RestDeleteRepositoryAction; import org.elasticsearch.rest.action.admin.cluster.repositories.get.RestGetRepositoriesAction; @@ -132,7 +131,6 @@ public class RestActionModule extends AbstractModule { bind(RestNodesInfoAction.class).asEagerSingleton(); bind(RestNodesStatsAction.class).asEagerSingleton(); bind(RestNodesHotThreadsAction.class).asEagerSingleton(); - bind(RestNodesShutdownAction.class).asEagerSingleton(); bind(RestClusterStatsAction.class).asEagerSingleton(); bind(RestClusterStateAction.class).asEagerSingleton(); bind(RestClusterHealthAction.class).asEagerSingleton(); diff --git a/src/main/java/org/elasticsearch/rest/action/admin/cluster/node/shutdown/RestNodesShutdownAction.java b/src/main/java/org/elasticsearch/rest/action/admin/cluster/node/shutdown/RestNodesShutdownAction.java deleted file mode 100644 index 950ce9083af..00000000000 --- a/src/main/java/org/elasticsearch/rest/action/admin/cluster/node/shutdown/RestNodesShutdownAction.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.rest.action.admin.cluster.node.shutdown; - -import org.elasticsearch.action.admin.cluster.node.shutdown.NodesShutdownRequest; -import org.elasticsearch.action.admin.cluster.node.shutdown.NodesShutdownResponse; -import org.elasticsearch.client.Client; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.rest.*; -import org.elasticsearch.rest.action.support.RestBuilderListener; - -/** - * - */ -public class RestNodesShutdownAction extends BaseRestHandler { - - @Inject - public RestNodesShutdownAction(Settings settings, RestController controller, Client client) { - super(settings, controller, client); - - controller.registerHandler(RestRequest.Method.POST, "/_shutdown", this); - controller.registerHandler(RestRequest.Method.POST, "/_cluster/nodes/_shutdown", this); - controller.registerHandler(RestRequest.Method.POST, "/_cluster/nodes/{nodeId}/_shutdown", this); - } - - @Override - public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) { - String[] nodesIds = Strings.splitStringByCommaToArray(request.param("nodeId")); - NodesShutdownRequest nodesShutdownRequest = new NodesShutdownRequest(nodesIds); - nodesShutdownRequest.listenerThreaded(false); - nodesShutdownRequest.delay(request.paramAsTime("delay", nodesShutdownRequest.delay())); - nodesShutdownRequest.exit(request.paramAsBoolean("exit", nodesShutdownRequest.exit())); - client.admin().cluster().nodesShutdown(nodesShutdownRequest, new RestBuilderListener(channel) { - @Override - public RestResponse buildResponse(NodesShutdownResponse response, XContentBuilder builder) throws Exception { - builder.startObject(); - builder.field("cluster_name", response.getClusterName().value()); - - builder.startObject("nodes"); - for (DiscoveryNode node : response.getNodes()) { - builder.startObject(node.id(), XContentBuilder.FieldCaseConversion.NONE); - builder.field("name", node.name(), XContentBuilder.FieldCaseConversion.NONE); - builder.endObject(); - } - builder.endObject(); - - builder.endObject(); - return new BytesRestResponse(RestStatus.OK, builder); - } - }); - } -} diff --git a/src/test/java/org/elasticsearch/client/AbstractClientHeadersTests.java b/src/test/java/org/elasticsearch/client/AbstractClientHeadersTests.java index 022eb815f2c..05561a9dec0 100644 --- a/src/test/java/org/elasticsearch/client/AbstractClientHeadersTests.java +++ b/src/test/java/org/elasticsearch/client/AbstractClientHeadersTests.java @@ -23,8 +23,6 @@ import com.google.common.base.Throwables; import com.google.common.collect.ImmutableMap; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.GenericAction; -import org.elasticsearch.action.admin.cluster.node.shutdown.NodesShutdownAction; -import org.elasticsearch.action.admin.cluster.node.shutdown.NodesShutdownResponse; import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteAction; import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteResponse; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotAction; @@ -80,7 +78,7 @@ public abstract class AbstractClientHeadersTests extends ElasticsearchTestCase { IndexAction.INSTANCE, // cluster admin actions - ClusterStatsAction.INSTANCE, CreateSnapshotAction.INSTANCE, NodesShutdownAction.INSTANCE, ClusterRerouteAction.INSTANCE, + ClusterStatsAction.INSTANCE, CreateSnapshotAction.INSTANCE, ClusterRerouteAction.INSTANCE, // indices admin actions CreateIndexAction.INSTANCE, IndicesStatsAction.INSTANCE, ClearIndicesCacheAction.INSTANCE, FlushAction.INSTANCE @@ -119,7 +117,6 @@ public abstract class AbstractClientHeadersTests extends ElasticsearchTestCase { // choosing arbitrary cluster admin actions to test client.admin().cluster().prepareClusterStats().execute().addListener(new AssertingActionListener(ClusterStatsAction.NAME)); client.admin().cluster().prepareCreateSnapshot("repo", "bck").execute().addListener(new AssertingActionListener(CreateSnapshotAction.NAME)); - client.admin().cluster().prepareNodesShutdown("n1", "n2").execute().addListener(new AssertingActionListener(NodesShutdownAction.NAME)); client.admin().cluster().prepareReroute().execute().addListener(new AssertingActionListener(ClusterRerouteAction.NAME)); // choosing arbitrary indices admin actions to test diff --git a/src/test/java/org/elasticsearch/stresstest/manyindices/ManyNodesManyIndicesRecoveryStressTest.java b/src/test/java/org/elasticsearch/stresstest/manyindices/ManyNodesManyIndicesRecoveryStressTest.java index 45cbd022f1c..57bcd69b91c 100644 --- a/src/test/java/org/elasticsearch/stresstest/manyindices/ManyNodesManyIndicesRecoveryStressTest.java +++ b/src/test/java/org/elasticsearch/stresstest/manyindices/ManyNodesManyIndicesRecoveryStressTest.java @@ -72,7 +72,9 @@ public class ManyNodesManyIndicesRecoveryStressTest { } System.out.println("--> Initiating shutdown"); - client.admin().cluster().prepareNodesShutdown().setExit(false).execute().actionGet(); + for (Node node : nodes) { + node.close(); + } System.out.println("--> Waiting for all nodes to be closed..."); while (true) { diff --git a/src/test/java/org/elasticsearch/test/ExternalNode.java b/src/test/java/org/elasticsearch/test/ExternalNode.java index 705f07d3e2a..f304b71cd4b 100644 --- a/src/test/java/org/elasticsearch/test/ExternalNode.java +++ b/src/test/java/org/elasticsearch/test/ExternalNode.java @@ -212,16 +212,8 @@ final class ExternalNode implements Closeable { } synchronized void stop() { - stop(false); - } - - synchronized void stop(boolean forceKill) { if (running()) { try { - if (forceKill == false && nodeInfo != null && random.nextBoolean()) { - // sometimes shut down gracefully - getClient().admin().cluster().prepareNodesShutdown(this.nodeInfo.getNode().id()).setExit(random.nextBoolean()).setDelay("0s").get(); - } if (this.client != null) { client.close(); }