This is an automated email from the ASF dual-hosted git repository. dgovorukhin pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push: new d496245 IGNITE-12162 Add the cluster name to the promt message "--deactivate" the control.sh - Fixes #6863. d496245 is described below commit d496245d1c518c41d4bcaafb576b86c66383efe7 Author: Kirill Tkalenko <tkalkir...@yandex.ru> AuthorDate: Fri Sep 20 11:35:53 2019 +0300 IGNITE-12162 Add the cluster name to the promt message "--deactivate" the control.sh - Fixes #6863. Signed-off-by: Dmitriy Govorukhin <dmitriy.govoruk...@gmail.com> --- .../internal/client/GridClientClusterState.java | 8 +++ .../client/impl/GridClientClusterStateImpl.java | 5 ++ .../impl/connection/GridClientConnection.java | 11 +++ .../connection/GridClientNioTcpConnection.java | 7 ++ .../ignite/internal/commandline/Command.java | 10 +++ .../internal/commandline/CommandHandler.java | 35 +++++----- .../internal/commandline/DeactivateCommand.java | 12 +++- .../processors/cluster/ClusterProcessor.java | 13 ++++ .../internal/processors/rest/GridRestCommand.java | 3 + .../processors/rest/GridRestProcessor.java | 3 + .../message/GridClientClusterNameRequest.java | 26 ++++++++ .../handlers/GridRestCommandHandlerAdapter.java | 19 ++++++ .../GridChangeReadOnlyModeCommandHandler.java | 11 +-- .../cluster/GridChangeStateCommandHandler.java | 11 +-- ...ler.java => GridClusterNameCommandHandler.java} | 45 +++---------- .../rest/protocols/tcp/GridTcpRestNioListener.java | 4 ++ .../rest/request/GridRestClusterNameRequest.java | 38 +++++++++++ .../main/resources/META-INF/classnames.properties | 1 + .../util/GridCommandHandlerAbstractTest.java | 28 +++++++- .../apache/ignite/util/GridCommandHandlerTest.java | 78 ++++++++++++++++++++++ .../protocols/http/jetty/GridJettyRestHandler.java | 7 ++ 21 files changed, 300 insertions(+), 75 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/GridClientClusterState.java b/modules/core/src/main/java/org/apache/ignite/internal/client/GridClientClusterState.java index 1d669f6..6f924ee 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/client/GridClientClusterState.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/client/GridClientClusterState.java @@ -44,4 +44,12 @@ public interface GridClientClusterState { * @throws GridClientException If change of read-only mode is failed. */ public void readOnly(boolean readOnly) throws GridClientException; + + /** + * Get the cluster name. + * + * @return The name of the cluster. + * @throws GridClientException If the request to get the cluster name failed. + * */ + String clusterName() throws GridClientException; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/GridClientClusterStateImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/GridClientClusterStateImpl.java index 97901e7..4c1331c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/GridClientClusterStateImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/GridClientClusterStateImpl.java @@ -84,4 +84,9 @@ public class GridClientClusterStateImpl extends GridClientAbstractProjection<Gri } }).get(); } + + /** {@inheritDoc} */ + @Override public String clusterName() throws GridClientException { + return withReconnectHandling(GridClientConnection::clusterName).get(); + } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientConnection.java b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientConnection.java index de4347c..7214986 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientConnection.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientConnection.java @@ -347,6 +347,17 @@ public abstract class GridClientConnection { throws GridClientClosedException, GridClientConnectionResetException; /** + * Get a cluster name. + * + * @param destNodeId Destination node id. + * @return Future to get the cluster name. + * @throws GridClientConnectionResetException In case of error. + * @throws GridClientClosedException If client was manually closed before request was sent over network. + */ + public abstract GridClientFuture<String> clusterName(UUID destNodeId) + throws GridClientClosedException, GridClientConnectionResetException; + + /** * Gets node by node ID. * * @param id Node ID. diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientNioTcpConnection.java b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientNioTcpConnection.java index 5e489ac..fb10675 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientNioTcpConnection.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientNioTcpConnection.java @@ -59,6 +59,7 @@ import org.apache.ignite.internal.client.marshaller.optimized.GridClientOptimize import org.apache.ignite.internal.client.marshaller.optimized.GridClientZipOptimizedMarshaller; import org.apache.ignite.internal.processors.rest.client.message.GridClientAuthenticationRequest; import org.apache.ignite.internal.processors.rest.client.message.GridClientCacheRequest; +import org.apache.ignite.internal.processors.rest.client.message.GridClientClusterNameRequest; import org.apache.ignite.internal.processors.rest.client.message.GridClientReadOnlyModeRequest; import org.apache.ignite.internal.processors.rest.client.message.GridClientStateRequest; import org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeRequest; @@ -950,6 +951,12 @@ public class GridClientNioTcpConnection extends GridClientConnection { return res; } + /** {@inheritDoc} */ + @Override public GridClientFuture<String> clusterName(UUID destNodeId) + throws GridClientClosedException, GridClientConnectionResetException { + return makeRequest(new GridClientClusterNameRequest(), destNodeId); + } + /** * Creates client node instance from message. * diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/Command.java b/modules/core/src/main/java/org/apache/ignite/internal/commandline/Command.java index c1f382e..6f033a2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/commandline/Command.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/Command.java @@ -74,6 +74,16 @@ public interface Command<T> { public Object execute(GridClientConfiguration clientCfg, Logger logger) throws Exception; /** + * Prepares confirmation for the command. + * + * @param clientCfg Thin client configuration. + * @throws Exception If error occur. + */ + default void prepareConfirmation(GridClientConfiguration clientCfg) throws Exception{ + //no-op + } + + /** * @return Message text to show user for. If null it means that confirmantion is not needed. */ public default String confirmationPrompt() { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java index cd474db..e55ecaa 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java @@ -54,6 +54,7 @@ import org.apache.ignite.ssl.SslContextFactory; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static java.lang.System.lineSeparator; import static org.apache.ignite.internal.IgniteVersionUtils.ACK_VER_STR; import static org.apache.ignite.internal.IgniteVersionUtils.COPYRIGHT; import static org.apache.ignite.internal.commandline.CommandLogger.DOUBLE_INDENT; @@ -100,7 +101,7 @@ public class CommandHandler { private static final long DFLT_PING_TIMEOUT = 30_000L; /** */ - private static final Scanner IN = new Scanner(System.in); + private final Scanner in = new Scanner(System.in); /** Utility name. */ public static final String UTILITY_NAME = "control.(sh|bat)"; @@ -229,26 +230,30 @@ public class CommandHandler { Command command = args.command(); commandName = command.name(); - if (!args.autoConfirmation() && !confirm(command.confirmationPrompt())) { - logger.info("Operation cancelled."); - - return EXIT_CODE_OK; - } + GridClientConfiguration clientCfg = getClientConfiguration(args); int tryConnectMaxCount = 3; boolean suppliedAuth = !F.isEmpty(args.userName()) && !F.isEmpty(args.password()); - GridClientConfiguration clientCfg = getClientConfiguration(args); - - logger.info("Command [" + commandName + "] started"); - logger.info("Arguments: " + String.join(" ", rawArgs)); - logger.info(DELIM); - boolean credentialsRequested = false; while (true) { try { + if (!args.autoConfirmation()) { + command.prepareConfirmation(clientCfg); + + if (!confirm(command.confirmationPrompt())) { + logger.info("Operation cancelled."); + + return EXIT_CODE_OK; + } + } + + logger.info("Command [" + commandName + "] started"); + logger.info("Arguments: " + String.join(" ", rawArgs)); + logger.info(DELIM); + lastOperationRes = command.execute(clientCfg, logger); break; @@ -546,7 +551,7 @@ public class CommandHandler { private String readLine(String prompt) { System.out.print(prompt); - return IN.nextLine(); + return in.nextLine(); } /** @@ -554,11 +559,11 @@ public class CommandHandler { * * @return {@code true} if operation confirmed (or not needed), {@code false} otherwise. */ - private <T> boolean confirm(String str) { + private boolean confirm(String str) { if (str == null) return true; - String prompt = str + "\nPress '" + CONFIRM_MSG + "' to continue . . . "; + String prompt = str + lineSeparator() + "Press '" + CONFIRM_MSG + "' to continue . . . "; return CONFIRM_MSG.equalsIgnoreCase(readLine(prompt)); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/DeactivateCommand.java b/modules/core/src/main/java/org/apache/ignite/internal/commandline/DeactivateCommand.java index 37930da..b54fdeb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/commandline/DeactivateCommand.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/DeactivateCommand.java @@ -30,14 +30,24 @@ import static org.apache.ignite.internal.commandline.CommonArgParser.CMD_AUTO_CO * Command to deactivate cluster. */ public class DeactivateCommand implements Command<Void> { + /** Cluster name. */ + private String clusterName; + /** {@inheritDoc} */ @Override public void printUsage(Logger logger) { Command.usage(logger, "Deactivate cluster:", DEACTIVATE, optional(CMD_AUTO_CONFIRMATION)); } /** {@inheritDoc} */ + @Override public void prepareConfirmation(GridClientConfiguration clientCfg) throws Exception { + try (GridClient client = Command.startClient(clientCfg)) { + clusterName = client.state().clusterName(); + } + } + + /** {@inheritDoc} */ @Override public String confirmationPrompt() { - return "Warning: the command will deactivate a cluster."; + return "Warning: the command will deactivate a cluster \"" + clusterName + "\"."; } /** diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java index 69f8512..44a68af 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java @@ -68,6 +68,7 @@ import org.apache.ignite.spi.discovery.DiscoveryMetricsProvider; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; import org.jetbrains.annotations.Nullable; +import static org.apache.ignite.IgniteSystemProperties.IGNITE_CLUSTER_NAME; import static org.apache.ignite.IgniteSystemProperties.IGNITE_DIAGNOSTIC_ENABLED; import static org.apache.ignite.IgniteSystemProperties.IGNITE_UPDATE_NOTIFIER; import static org.apache.ignite.IgniteSystemProperties.getBoolean; @@ -539,6 +540,18 @@ public class ClusterProcessor extends GridProcessorAdapter { } /** + * Get cluster name. + * + * @return Cluster name. + * */ + public String clusterName() { + return IgniteSystemProperties.getString( + IGNITE_CLUSTER_NAME, + ctx.cache().utilityCache().context().dynamicDeploymentId().toString() + ); + } + + /** * Sends diagnostic message closure to remote node. When response received dumps remote message and local * communication info about connection(s) with remote node. * diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java index 7531917..102fefa 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java @@ -176,6 +176,9 @@ public enum GridRestCommand { /** */ CLUSTER_CURRENT_STATE("currentstate"), + /** Current cluster name. */ + CLUSTER_NAME("clustername"), + /** */ CLUSTER_CURRENT_READ_ONLY_MODE("currentreadonlymode"), diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java index 82faa86..76ac9fd 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java @@ -52,6 +52,7 @@ import org.apache.ignite.internal.processors.rest.handlers.cache.GridCacheComman import org.apache.ignite.internal.processors.rest.handlers.cluster.GridBaselineCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.cluster.GridChangeReadOnlyModeCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.cluster.GridChangeStateCommandHandler; +import org.apache.ignite.internal.processors.rest.handlers.cluster.GridClusterNameCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.memory.MemoryMetricsCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.datastructures.DataStructuresCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.log.GridLogCommandHandler; @@ -544,6 +545,7 @@ public class GridRestProcessor extends GridProcessorAdapter { addHandler(new GridLogCommandHandler(ctx)); addHandler(new GridChangeStateCommandHandler(ctx)); addHandler(new GridChangeReadOnlyModeCommandHandler(ctx)); + addHandler(new GridClusterNameCommandHandler(ctx)); addHandler(new AuthenticationCommandHandler(ctx)); addHandler(new UserActionCommandHandler(ctx)); addHandler(new GridBaselineCommandHandler(ctx)); @@ -933,6 +935,7 @@ public class GridRestProcessor extends GridProcessorAdapter { case NAME: case LOG: case CLUSTER_CURRENT_STATE: + case CLUSTER_NAME: case BASELINE_CURRENT_STATE: case AUTHENTICATE: case ADD_USER: diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/client/message/GridClientClusterNameRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/client/message/GridClientClusterNameRequest.java new file mode 100644 index 0000000..43fe1fb --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/client/message/GridClientClusterNameRequest.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.apache.ignite.internal.processors.rest.client.message; + +/** + * + */ +public class GridClientClusterNameRequest extends GridClientAbstractMessage { + /** */ + private static final long serialVersionUID = 0L; +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/GridRestCommandHandlerAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/GridRestCommandHandlerAdapter.java index 8d3fd1a..e1afe13 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/GridRestCommandHandlerAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/GridRestCommandHandlerAdapter.java @@ -19,6 +19,8 @@ package org.apache.ignite.internal.processors.rest.handlers; import org.apache.ignite.IgniteLogger; import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.util.typedef.X; +import org.apache.ignite.internal.util.typedef.internal.SB; /** * Abstract command handler. @@ -51,4 +53,21 @@ public abstract class GridRestCommandHandlerAdapter implements GridRestCommandHa protected static String missingParameter(String param) { return "Failed to find mandatory parameter in request: " + param; } + + /** + * Converts exception to string representation for error in response. + * + * @param e Exception. + * @return String representation of exception for error in response. + */ + protected static String errorMessage(Exception e) { + SB sb = new SB(); + + sb.a(e.getMessage()).a("\n").a("suppressed: \n"); + + for (Throwable t : X.getSuppressedList(e)) + sb.a(t.getMessage()).a("\n"); + + return sb.toString(); + } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cluster/GridChangeReadOnlyModeCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cluster/GridChangeReadOnlyModeCommandHandler.java index a220361..acc893e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cluster/GridChangeReadOnlyModeCommandHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cluster/GridChangeReadOnlyModeCommandHandler.java @@ -26,8 +26,6 @@ import org.apache.ignite.internal.processors.rest.handlers.GridRestCommandHandle import org.apache.ignite.internal.processors.rest.request.GridRestReadOnlyChangeModeRequest; import org.apache.ignite.internal.processors.rest.request.GridRestRequest; import org.apache.ignite.internal.util.future.GridFutureAdapter; -import org.apache.ignite.internal.util.typedef.X; -import org.apache.ignite.internal.util.typedef.internal.SB; import org.apache.ignite.internal.util.typedef.internal.U; import static org.apache.ignite.internal.processors.rest.GridRestCommand.CLUSTER_CURRENT_READ_ONLY_MODE; @@ -85,14 +83,7 @@ public class GridChangeReadOnlyModeCommandHandler extends GridRestCommandHandler fut.onDone(res); } catch (Exception e) { - SB sb = new SB(); - - sb.a(e.getMessage()).a("\n").a("suppressed: \n"); - - for (Throwable t : X.getSuppressedList(e)) - sb.a(t.getMessage()).a("\n"); - - res.setError(sb.toString()); + res.setError(errorMessage(e)); fut.onDone(res); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cluster/GridChangeStateCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cluster/GridChangeStateCommandHandler.java index c9b5a12..3bea4fd 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cluster/GridChangeStateCommandHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cluster/GridChangeStateCommandHandler.java @@ -26,8 +26,6 @@ import org.apache.ignite.internal.processors.rest.handlers.GridRestCommandHandle import org.apache.ignite.internal.processors.rest.request.GridRestChangeStateRequest; import org.apache.ignite.internal.processors.rest.request.GridRestRequest; import org.apache.ignite.internal.util.future.GridFutureAdapter; -import org.apache.ignite.internal.util.typedef.X; -import org.apache.ignite.internal.util.typedef.internal.SB; import org.apache.ignite.internal.util.typedef.internal.U; import static org.apache.ignite.internal.processors.rest.GridRestCommand.CLUSTER_ACTIVATE; @@ -84,14 +82,7 @@ public class GridChangeStateCommandHandler extends GridRestCommandHandlerAdapter fut.onDone(res); } catch (Exception e) { - SB sb = new SB(); - - sb.a(e.getMessage()).a("\n").a("suppressed: \n"); - - for (Throwable t : X.getSuppressedList(e)) - sb.a(t.getMessage()).a("\n"); - - res.setError(sb.toString()); + res.setError(errorMessage(e)); fut.onDone(res); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cluster/GridChangeReadOnlyModeCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cluster/GridClusterNameCommandHandler.java similarity index 57% copy from modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cluster/GridChangeReadOnlyModeCommandHandler.java copy to modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cluster/GridClusterNameCommandHandler.java index a220361..2eca474 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cluster/GridChangeReadOnlyModeCommandHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cluster/GridClusterNameCommandHandler.java @@ -23,29 +23,24 @@ import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.processors.rest.GridRestCommand; import org.apache.ignite.internal.processors.rest.GridRestResponse; import org.apache.ignite.internal.processors.rest.handlers.GridRestCommandHandlerAdapter; -import org.apache.ignite.internal.processors.rest.request.GridRestReadOnlyChangeModeRequest; +import org.apache.ignite.internal.processors.rest.request.GridRestClusterNameRequest; import org.apache.ignite.internal.processors.rest.request.GridRestRequest; import org.apache.ignite.internal.util.future.GridFutureAdapter; -import org.apache.ignite.internal.util.typedef.X; -import org.apache.ignite.internal.util.typedef.internal.SB; import org.apache.ignite.internal.util.typedef.internal.U; -import static org.apache.ignite.internal.processors.rest.GridRestCommand.CLUSTER_CURRENT_READ_ONLY_MODE; -import static org.apache.ignite.internal.processors.rest.GridRestCommand.CLUSTER_READ_ONLY_DISABLE; -import static org.apache.ignite.internal.processors.rest.GridRestCommand.CLUSTER_READ_ONLY_ENABLE; +import static org.apache.ignite.internal.processors.rest.GridRestCommand.CLUSTER_NAME; /** * */ -public class GridChangeReadOnlyModeCommandHandler extends GridRestCommandHandlerAdapter { +public class GridClusterNameCommandHandler extends GridRestCommandHandlerAdapter { /** Commands. */ - private static final Collection<GridRestCommand> COMMANDS = - U.sealList(CLUSTER_CURRENT_READ_ONLY_MODE, CLUSTER_READ_ONLY_DISABLE, CLUSTER_READ_ONLY_ENABLE); + private static final Collection<GridRestCommand> COMMANDS = U.sealList(CLUSTER_NAME); /** * @param ctx Context. */ - public GridChangeReadOnlyModeCommandHandler(GridKernalContext ctx) { + public GridClusterNameCommandHandler(GridKernalContext ctx) { super(ctx); } @@ -56,43 +51,19 @@ public class GridChangeReadOnlyModeCommandHandler extends GridRestCommandHandler /** {@inheritDoc} */ @Override public IgniteInternalFuture<GridRestResponse> handleAsync(GridRestRequest restReq) { - GridRestReadOnlyChangeModeRequest req = (GridRestReadOnlyChangeModeRequest)restReq; + assert restReq instanceof GridRestClusterNameRequest : restReq; final GridFutureAdapter<GridRestResponse> fut = new GridFutureAdapter<>(); final GridRestResponse res = new GridRestResponse(); try { - switch (req.command()) { - case CLUSTER_CURRENT_READ_ONLY_MODE: - res.setResponse(ctx.grid().cluster().readOnly()); - - break; - - default: - if (req.readOnly()) - U.log(log, "Received enable read-only mode request from client node with ID: " + req.clientId()); - else - U.log(log, "Received disable read-only mode request from client node with ID: " + req.clientId()); - - ctx.grid().cluster().readOnly(req.readOnly()); - - res.setResponse(req.command().key() + " done"); - - break; - } + res.setResponse(ctx.cluster().clusterName()); fut.onDone(res); } catch (Exception e) { - SB sb = new SB(); - - sb.a(e.getMessage()).a("\n").a("suppressed: \n"); - - for (Throwable t : X.getSuppressedList(e)) - sb.a(t.getMessage()).a("\n"); - - res.setError(sb.toString()); + res.setError(errorMessage(e)); fut.onDone(res); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestNioListener.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestNioListener.java index e6012e4..39caecb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestNioListener.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestNioListener.java @@ -35,6 +35,7 @@ import org.apache.ignite.internal.processors.rest.GridRestProtocolHandler; import org.apache.ignite.internal.processors.rest.GridRestResponse; import org.apache.ignite.internal.processors.rest.client.message.GridClientAuthenticationRequest; import org.apache.ignite.internal.processors.rest.client.message.GridClientCacheRequest; +import org.apache.ignite.internal.processors.rest.client.message.GridClientClusterNameRequest; import org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeRequest; import org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeResponse; import org.apache.ignite.internal.processors.rest.client.message.GridClientMessage; @@ -49,6 +50,7 @@ import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisM import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisNioListener; import org.apache.ignite.internal.processors.rest.request.GridRestCacheRequest; import org.apache.ignite.internal.processors.rest.request.GridRestChangeStateRequest; +import org.apache.ignite.internal.processors.rest.request.GridRestClusterNameRequest; import org.apache.ignite.internal.processors.rest.request.GridRestReadOnlyChangeModeRequest; import org.apache.ignite.internal.processors.rest.request.GridRestRequest; import org.apache.ignite.internal.processors.rest.request.GridRestTaskRequest; @@ -399,6 +401,8 @@ public class GridTcpRestNioListener extends GridNioServerListenerAdapter<GridCli restReq = restChangeReq; } + else if (msg instanceof GridClientClusterNameRequest) + restReq = new GridRestClusterNameRequest(); if (restReq != null) { restReq.destinationId(msg.destinationId()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestClusterNameRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestClusterNameRequest.java new file mode 100644 index 0000000..b45f4e4 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestClusterNameRequest.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.apache.ignite.internal.processors.rest.request; + +import org.apache.ignite.internal.processors.rest.GridRestCommand; +import org.apache.ignite.internal.util.typedef.internal.S; + +/** + * Grid command request of cluster name. + */ +public class GridRestClusterNameRequest extends GridRestRequest { + /** + * Constructor. + */ + public GridRestClusterNameRequest() { + command(GridRestCommand.CLUSTER_NAME); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridRestClusterNameRequest.class, this, super.toString()); + } +} diff --git a/modules/core/src/main/resources/META-INF/classnames.properties b/modules/core/src/main/resources/META-INF/classnames.properties index 9e58951..98cdc25 100644 --- a/modules/core/src/main/resources/META-INF/classnames.properties +++ b/modules/core/src/main/resources/META-INF/classnames.properties @@ -1652,6 +1652,7 @@ org.apache.ignite.internal.processors.rest.client.message.GridClientAuthenticati org.apache.ignite.internal.processors.rest.client.message.GridClientCacheBean org.apache.ignite.internal.processors.rest.client.message.GridClientCacheRequest org.apache.ignite.internal.processors.rest.client.message.GridClientCacheRequest$GridCacheOperation +org.apache.ignite.internal.processors.rest.client.message.GridClientClusterNameRequest org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeRequest org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeResponse org.apache.ignite.internal.processors.rest.client.message.GridClientMessage diff --git a/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerAbstractTest.java index 258964a..f1d7b7b 100644 --- a/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerAbstractTest.java +++ b/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerAbstractTest.java @@ -17,7 +17,9 @@ package org.apache.ignite.util; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.InputStream; import java.io.PrintStream; import java.nio.file.DirectoryStream; import java.nio.file.Path; @@ -55,6 +57,8 @@ import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.junit.ClassRule; import org.junit.rules.TestRule; +import static java.lang.String.join; +import static java.lang.System.lineSeparator; import static java.nio.file.Files.delete; import static java.nio.file.Files.newDirectoryStream; import static java.util.Arrays.asList; @@ -86,6 +90,9 @@ public abstract class GridCommandHandlerAbstractTest extends GridCommonAbstractT /** System out. */ protected static PrintStream sysOut; + /** System in. */ + private static InputStream sysIn; + /** * Test out - can be injected via {@link #injectTestSystemOut()} instead of System.out and analyzed in test. * Will be as well passed as a handler output for an anonymous logger in the test. @@ -101,12 +108,16 @@ public abstract class GridCommandHandlerAbstractTest extends GridCommonAbstractT /** Checkpoint frequency. */ protected long checkpointFreq = DFLT_CHECKPOINT_FREQ; + /** Enable automatic confirmation to avoid user interaction. */ + protected boolean autoConfirmation = true; + /** {@inheritDoc} */ @Override protected void beforeTestsStarted() throws Exception { super.beforeTestsStarted(); testOut = new ByteArrayOutputStream(16 * 1024); sysOut = System.out; + sysIn = System.in; } /** {@inheritDoc} */ @@ -124,6 +135,7 @@ public abstract class GridCommandHandlerAbstractTest extends GridCommonAbstractT log.info("----------------------------------------"); System.setOut(sysOut); + System.setIn(sysIn); log.info(testOut.toString()); @@ -248,8 +260,8 @@ public abstract class GridCommandHandlerAbstractTest extends GridCommonAbstractT * @param args Incoming arguments; */ protected void addExtraArguments(List<String> args) { - // Add force to avoid interactive confirmation. - args.add(CMD_AUTO_CONFIRMATION); + if (autoConfirmation) + args.add(CMD_AUTO_CONFIRMATION); } /** */ @@ -258,6 +270,18 @@ public abstract class GridCommandHandlerAbstractTest extends GridCommonAbstractT } /** + * Emulates user input. + * + * @param inputStrings User input strings. + * */ + protected void injectTestSystemIn(String... inputStrings) { + assert nonNull(inputStrings); + + String inputStr = join(lineSeparator(), inputStrings); + System.setIn(new ByteArrayInputStream(inputStr.getBytes())); + } + + /** * Checks if all non-system txs and non-system mvcc futures are finished. */ protected void checkUserFutures() { diff --git a/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java b/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java index 8317560..95a0296 100644 --- a/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java +++ b/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java @@ -90,6 +90,7 @@ import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.testframework.GridTestUtils; +import org.apache.ignite.testframework.junits.WithSystemProperty; import org.apache.ignite.transactions.Transaction; import org.apache.ignite.transactions.TransactionRollbackException; import org.apache.ignite.transactions.TransactionTimeoutException; @@ -97,13 +98,16 @@ import org.jetbrains.annotations.NotNull; import org.junit.Test; import static java.io.File.separatorChar; +import static org.apache.ignite.IgniteSystemProperties.IGNITE_CLUSTER_NAME; import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL; import static org.apache.ignite.cache.CacheMode.PARTITIONED; import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; import static org.apache.ignite.cache.PartitionLossPolicy.READ_ONLY_SAFE; +import static org.apache.ignite.internal.commandline.CommandHandler.CONFIRM_MSG; import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_INVALID_ARGUMENTS; import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_OK; import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_UNEXPECTED_ERROR; +import static org.apache.ignite.internal.commandline.CommandList.DEACTIVATE; import static org.apache.ignite.internal.processors.diagnostic.DiagnosticProcessor.DEFAULT_TARGET_FOLDER; import static org.apache.ignite.testframework.GridTestUtils.assertContains; import static org.apache.ignite.testframework.GridTestUtils.waitForCondition; @@ -218,6 +222,80 @@ public class GridCommandHandlerTest extends GridCommandHandlerClusterPerMethodAb } /** + * Test the deactivation command on the active and no cluster with checking + * the cluster name(which is set through the system property) in + * confirmation. + * + * @throws Exception If failed. + * */ + @Test + @WithSystemProperty(key = IGNITE_CLUSTER_NAME, value = "TEST_CLUSTER_NAME") + public void testDeactivateWithCheckClusterNameInConfirmationBySystemProperty() throws Exception { + IgniteEx igniteEx = startGrid(0); + assertFalse(igniteEx.cluster().active()); + + deactivateActiveOrNotClusterWithCheckClusterNameInConfirmation(igniteEx, "TEST_CLUSTER_NAME"); + } + + /** + * Test the deactivation command on the active and no cluster with checking + * the cluster name(default) in confirmation. + * + * @throws Exception If failed. + * */ + @Test + public void testDeactivateWithCheckClusterNameInConfirmationByDefault() throws Exception { + IgniteEx igniteEx = startGrid(0); + assertFalse(igniteEx.cluster().active()); + + deactivateActiveOrNotClusterWithCheckClusterNameInConfirmation( + igniteEx, + igniteEx.context().cache().utilityCache().context().dynamicDeploymentId().toString() + ); + } + + /** + * Deactivating the cluster(active and not) with checking the cluster name + * in the confirmation. + * + * @param igniteEx Node. + * @param clusterName Cluster name to check in the confirmation message. + * */ + private void deactivateActiveOrNotClusterWithCheckClusterNameInConfirmation( + IgniteEx igniteEx, + String clusterName + ) { + deactivateWithCheckClusterNameInConfirmation(igniteEx, clusterName); + + igniteEx.cluster().active(true); + assertTrue(igniteEx.cluster().active()); + + deactivateWithCheckClusterNameInConfirmation(igniteEx, clusterName); + } + + /** + * Deactivating the cluster with checking the cluster name in the + * confirmation. + * + * @param igniteEx Node. + * @param clusterName Cluster name to check in the confirmation message. + * */ + private void deactivateWithCheckClusterNameInConfirmation(IgniteEx igniteEx, String clusterName) { + autoConfirmation = false; + injectTestSystemOut(); + injectTestSystemIn(CONFIRM_MSG); + + assertEquals(EXIT_CODE_OK, execute(DEACTIVATE.text())); + assertFalse(igniteEx.cluster().active()); + + assertContains( + log, + testOut.toString(), + "Warning: the command will deactivate a cluster \"" + clusterName + "\"." + ); + } + + /** * Test cluster active state works via control.sh * * @throws Exception If failed. diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java index f36bdb6..ef9c99f 100644 --- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java +++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java @@ -54,6 +54,7 @@ import org.apache.ignite.internal.processors.rest.request.DataStructuresRequest; import org.apache.ignite.internal.processors.rest.request.GridRestBaselineRequest; import org.apache.ignite.internal.processors.rest.request.GridRestCacheRequest; import org.apache.ignite.internal.processors.rest.request.GridRestChangeStateRequest; +import org.apache.ignite.internal.processors.rest.request.GridRestClusterNameRequest; import org.apache.ignite.internal.processors.rest.request.GridRestLogRequest; import org.apache.ignite.internal.processors.rest.request.GridRestRequest; import org.apache.ignite.internal.processors.rest.request.GridRestTaskRequest; @@ -763,6 +764,12 @@ public class GridJettyRestHandler extends AbstractHandler { break; } + case CLUSTER_NAME: { + restReq = new GridRestClusterNameRequest(); + + break; + } + case BASELINE_CURRENT_STATE: case BASELINE_SET: case BASELINE_ADD: