You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2020/09/10 15:25:41 UTC
[ignite] branch master updated: IGNITE-13362 Add warmup stop
command to control.sh - Fixes #8201.
This is an automated email from the ASF dual-hosted git repository.
agoncharuk 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 0260ba0 IGNITE-13362 Add warmup stop command to control.sh - Fixes #8201.
0260ba0 is described below
commit 0260ba0c8fa3be6ddce9efc473f45b13d11f7784
Author: ktkalenko <kt...@gridgain.com>
AuthorDate: Thu Sep 10 17:51:29 2020 +0300
IGNITE-13362 Add warmup stop command to control.sh - Fixes #8201.
Signed-off-by: Alexey Goncharuk <al...@gmail.com>
---
.../ignite/internal/commandline/Command.java | 31 ++++
.../ignite/internal/commandline/CommandList.java | 5 +-
.../ignite/internal/commandline/WarmUpCommand.java | 121 +++++++++++++
.../commandline/CommandHandlerParsingTest.java | 36 +++-
.../apache/ignite/util/GridCommandHandlerTest.java | 58 +++++++
.../internal/client/GridClientBeforeNodeStart.java | 66 +++++++
.../ignite/internal/client/GridClientFactory.java | 33 +++-
.../client/GridClientNodeStateBeforeStart.java} | 16 +-
.../internal/client/impl/GridClientImpl.java | 190 +++++++++++++++------
.../impl/GridClientNodeStateBeforeStartImpl.java | 49 ++++++
.../impl/connection/GridClientConnection.java | 9 +
.../connection/GridClientConnectionManager.java | 12 ++
.../GridClientConnectionManagerAdapter.java | 156 +++++++++++------
.../GridClientConnectionManagerOsImpl.java | 7 +-
.../connection/GridClientNioTcpConnection.java | 8 +
.../client/router/impl/GridRouterClientImpl.java | 2 +-
.../internal/processors/rest/GridRestCommand.java | 8 +-
.../processors/rest/GridRestProcessor.java | 11 +-
.../internal/processors/rest/GridRestProtocol.java | 5 +
.../GridClientNodeStateBeforeStartRequest.java} | 16 +-
.../client/message/GridClientWarmUpRequest.java | 90 ++++++++++
.../NodeStateBeforeStartCommandHandler.java | 75 ++++++++
.../rest/protocols/GridRestProtocolAdapter.java | 5 +
.../rest/protocols/tcp/GridTcpRestNioListener.java | 22 +++
.../rest/protocols/tcp/GridTcpRestProtocol.java | 6 +-
.../GridRestNodeStateBeforeStartRequest.java} | 13 +-
.../rest/request/GridRestWarmUpRequest.java | 54 ++++++
.../main/resources/META-INF/classnames.properties | 2 +
.../cache/warmup/BlockedWarmUpConfiguration.java | 4 +-
...ockedWarmUp.java => BlockedWarmUpStrategy.java} | 6 +-
.../SimpleObservableWarmUpConfiguration.java | 2 +-
...Up.java => SimpleObservableWarmUpStrategy.java} | 2 +-
.../processors/cache/warmup/WarmUpSelfTest.java | 10 +-
.../cache/warmup/WarmUpTestPluginProvider.java | 8 +-
...ridCommandHandlerClusterByClassTest_help.output | 3 +
...andHandlerClusterByClassWithSSLTest_help.output | 3 +
.../Cache/PartitionLossTest.cs | 12 +-
37 files changed, 1003 insertions(+), 153 deletions(-)
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/Command.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/Command.java
index b147933..5b00a78 100644
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/Command.java
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/Command.java
@@ -22,6 +22,7 @@ import java.util.Map;
import java.util.logging.Logger;
import org.apache.ignite.IgniteSystemProperties;
import org.apache.ignite.internal.client.GridClient;
+import org.apache.ignite.internal.client.GridClientBeforeNodeStart;
import org.apache.ignite.internal.client.GridClientConfiguration;
import org.apache.ignite.internal.client.GridClientException;
import org.apache.ignite.internal.client.GridClientFactory;
@@ -69,6 +70,36 @@ public interface Command<T> {
}
/**
+ * Method to create thin client for communication with node before it starts.
+ * If node has already started, there will be an error.
+ *
+ * @param clientCfg Thin client configuration.
+ * @return Grid thin client instance which is already connected to node before it starts.
+ * @throws Exception If error occur.
+ */
+ public static GridClientBeforeNodeStart startClientBeforeNodeStart(
+ GridClientConfiguration clientCfg
+ ) throws Exception {
+ GridClientBeforeNodeStart client = GridClientFactory.startBeforeNodeStart(clientCfg);
+
+ // If connection is unsuccessful, fail before doing any operations:
+ if (!client.connected()) {
+ GridClientException lastErr = client.checkLastError();
+
+ try {
+ client.close();
+ }
+ catch (Throwable e) {
+ lastErr.addSuppressed(e);
+ }
+
+ throw lastErr;
+ }
+
+ return client;
+ }
+
+ /**
* Print command usage.
*
* @param logger Logger to use.
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java
index 1e3df5d..4190604 100644
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java
@@ -74,7 +74,10 @@ public enum CommandList {
SHUTDOWN_POLICY("--shutdown-policy", new ShutdownPolicyCommand()),
/** */
- TRACING_CONFIGURATION("--tracing-configuration", new TracingConfigurationCommand());
+ TRACING_CONFIGURATION("--tracing-configuration", new TracingConfigurationCommand()),
+
+ /** Warm-up command. */
+ WARM_UP("--warm-up", new WarmUpCommand());
/** Private values copy so there's no need in cloning it every time. */
private static final CommandList[] VALUES = CommandList.values();
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/WarmUpCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/WarmUpCommand.java
new file mode 100644
index 0000000..1d69f09
--- /dev/null
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/WarmUpCommand.java
@@ -0,0 +1,121 @@
+/*
+ * 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.commandline;
+
+import java.util.logging.Logger;
+import org.apache.ignite.internal.client.GridClientBeforeNodeStart;
+import org.apache.ignite.internal.client.GridClientConfiguration;
+import org.apache.ignite.internal.client.GridClientDisconnectedException;
+import org.apache.ignite.internal.client.GridClientException;
+import org.apache.ignite.internal.commandline.argument.CommandArg;
+import org.apache.ignite.internal.commandline.argument.CommandArgUtils;
+
+import static java.util.Objects.isNull;
+import static java.util.Objects.nonNull;
+import static org.apache.ignite.internal.commandline.CommandList.WARM_UP;
+
+/**
+ * Command for interacting with warm-up.
+ */
+public class WarmUpCommand implements Command<Void> {
+ /** {@inheritDoc} */
+ @Override public void printUsage(Logger logger) {
+ Command.usage(logger, "Stop warm-up:", WARM_UP, WarmUpCommandArg.STOP.argName());
+ }
+
+ /** {@inheritDoc} */
+ @Override public String name() {
+ return CommandList.WARM_UP.toCommandName();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Void arg() {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void parseArguments(CommandArgIterator argIter) {
+ boolean stop = false;
+
+ while (nonNull(argIter.peekNextArg())) {
+ WarmUpCommandArg arg = CommandArgUtils.of(argIter.nextArg(""), WarmUpCommandArg.class);
+
+ if (isNull(arg))
+ break;
+
+ switch (arg) {
+ case STOP:
+ stop = true;
+ break;
+
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ if (!stop)
+ throw new IllegalArgumentException(WarmUpCommandArg.STOP.argName() + " argument is missing.");
+ }
+
+ /** {@inheritDoc} */
+ @Override public String confirmationPrompt() {
+ return "Warning: command will stop warm-up.";
+ }
+
+ /** {@inheritDoc} */
+ @Override public Object execute(GridClientConfiguration clientCfg, Logger log) throws Exception {
+ try (GridClientBeforeNodeStart client = Command.startClientBeforeNodeStart(clientCfg)) {
+ client.beforeStartState().stopWarmUp();
+ }
+ catch (GridClientDisconnectedException e) {
+ throw new GridClientException(e.getCause());
+ }
+
+ return true;
+ }
+
+ /**
+ * Warm-up command arguments name.
+ */
+ private enum WarmUpCommandArg implements CommandArg {
+ /** Stop warm-up argument. */
+ STOP("--stop");
+
+ /** Option name. */
+ private final String name;
+
+ /**
+ * Constructor.
+ *
+ * @param name Argument name.
+ */
+ WarmUpCommandArg(String name) {
+ this.name = name;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String argName() {
+ return name;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return name;
+ }
+ }
+}
diff --git a/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java b/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java
index f3705df..a9ae762 100644
--- a/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java
+++ b/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java
@@ -57,6 +57,7 @@ import static org.apache.ignite.internal.commandline.CommandList.CLUSTER_CHANGE_
import static org.apache.ignite.internal.commandline.CommandList.SET_STATE;
import static org.apache.ignite.internal.commandline.CommandList.SHUTDOWN_POLICY;
import static org.apache.ignite.internal.commandline.CommandList.WAL;
+import static org.apache.ignite.internal.commandline.CommandList.WARM_UP;
import static org.apache.ignite.internal.commandline.CommonArgParser.CMD_VERBOSE;
import static org.apache.ignite.internal.commandline.TaskExecutor.DFLT_HOST;
import static org.apache.ignite.internal.commandline.TaskExecutor.DFLT_PORT;
@@ -70,6 +71,7 @@ import static org.apache.ignite.testframework.GridTestUtils.assertThrows;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
@@ -378,6 +380,8 @@ public class CommandHandlerParsingTest {
args = parseArgs(asList(cmdL.text(), "ACTIVE"));
else if (cmdL == CLUSTER_CHANGE_TAG)
args = parseArgs(asList(cmdL.text(), "newTagValue"));
+ else if (cmdL == WARM_UP)
+ args = parseArgs(asList(cmdL.text(), "--stop"));
else
args = parseArgs(asList(cmdL.text()));
@@ -455,6 +459,12 @@ public class CommandHandlerParsingTest {
break;
}
+ case WARM_UP: {
+ args = parseArgs(asList(cmdL.text(), "--stop", "--yes"));
+
+ break;
+ }
+
default:
fail("Unknown command: " + cmd);
}
@@ -937,6 +947,29 @@ public class CommandHandlerParsingTest {
}
/**
+ * Test verifies correctness of parsing of arguments --warm-up command.
+ */
+ @Test
+ public void testWarmUpArgs() {
+ String[][] args = {
+ {"--warm-up"},
+ {"--warm-up", "1"},
+ {"--warm-up", "stop"}
+ };
+
+ for (String[] arg : args) {
+ GridTestUtils.assertThrows(
+ null,
+ () -> parseArgs(asList(arg)),
+ IllegalArgumentException.class,
+ "--stop argument is missing."
+ );
+ }
+
+ assertNotNull(parseArgs(asList("--warm-up", "--stop")));
+ }
+
+ /**
* @param args Raw arg list.
* @return Common parameters container object.
*/
@@ -994,6 +1027,7 @@ public class CommandHandlerParsingTest {
cmd == CommandList.KILL ||
cmd == CommandList.SNAPSHOT ||
cmd == CommandList.CLUSTER_CHANGE_TAG ||
- cmd == CommandList.METADATA;
+ cmd == CommandList.METADATA ||
+ cmd == CommandList.WARM_UP;
}
}
diff --git a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java
index 62a7f17..fcacd9b 100644
--- a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java
+++ b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java
@@ -35,6 +35,7 @@ import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
@@ -89,6 +90,9 @@ import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.transactions.TransactionProxyImpl;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
+import org.apache.ignite.internal.processors.cache.warmup.BlockedWarmUpConfiguration;
+import org.apache.ignite.internal.processors.cache.warmup.BlockedWarmUpStrategy;
+import org.apache.ignite.internal.processors.cache.warmup.WarmUpTestPluginProvider;
import org.apache.ignite.internal.processors.cluster.GridClusterStateProcessor;
import org.apache.ignite.internal.util.lang.GridAbsPredicate;
import org.apache.ignite.internal.util.typedef.G;
@@ -2330,6 +2334,60 @@ public class GridCommandHandlerTest extends GridCommandHandlerClusterPerMethodAb
}
/**
+ * Verification of successful warm-up stop.
+ * <p/>
+ * Steps:
+ * 1)Starting node with warm-up;
+ * 2)Stop warm-up;
+ * 3)Waiting for a successful stop of warm-up and start of node.
+ *
+ * @throws Exception If failed.
+ */
+ @Test
+ public void testSuccessStopWarmUp() throws Exception {
+ WarmUpTestPluginProvider provider = new WarmUpTestPluginProvider();
+
+ IgniteConfiguration cfg = getConfiguration(getTestIgniteInstanceName(0)).setPluginProviders(provider);
+ cfg.getDataStorageConfiguration().setDefaultWarmUpConfiguration(new BlockedWarmUpConfiguration());
+
+ cfg.getConnectorConfiguration().setHost("localhost");
+
+ IgniteInternalFuture<IgniteEx> fut = runAsync(() -> startGrid(cfg));
+
+ BlockedWarmUpStrategy blockedWarmUpStgy = (BlockedWarmUpStrategy)provider.strats.get(1);
+
+ try {
+ U.await(blockedWarmUpStgy.startLatch, 60, TimeUnit.SECONDS);
+
+ assertEquals(EXIT_CODE_OK, execute("--warm-up", "--stop", "--yes"));
+
+ fut.get(60_000);
+ }
+ catch (Throwable t) {
+ blockedWarmUpStgy.stopLatch.countDown();
+
+ throw t;
+ }
+ }
+
+ /**
+ * Check that command will not be executed because node has already started.
+ * <p/>
+ * Steps:
+ * 1)Starting node;
+ * 2)Attempt to stop warm-up;
+ * 3)Waiting for an error because node has already started.
+ *
+ * @throws Exception If failed.
+ */
+ @Test
+ public void testFailStopWarmUp() throws Exception {
+ startGrid(0);
+
+ assertEquals(EXIT_CODE_UNEXPECTED_ERROR, execute("--warm-up", "--stop", "--yes"));
+ }
+
+ /**
* @param ignite Ignite to execute task on.
* @param delFoundGarbage If clearing mode should be used.
* @return Result of task run.
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/GridClientBeforeNodeStart.java b/modules/core/src/main/java/org/apache/ignite/internal/client/GridClientBeforeNodeStart.java
new file mode 100644
index 0000000..d8cc76b
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/GridClientBeforeNodeStart.java
@@ -0,0 +1,66 @@
+/*
+ * 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.client;
+
+import java.util.UUID;
+
+/**
+ * Ignite Java client API for communicate with node before it start.
+ * If node has already started, then there will be errors.
+ * For get an instance, need to use {@link GridClientFactory#startBeforeNodeStart}.
+ */
+public interface GridClientBeforeNodeStart extends AutoCloseable {
+ /**
+ * Gets a unique client identifier. This identifier is generated by factory on client creation
+ * and used in identification and authentication procedure on server node.
+ *
+ * @return Generated client id.
+ */
+ public UUID id();
+
+ /**
+ * Indicates whether client is connected to remote Grid.
+ * In other words it allow to determine if client is able to communicate
+ * with Grid right now. It can be used only fo diagnostic and monitoring purposes.
+ *
+ * @return Whether client is connected to remote Grid.
+ */
+ public boolean connected();
+
+ /**
+ * Closes client instance. This method is identical to
+ * {@link GridClientFactory#stop(UUID) GridClientFactory.stop(clientId)}.
+ */
+ @Override public void close();
+
+ /**
+ * Checking for an error.
+ *
+ * @return {@code Exception} if client was not connected.
+ */
+ public GridClientException checkLastError();
+
+ /**
+ * Getting a client projection of node state before its start.
+ *
+ * @return Projection of node state before its start.
+ *
+ * @see GridClientNodeStateBeforeStart
+ */
+ public GridClientNodeStateBeforeStart beforeStartState();
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/GridClientFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/client/GridClientFactory.java
index 00d9308..d40b466 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/GridClientFactory.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/GridClientFactory.java
@@ -32,7 +32,7 @@ public class GridClientFactory {
private static ConcurrentMap<UUID, GridClientImpl> openClients = new ConcurrentHashMap<>();
/** Lock to prevent concurrent adding of clients while stopAll is working. */
- private static ReadWriteLock busyLock = new ReentrantReadWriteLock();
+ private static final ReadWriteLock busyLock = new ReentrantReadWriteLock();
/**
* Ensure singleton.
@@ -50,12 +50,41 @@ public class GridClientFactory {
* @throws GridClientException If client could not be created.
*/
public static GridClient start(GridClientConfiguration cfg) throws GridClientException {
+ return start(cfg, false);
+ }
+
+ /**
+ * Starts a client before node start with given configuration.
+ * If node has already started, there will be an error.
+ *
+ * @param cfg Client configuration.
+ * @return Started client.
+ * @throws GridClientException If client could not be created.
+ */
+ public static GridClientBeforeNodeStart startBeforeNodeStart(
+ GridClientConfiguration cfg
+ ) throws GridClientException {
+ return start(cfg, true);
+ }
+
+ /**
+ * Starts a client with given configuration.
+ *
+ * @param cfg Client configuration.
+ * @param beforeNodeStart Before node start.
+ * @return Started client.
+ * @throws GridClientException If client could not be created.
+ */
+ private static GridClientImpl start(
+ GridClientConfiguration cfg,
+ boolean beforeNodeStart
+ ) throws GridClientException {
busyLock.readLock().lock();
try {
UUID clientId = UUID.randomUUID();
- GridClientImpl client = new GridClientImpl(clientId, cfg, false);
+ GridClientImpl client = new GridClientImpl(clientId, cfg, false, beforeNodeStart);
GridClientImpl old = openClients.putIfAbsent(clientId, client);
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUpConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/client/GridClientNodeStateBeforeStart.java
similarity index 67%
copy from modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUpConfiguration.java
copy to modules/core/src/main/java/org/apache/ignite/internal/client/GridClientNodeStateBeforeStart.java
index d050133..7eec8ad 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUpConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/GridClientNodeStateBeforeStart.java
@@ -15,13 +15,17 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.processors.cache.warmup;
-
-import org.apache.ignite.configuration.WarmUpConfiguration;
+package org.apache.ignite.internal.client;
/**
- * Configuration for {@link SimpleObservableWarmUp}.
+ * Interface for managing state of a node before it starts and getting information about it.
+ * An exception will be thrown if node has already started.
*/
-class SimpleObservableWarmUpConfiguration implements WarmUpConfiguration {
- // No-op.
+public interface GridClientNodeStateBeforeStart {
+ /**
+ * Stop warm-up.
+ *
+ * @throws GridClientException In case of error.
+ */
+ void stopWarmUp() throws GridClientException;
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/GridClientImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/GridClientImpl.java
index fb2546b..c52241c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/GridClientImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/GridClientImpl.java
@@ -34,8 +34,10 @@ import java.util.logging.Logger;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
import org.apache.ignite.IgniteSystemProperties;
import org.apache.ignite.internal.client.GridClient;
+import org.apache.ignite.internal.client.GridClientBeforeNodeStart;
import org.apache.ignite.internal.client.GridClientCacheMode;
import org.apache.ignite.internal.client.GridClientClosedException;
import org.apache.ignite.internal.client.GridClientClusterState;
@@ -48,12 +50,14 @@ import org.apache.ignite.internal.client.GridClientDisconnectedException;
import org.apache.ignite.internal.client.GridClientException;
import org.apache.ignite.internal.client.GridClientFactory;
import org.apache.ignite.internal.client.GridClientNode;
+import org.apache.ignite.internal.client.GridClientNodeStateBeforeStart;
import org.apache.ignite.internal.client.GridClientPartitionAffinity;
import org.apache.ignite.internal.client.GridClientPredicate;
import org.apache.ignite.internal.client.GridClientTopologyListener;
import org.apache.ignite.internal.client.GridServerUnreachableException;
import org.apache.ignite.internal.client.balancer.GridClientLoadBalancer;
import org.apache.ignite.internal.client.balancer.GridClientRandomBalancer;
+import org.apache.ignite.internal.client.impl.connection.GridClientConnection;
import org.apache.ignite.internal.client.impl.connection.GridClientConnectionManager;
import org.apache.ignite.internal.client.impl.connection.GridClientConnectionManagerOsImpl;
import org.apache.ignite.internal.client.impl.connection.GridClientTopology;
@@ -68,7 +72,7 @@ import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_MACS;
/**
* Client implementation.
*/
-public class GridClientImpl implements GridClient {
+public class GridClientImpl implements GridClient, GridClientBeforeNodeStart {
/** Null mask object. */
private static final Object NULL_MASK = new Object();
@@ -99,28 +103,28 @@ public class GridClientImpl implements GridClient {
protected final GridClientConfiguration cfg;
/** SSL context if ssl enabled. */
- private SSLContext sslCtx;
+ private final SSLContext sslCtx;
/** Main compute projection. */
- private final GridClientComputeImpl compute;
+ @Nullable private final GridClientComputeImpl compute;
/** Cluster state projection. */
- private final GridClientClusterStateImpl clusterState;
+ @Nullable private final GridClientClusterStateImpl clusterState;
/** Data projections. */
- private ConcurrentMap<Object, GridClientDataImpl> dataMap = new ConcurrentHashMap<>();
+ private final ConcurrentMap<Object, GridClientDataImpl> dataMap = new ConcurrentHashMap<>();
/** Topology. */
- protected GridClientTopology top;
+ protected final GridClientTopology top;
/** Topology updater thread. */
- private final Thread topUpdateThread;
+ @Nullable private final Thread topUpdateThread;
/** Closed flag. */
- private AtomicBoolean closed = new AtomicBoolean();
+ private final AtomicBoolean closed = new AtomicBoolean();
/** Connection manager. */
- protected GridClientConnectionManager connMgr;
+ protected final GridClientConnectionManager connMgr;
/** Routers. */
private final Collection<InetSocketAddress> routers;
@@ -128,18 +132,29 @@ public class GridClientImpl implements GridClient {
/** Servers. */
private final Collection<InetSocketAddress> srvs;
+ /** Projection of node state before its start. */
+ @Nullable private final GridClientNodeStateBeforeStart beforeStartState;
+
/**
* Creates a new client based on a given configuration.
+ * <p/>
+ * If {@code beforeNodeStart == true}, topology will not be received/updated,
+ * and there will also be errors when trying to work with topology, compute, state and cache.
*
* @param id Client identifier.
* @param cfg0 Client configuration.
* @param routerClient Router client flag.
+ * @param beforeNodeStart Connecting to a node before it start.
* @throws GridClientException If client configuration is incorrect.
- * @throws GridServerUnreachableException If none of the servers specified in configuration can
- * be reached.
+ * @throws GridServerUnreachableException If none of the servers specified in configuration can be reached.
*/
@SuppressWarnings("CallToThreadStartDuringObjectConstruction")
- public GridClientImpl(UUID id, GridClientConfiguration cfg0, boolean routerClient) throws GridClientException {
+ public GridClientImpl(
+ UUID id,
+ GridClientConfiguration cfg0,
+ boolean routerClient,
+ boolean beforeNodeStart
+ ) throws GridClientException {
this.id = id;
cfg = new GridClientConfiguration(cfg0);
@@ -149,14 +164,16 @@ public class GridClientImpl implements GridClient {
try {
top = new GridClientTopology(cfg);
- for (GridClientDataConfiguration dataCfg : cfg.getDataConfigurations()) {
- GridClientDataAffinity aff = dataCfg.getAffinity();
+ if (!beforeNodeStart) {
+ for (GridClientDataConfiguration dataCfg : cfg.getDataConfigurations()) {
+ GridClientDataAffinity aff = dataCfg.getAffinity();
- if (aff instanceof GridClientTopologyListener)
- addTopologyListener((GridClientTopologyListener)aff);
+ if (aff instanceof GridClientTopologyListener)
+ addTopologyListener((GridClientTopologyListener)aff);
+ }
}
- if (cfg.getBalancer() instanceof GridClientTopologyListener)
+ if (!beforeNodeStart && cfg.getBalancer() instanceof GridClientTopologyListener)
top.addTopologyListener((GridClientTopologyListener)cfg.getBalancer());
GridSslContextFactory factory = cfg.getSslContextFactory();
@@ -170,6 +187,8 @@ public class GridClientImpl implements GridClient {
"check ssl context factory configuration): " + e.getMessage(), e);
}
}
+ else
+ sslCtx = null;
if (cfg.isAutoFetchMetrics() && !cfg.isEnableMetricsCache())
log.warning("Auto-fetch for metrics is enabled without enabling caching for them.");
@@ -189,11 +208,11 @@ public class GridClientImpl implements GridClient {
throw new GridClientException("Servers addresses and routers addresses cannot both be provided " +
"for client (please fix configuration and restart): " + this);
- connMgr = createConnectionManager(id, sslCtx, cfg, routers, top, null, routerClient);
+ connMgr = createConnectionManager(id, sslCtx, cfg, routers, top, null, routerClient, beforeNodeStart);
try {
- // Init connection manager, it should cause topology update.
- tryInitTopology();
+ // Init connection manager.
+ tryInit();
}
catch (GridClientException e) {
top.fail(e);
@@ -206,15 +225,28 @@ public class GridClientImpl implements GridClient {
throw new GridClientException("Client startup was interrupted.", e);
}
- topUpdateThread = new TopologyUpdaterThread();
+ if (!beforeNodeStart) {
+ beforeStartState = null;
- topUpdateThread.setDaemon(true);
+ topUpdateThread = new TopologyUpdaterThread();
- topUpdateThread.start();
+ topUpdateThread.setDaemon(true);
+
+ topUpdateThread.start();
+
+ compute = new GridClientComputeImpl(this, null, null, cfg.getBalancer());
+
+ clusterState = new GridClientClusterStateImpl(this, null, null, cfg.getBalancer());
+ }
+ else {
+ topUpdateThread = null;
- compute = new GridClientComputeImpl(this, null, null, cfg.getBalancer());
+ compute = null;
- clusterState = new GridClientClusterStateImpl(this, null, null, cfg.getBalancer());
+ clusterState = null;
+
+ beforeStartState = new GridClientNodeStateBeforeStartImpl(this);
+ }
if (log.isLoggable(Level.INFO))
log.info("Client started [id=" + id + ", protocol=" + cfg.getProtocol() + ']');
@@ -265,6 +297,8 @@ public class GridClientImpl implements GridClient {
@Override public GridClientData data(@Nullable final String cacheName) throws GridClientException {
checkClosed();
+ checkBeforeNodeStartMode();
+
Object key = maskNull(cacheName);
GridClientDataImpl data = dataMap.get(key);
@@ -303,26 +337,36 @@ public class GridClientImpl implements GridClient {
/** {@inheritDoc} */
@Override public GridClientCompute compute() {
+ checkBeforeNodeStartMode();
+
return compute;
}
/** {@inheritDoc} */
@Override public GridClientClusterState state() {
+ checkBeforeNodeStartMode();
+
return clusterState;
}
/** {@inheritDoc} */
@Override public void addTopologyListener(GridClientTopologyListener lsnr) {
+ checkBeforeNodeStartMode();
+
top.addTopologyListener(lsnr);
}
/** {@inheritDoc} */
@Override public void removeTopologyListener(GridClientTopologyListener lsnr) {
+ checkBeforeNodeStartMode();
+
top.removeTopologyListener(lsnr);
}
/** {@inheritDoc} */
@Override public Collection<GridClientTopologyListener> topologyListeners() {
+ checkBeforeNodeStartMode();
+
return top.topologyListeners();
}
@@ -342,6 +386,8 @@ public class GridClientImpl implements GridClient {
* @return Topology instance.
*/
public GridClientTopology topology() {
+ checkBeforeNodeStartMode();
+
return top;
}
@@ -350,6 +396,11 @@ public class GridClientImpl implements GridClient {
return top.lastError();
}
+ /** {@inheritDoc} */
+ @Override @Nullable public GridClientNodeStateBeforeStart beforeStartState() {
+ return beforeStartState;
+ }
+
/**
* @return Connection manager.
*/
@@ -382,6 +433,16 @@ public class GridClientImpl implements GridClient {
}
/**
+ * Checks and throws an exception if mode is "before node start".
+ *
+ * @throws IgniteException If mode is "before node start".
+ */
+ private void checkBeforeNodeStartMode() throws IgniteException {
+ if (beforeStartState != null)
+ throw new IgniteException("It is possible to work with a node only before it starts.");
+ }
+
+ /**
* Masks null cache name with unique object.
*
* @param cacheName Name to be masked.
@@ -423,9 +484,11 @@ public class GridClientImpl implements GridClient {
* @return New connection manager based on current client settings.
* @throws GridClientException If failed to start connection server.
*/
- public GridClientConnectionManager newConnectionManager(@Nullable Byte marshId, boolean routerClient)
- throws GridClientException {
- return createConnectionManager(id, sslCtx, cfg, routers, top, marshId, routerClient);
+ public GridClientConnectionManager newConnectionManager(
+ @Nullable Byte marshId,
+ boolean routerClient
+ ) throws GridClientException {
+ return createConnectionManager(id, sslCtx, cfg, routers, top, marshId, routerClient, beforeStartState != null);
}
/**
@@ -434,22 +497,65 @@ public class GridClientImpl implements GridClient {
* @param cfg Client configuration.
* @param routers Routers or empty collection to use endpoints from topology info.
* @param top Topology.
+ * @param beforeNodeStart Connecting to a node before starting it without getting/updating topology.
* @throws GridClientException In case of error.
*/
private GridClientConnectionManager createConnectionManager(UUID clientId, SSLContext sslCtx,
GridClientConfiguration cfg, Collection<InetSocketAddress> routers, GridClientTopology top,
- @Nullable Byte marshId, boolean routerClient)
- throws GridClientException {
- return new GridClientConnectionManagerOsImpl(clientId, sslCtx, cfg, routers, top, marshId, routerClient);
+ @Nullable Byte marshId, boolean routerClient, boolean beforeNodeStart) throws GridClientException {
+ return new GridClientConnectionManagerOsImpl(
+ clientId,
+ sslCtx,
+ cfg,
+ routers,
+ top,
+ marshId,
+ routerClient,
+ beforeNodeStart
+ );
}
/**
- * Tries to init client topology using configured set of servers or routers.
+ * Tries to init connection manager using configured set of servers or routers.
*
* @throws GridClientException If initialisation failed.
* @throws InterruptedException If initialisation was interrupted.
*/
- private void tryInitTopology() throws GridClientException, InterruptedException {
+ private void tryInit() throws GridClientException, InterruptedException {
+ connMgr.init(addresses());
+
+ Map<String, GridClientCacheMode> overallCaches = new HashMap<>();
+
+ for (GridClientNodeImpl node : top.nodes())
+ overallCaches.putAll(node.caches());
+
+ for (Map.Entry<String, GridClientCacheMode> entry : overallCaches.entrySet()) {
+ GridClientDataAffinity affinity = affinity(entry.getKey());
+
+ if (affinity instanceof GridClientPartitionAffinity && entry.getValue() !=
+ GridClientCacheMode.PARTITIONED)
+ log.warning(GridClientPartitionAffinity.class.getSimpleName() + " is used for a cache configured " +
+ "for non-partitioned mode [cacheName=" + entry.getKey() + ", cacheMode=" + entry.getValue() + ']');
+ }
+ }
+
+ /**
+ * Getting a client connection without topology information.
+ *
+ * @return Client connection.
+ * @throws GridClientException If failed.
+ */
+ public GridClientConnection connection() throws GridClientException, InterruptedException {
+ return connectionManager().connection(addresses());
+ }
+
+ /**
+ * Return addresses for connection.
+ *
+ * @return Addresses for connection.
+ * @throws GridClientException If failed.
+ */
+ private Collection<InetSocketAddress> addresses() throws GridClientException {
boolean hasSrvs = routers.isEmpty();
final Collection<InetSocketAddress> connSrvs = (hasSrvs) ? new LinkedHashSet<>(srvs) : routers;
@@ -486,21 +592,7 @@ public class GridClientImpl implements GridClient {
}
}
- connMgr.init(connSrvs);
-
- Map<String, GridClientCacheMode> overallCaches = new HashMap<>();
-
- for (GridClientNodeImpl node : top.nodes())
- overallCaches.putAll(node.caches());
-
- for (Map.Entry<String, GridClientCacheMode> entry : overallCaches.entrySet()) {
- GridClientDataAffinity affinity = affinity(entry.getKey());
-
- if (affinity instanceof GridClientPartitionAffinity && entry.getValue() !=
- GridClientCacheMode.PARTITIONED)
- log.warning(GridClientPartitionAffinity.class.getSimpleName() + " is used for a cache configured " +
- "for non-partitioned mode [cacheName=" + entry.getKey() + ", cacheMode=" + entry.getValue() + ']');
- }
+ return connSrvs;
}
/**
@@ -517,7 +609,7 @@ public class GridClientImpl implements GridClient {
/** {@inheritDoc} */
@Override public void iteration() throws InterruptedException {
try {
- tryInitTopology();
+ tryInit();
}
catch (GridClientException e) {
top.fail(e);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/GridClientNodeStateBeforeStartImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/GridClientNodeStateBeforeStartImpl.java
new file mode 100644
index 0000000..1d1f92f6
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/GridClientNodeStateBeforeStartImpl.java
@@ -0,0 +1,49 @@
+/*
+ * 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.client.impl;
+
+import org.apache.ignite.internal.client.GridClientException;
+import org.apache.ignite.internal.client.GridClientNodeStateBeforeStart;
+import org.apache.ignite.internal.processors.rest.client.message.GridClientWarmUpRequest;
+
+/**
+ * Implementation {@link GridClientNodeStateBeforeStart}.
+ */
+public class GridClientNodeStateBeforeStartImpl implements GridClientNodeStateBeforeStart {
+ /** Client instance. */
+ private final GridClientImpl client;
+
+ /**
+ * Constructor.
+ *
+ * @param client Client instance.
+ */
+ public GridClientNodeStateBeforeStartImpl(GridClientImpl client) {
+ this.client = client;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void stopWarmUp() throws GridClientException {
+ try {
+ client.connection().messageBeforeStart(new GridClientWarmUpRequest().stopWarmUp(true)).get();
+ }
+ catch (InterruptedException e) {
+ throw new GridClientException("Interrupted when (re)trying to perform request.", e);
+ }
+ }
+}
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 00759e0..8a60545 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
@@ -405,6 +405,15 @@ public abstract class GridClientConnection {
public abstract GridClientFutureAdapter<?> forwardMessage(Object body) throws GridClientException;
/**
+ * Sending messages before node starts and getting a response to it.
+ *
+ * @param msg A raw message to send.
+ * @return Future holding server's response.
+ * @throws GridClientException In case of error.
+ */
+ public abstract GridClientFutureAdapter<?> messageBeforeStart(Object msg) throws GridClientException;
+
+ /**
* @return {@code True} if connection is closed.
*/
public boolean isClosed() {
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientConnectionManager.java b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientConnectionManager.java
index dbab8be..94c9a73 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientConnectionManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientConnectionManager.java
@@ -71,4 +71,16 @@ public interface GridClientConnectionManager {
* (and receiving responses for all pending requests), otherwise it will return immediately.
*/
public void stop(boolean waitCompletion);
+
+ /**
+ * Returns connection to node using given server addresses.
+ *
+ * @param srvs Server addresses.
+ * @return Established connection.
+ * @throws GridClientException If failed.
+ * @throws InterruptedException If was interrupted while waiting for connection to be established.
+ */
+ public GridClientConnection connection(
+ Collection<InetSocketAddress> srvs
+ ) throws GridClientException, InterruptedException;
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientConnectionManagerAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientConnectionManagerAdapter.java
index 6fde7ad..63f19c4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientConnectionManagerAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientConnectionManagerAdapter.java
@@ -54,6 +54,7 @@ import org.apache.ignite.internal.client.util.GridClientStripedLock;
import org.apache.ignite.internal.client.util.GridClientUtils;
import org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeResponse;
import org.apache.ignite.internal.processors.rest.client.message.GridClientMessage;
+import org.apache.ignite.internal.processors.rest.client.message.GridClientNodeStateBeforeStartRequest;
import org.apache.ignite.internal.processors.rest.client.message.GridClientPingPacket;
import org.apache.ignite.internal.processors.rest.protocols.tcp.GridTcpRestParser;
import org.apache.ignite.internal.util.nio.GridNioCodecFilter;
@@ -68,6 +69,7 @@ import org.apache.ignite.logger.java.JavaLogger;
import org.apache.ignite.plugin.security.SecurityCredentials;
import org.jetbrains.annotations.Nullable;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO;
import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_MACS;
import static org.apache.ignite.internal.client.impl.connection.GridClientConnectionCloseReason.CLIENT_CLOSED;
@@ -128,6 +130,9 @@ public abstract class GridClientConnectionManagerAdapter implements GridClientCo
/** Marshaller ID. */
private final Byte marshId;
+ /** Connecting to a node before starting it without getting/updating topology. */
+ private final boolean beforeNodeStart;
+
/**
* @param clientId Client ID.
* @param sslCtx SSL context to enable secured connection or {@code null} to use unsecured one.
@@ -135,6 +140,7 @@ public abstract class GridClientConnectionManagerAdapter implements GridClientCo
* @param routers Routers or empty collection to use endpoints from topology info.
* @param top Topology.
* @param marshId Marshaller ID.
+ * @param beforeNodeStart Connecting to a node before starting it without getting/updating topology.
* @throws GridClientException In case of error.
*/
@SuppressWarnings("unchecked")
@@ -144,8 +150,9 @@ public abstract class GridClientConnectionManagerAdapter implements GridClientCo
Collection<InetSocketAddress> routers,
GridClientTopology top,
@Nullable Byte marshId,
- boolean routerClient)
- throws GridClientException {
+ boolean routerClient,
+ boolean beforeNodeStart
+ ) throws GridClientException {
assert clientId != null : "clientId != null";
assert cfg != null : "cfg != null";
assert routers != null : "routers != null";
@@ -156,6 +163,7 @@ public abstract class GridClientConnectionManagerAdapter implements GridClientCo
this.cfg = cfg;
this.routers = new ArrayList<>(routers);
this.top = top;
+ this.beforeNodeStart = beforeNodeStart;
log = Logger.getLogger(getClass().getName());
@@ -218,59 +226,19 @@ public abstract class GridClientConnectionManagerAdapter implements GridClientCo
}
/** {@inheritDoc} */
- @SuppressWarnings("BusyWait")
@Override public void init(Collection<InetSocketAddress> srvs) throws GridClientException, InterruptedException {
init0();
- GridClientException firstEx = null;
-
- for (int i = 0; i < INIT_RETRY_CNT; i++) {
- Collection<InetSocketAddress> srvsCp = new ArrayList<>(srvs);
-
- while (!srvsCp.isEmpty()) {
- GridClientConnection conn = null;
-
- try {
- conn = connect(null, srvsCp);
-
- conn.topology(cfg.isAutoFetchAttributes(), cfg.isAutoFetchMetrics(), null).get();
-
- return;
- }
- catch (GridServerUnreachableException e) {
- // No connection could be opened to any of initial addresses - exit to retry loop.
- assert conn == null :
- "GridClientConnectionResetException was thrown from GridClientConnection#topology";
-
- if (firstEx == null)
- firstEx = e;
-
- break;
- }
- catch (GridClientConnectionResetException e) {
- // Connection was established but topology update failed -
- // trying other initial addresses if any.
- assert conn != null : "GridClientConnectionResetException was thrown from connect()";
-
- if (firstEx == null)
- firstEx = e;
-
- if (!srvsCp.remove(conn.serverAddress()))
- // We have misbehaving collection or equals - just exit to avoid infinite loop.
- break;
- }
+ connect(srvs, conn -> {
+ if (beforeNodeStart) {
+ conn.messageBeforeStart(new GridClientNodeStateBeforeStartRequest())
+ .get(cfg.getConnectTimeout(), MILLISECONDS);
}
-
- Thread.sleep(INIT_RETRY_INTERVAL);
- }
-
- for (GridClientConnection c : conns.values()) {
- conns.remove(c.serverAddress(), c);
-
- c.close(FAILED, false);
- }
-
- throw firstEx;
+ else {
+ conn.topology(cfg.isAutoFetchAttributes(), cfg.isAutoFetchMetrics(), null)
+ .get(cfg.getConnectTimeout(), MILLISECONDS);
+ }
+ });
}
/**
@@ -553,6 +521,78 @@ public abstract class GridClientConnectionManagerAdapter implements GridClientCo
srv.stop();
}
+ /** {@inheritDoc} */
+ @Override public GridClientConnection connection(
+ Collection<InetSocketAddress> srvs
+ ) throws GridClientException, InterruptedException {
+ return connect(srvs, null);
+ }
+
+ /**
+ * Returns connection to node using given server addresses.
+ *
+ * @param srvs Server addresses.
+ * @param clo Client connection closure.
+ * @return Established connection.
+ * @throws GridClientException If failed.
+ * @throws InterruptedException If was interrupted while waiting for connection to be established.
+ */
+ private GridClientConnection connect(
+ Collection<InetSocketAddress> srvs,
+ @Nullable GridClientConnectionInClosure clo
+ ) throws InterruptedException, GridClientException {
+ GridClientException firstEx = null;
+
+ for (int i = 0; i < INIT_RETRY_CNT; i++) {
+ Collection<InetSocketAddress> srvsCp = new ArrayList<>(srvs);
+
+ while (!srvsCp.isEmpty()) {
+ GridClientConnection conn = null;
+
+ try {
+ conn = connect(null, srvsCp);
+
+ if (clo != null)
+ clo.apply(conn);
+
+ return conn;
+ }
+ catch (GridServerUnreachableException e) {
+ // No connection could be opened to any of initial addresses - exit to retry loop.
+ assert conn == null :
+ "GridClientConnectionResetException was thrown from GridClientConnection#topology";
+
+ if (firstEx == null)
+ firstEx = e;
+
+ break;
+ }
+ catch (GridClientConnectionResetException e) {
+ // Connection was established but topology update failed -
+ // trying other initial addresses if any.
+ assert conn != null : "GridClientConnectionResetException was thrown from connect()";
+
+ if (firstEx == null)
+ firstEx = e;
+
+ if (!srvsCp.remove(conn.serverAddress()))
+ // We have misbehaving collection or equals - just exit to avoid infinite loop.
+ break;
+ }
+ }
+
+ Thread.sleep(INIT_RETRY_INTERVAL);
+ }
+
+ for (GridClientConnection c : conns.values()) {
+ conns.remove(c.serverAddress(), c);
+
+ c.close(FAILED, false);
+ }
+
+ throw firstEx;
+ }
+
/**
* Close all connections idling for more then
* {@link GridClientConfiguration#getMaxConnectionIdleTime()} milliseconds.
@@ -696,4 +736,18 @@ public abstract class GridClientConnectionManagerAdapter implements GridClientCo
ses.close();
}
}
+
+ /**
+ * Client connection in closure.
+ */
+ @FunctionalInterface
+ private static interface GridClientConnectionInClosure {
+ /**
+ * Closure body.
+ *
+ * @param conn Client connection.
+ * @throws GridClientException If failed.
+ */
+ void apply(GridClientConnection conn) throws GridClientException;
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientConnectionManagerOsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientConnectionManagerOsImpl.java
index 3329a3b..881f4df 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientConnectionManagerOsImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientConnectionManagerOsImpl.java
@@ -34,12 +34,13 @@ public class GridClientConnectionManagerOsImpl extends GridClientConnectionManag
* @param cfg Client configuration.
* @param routers Routers or empty collection to use endpoints from topology info.
* @param top Topology.
+ * @param beforeNodeStart Connecting to a node before starting it without getting/updating topology.
* @throws GridClientException In case of error.
*/
public GridClientConnectionManagerOsImpl(UUID clientId, SSLContext sslCtx, GridClientConfiguration cfg,
- Collection<InetSocketAddress> routers, GridClientTopology top, Byte marshId, boolean routerClient)
- throws GridClientException {
- super(clientId, sslCtx, cfg, routers, top, marshId, routerClient);
+ Collection<InetSocketAddress> routers, GridClientTopology top, Byte marshId, boolean routerClient,
+ boolean beforeNodeStart) throws GridClientException {
+ super(clientId, sslCtx, cfg, routers, top, marshId, routerClient, beforeNodeStart);
}
/** {@inheritDoc} */
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 fefe68d..6a898e9 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
@@ -67,6 +67,7 @@ import org.apache.ignite.internal.processors.rest.client.message.GridClientHands
import org.apache.ignite.internal.processors.rest.client.message.GridClientMessage;
import org.apache.ignite.internal.processors.rest.client.message.GridClientNodeBean;
import org.apache.ignite.internal.processors.rest.client.message.GridClientNodeMetricsBean;
+import org.apache.ignite.internal.processors.rest.client.message.GridClientNodeStateBeforeStartRequest;
import org.apache.ignite.internal.processors.rest.client.message.GridClientPingPacket;
import org.apache.ignite.internal.processors.rest.client.message.GridClientResponse;
import org.apache.ignite.internal.processors.rest.client.message.GridClientTaskRequest;
@@ -1082,6 +1083,13 @@ public class GridClientNioTcpConnection extends GridClientConnection {
return nodeBuilder.build();
}
+ /** {@inheritDoc} */
+ @Override public GridClientFutureAdapter<?> messageBeforeStart(Object msg) throws GridClientException {
+ assert msg instanceof GridClientNodeStateBeforeStartRequest;
+
+ return makeRequest((GridClientMessage)msg, new TcpClientFuture<>());
+ }
+
/**
* Future extension that holds client tcp message and auth retry flag.
*/
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridRouterClientImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridRouterClientImpl.java
index 8a5a746..163b872 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridRouterClientImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridRouterClientImpl.java
@@ -77,7 +77,7 @@ public class GridRouterClientImpl implements GridClient {
this.cliCfg = cliCfg;
- clientImpl = new GridClientImpl(id, cliCfg, true);
+ clientImpl = new GridClientImpl(id, cliCfg, true, false);
if (cliCfg.getProtocol() != GridClientProtocol.TCP)
throw new AssertionError("Unknown protocol: " + cliCfg.getProtocol());
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 66a7a62..c97c26a 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
@@ -217,7 +217,13 @@ public enum GridRestCommand {
DATA_REGION_METRICS("dataregion"),
/** Data storage metrics. */
- DATA_STORAGE_METRICS("datastorage");
+ DATA_STORAGE_METRICS("datastorage"),
+
+ /** Node state before its start. */
+ NODE_STATE_BEFORE_START("nodestatebeforestart"),
+
+ /** Warm-up. */
+ WARM_UP("warmup");
/** Enum values. */
private static final GridRestCommand[] VALS = values();
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 9c1cdc2..5f1ea66 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
@@ -47,6 +47,7 @@ import org.apache.ignite.internal.processors.authentication.AuthorizationContext
import org.apache.ignite.internal.processors.rest.client.message.GridClientTaskResultBean;
import org.apache.ignite.internal.processors.rest.handlers.GridRestCommandHandler;
import org.apache.ignite.internal.processors.rest.handlers.auth.AuthenticationCommandHandler;
+import org.apache.ignite.internal.processors.rest.handlers.beforeStart.NodeStateBeforeStartCommandHandler;
import org.apache.ignite.internal.processors.rest.handlers.cache.GridCacheCommandHandler;
import org.apache.ignite.internal.processors.rest.handlers.cluster.GridBaselineCommandHandler;
import org.apache.ignite.internal.processors.rest.handlers.cluster.GridChangeClusterStateCommandHandler;
@@ -62,6 +63,7 @@ import org.apache.ignite.internal.processors.rest.handlers.user.UserActionComman
import org.apache.ignite.internal.processors.rest.handlers.version.GridVersionCommandHandler;
import org.apache.ignite.internal.processors.rest.protocols.tcp.GridTcpRestProtocol;
import org.apache.ignite.internal.processors.rest.request.GridRestCacheRequest;
+import org.apache.ignite.internal.processors.rest.request.GridRestNodeStateBeforeStartRequest;
import org.apache.ignite.internal.processors.rest.request.GridRestRequest;
import org.apache.ignite.internal.processors.rest.request.GridRestTaskRequest;
import org.apache.ignite.internal.processors.rest.request.RestQueryRequest;
@@ -229,7 +231,11 @@ public class GridRestProcessor extends GridProcessorAdapter implements IgniteRes
* @return Future.
*/
private IgniteInternalFuture<GridRestResponse> handleRequest(final GridRestRequest req) {
- if (startLatch.getCount() > 0) {
+ if (req instanceof GridRestNodeStateBeforeStartRequest) {
+ if (startLatch.getCount() == 0)
+ return new GridFinishedFuture<>(new IgniteCheckedException("Node has already started."));
+ }
+ else if (startLatch.getCount() > 0) {
try {
startLatch.await();
}
@@ -549,6 +555,7 @@ public class GridRestProcessor extends GridProcessorAdapter implements IgniteRes
addHandler(new UserActionCommandHandler(ctx));
addHandler(new GridBaselineCommandHandler(ctx));
addHandler(new MemoryMetricsCommandHandler(ctx));
+ addHandler(new NodeStateBeforeStartCommandHandler(ctx));
// Start protocols.
startTcpProtocol();
@@ -571,6 +578,8 @@ public class GridRestProcessor extends GridProcessorAdapter implements IgniteRes
ctx.addNodeAttribute(key, p.getValue());
}
}
+
+ proto.onProcessorStart();
}
}
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProtocol.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProtocol.java
index 1313862..073ce0c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProtocol.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProtocol.java
@@ -55,4 +55,9 @@ public interface GridRestProtocol {
* Stops protocol.
*/
public abstract void stop();
+
+ /**
+ * Processor start callback.
+ */
+ void onProcessorStart();
}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUpConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/client/message/GridClientNodeStateBeforeStartRequest.java
similarity index 60%
copy from modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUpConfiguration.java
copy to modules/core/src/main/java/org/apache/ignite/internal/processors/rest/client/message/GridClientNodeStateBeforeStartRequest.java
index d050133..c8c77bd 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUpConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/client/message/GridClientNodeStateBeforeStartRequest.java
@@ -15,13 +15,19 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.processors.cache.warmup;
+package org.apache.ignite.internal.processors.rest.client.message;
-import org.apache.ignite.configuration.WarmUpConfiguration;
+import org.apache.ignite.internal.util.typedef.internal.S;
/**
- * Configuration for {@link SimpleObservableWarmUp}.
+ * Request to manage and obtain information about node before its start.
*/
-class SimpleObservableWarmUpConfiguration implements WarmUpConfiguration {
- // No-op.
+public class GridClientNodeStateBeforeStartRequest extends GridClientAbstractMessage {
+ /** Serial version uid. */
+ private static final long serialVersionUID = 0L;
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(GridClientNodeStateBeforeStartRequest.class, this, super.toString());
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/client/message/GridClientWarmUpRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/client/message/GridClientWarmUpRequest.java
new file mode 100644
index 0000000..b3de271
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/client/message/GridClientWarmUpRequest.java
@@ -0,0 +1,90 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Objects;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+public class GridClientWarmUpRequest extends GridClientNodeStateBeforeStartRequest {
+ /** Serial version uid. */
+ private static final long serialVersionUID = 0L;
+
+ /** Stop warm-up. */
+ private boolean stopWarmUp;
+
+ /**
+ * Return {@code true} to stop warm-up.
+ *
+ * @return {@code true} to stop warm-up.
+ */
+ public boolean stopWarmUp() {
+ return stopWarmUp;
+ }
+
+ /**
+ * Set need to stop warm-up.
+ *
+ * @param stopWarmUp {@code true} to stop warm-up.
+ * @return {@code this} instance.
+ */
+ public GridClientWarmUpRequest stopWarmUp(boolean stopWarmUp) {
+ this.stopWarmUp = stopWarmUp;
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeExternal(ObjectOutput out) throws IOException {
+ super.writeExternal(out);
+
+ out.writeBoolean(stopWarmUp);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ super.readExternal(in);
+
+ stopWarmUp = in.readBoolean();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ GridClientWarmUpRequest req = (GridClientWarmUpRequest)o;
+
+ return stopWarmUp == req.stopWarmUp;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return Objects.hash(stopWarmUp);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(GridClientWarmUpRequest.class, this, super.toString());
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/beforeStart/NodeStateBeforeStartCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/beforeStart/NodeStateBeforeStartCommandHandler.java
new file mode 100644
index 0000000..fcb2ef9
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/beforeStart/NodeStateBeforeStartCommandHandler.java
@@ -0,0 +1,75 @@
+/*
+ * 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.handlers.beforeStart;
+
+import java.util.Arrays;
+import java.util.Collection;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.GridKernalContext;
+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.GridRestNodeStateBeforeStartRequest;
+import org.apache.ignite.internal.processors.rest.request.GridRestRequest;
+import org.apache.ignite.internal.processors.rest.request.GridRestWarmUpRequest;
+import org.apache.ignite.internal.util.future.GridFinishedFuture;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/**
+ * Command handler for managing state of a node before it starts and getting information about it.
+ */
+public class NodeStateBeforeStartCommandHandler extends GridRestCommandHandlerAdapter {
+ /**
+ * Construecor.
+ *
+ * @param ctx Kernal context.
+ */
+ public NodeStateBeforeStartCommandHandler(GridKernalContext ctx) {
+ super(ctx);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<GridRestCommand> supportedCommands() {
+ return Arrays.asList(GridRestCommand.NODE_STATE_BEFORE_START, GridRestCommand.WARM_UP);
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteInternalFuture<GridRestResponse> handleAsync(GridRestRequest req) {
+ GridRestNodeStateBeforeStartRequest restReq = (GridRestNodeStateBeforeStartRequest)req;
+
+ if (log.isDebugEnabled())
+ log.debug("Handling REST request: " + req);
+
+ try {
+ if (restReq instanceof GridRestWarmUpRequest) {
+ GridRestWarmUpRequest warmUpReq = (GridRestWarmUpRequest)restReq;
+
+ if (warmUpReq.stopWarmUp())
+ ctx.cache().stopWarmUp();
+ }
+ }
+ catch (IgniteCheckedException e) {
+ U.error(log, "Failed to execute cache command: " + req, e);
+
+ return new GridFinishedFuture<>(e);
+ }
+
+ return new GridFinishedFuture<>(new GridRestResponse());
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/GridRestProtocolAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/GridRestProtocolAdapter.java
index 76c6926..0a639c4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/GridRestProtocolAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/GridRestProtocolAdapter.java
@@ -194,4 +194,9 @@ public abstract class GridRestProtocolAdapter implements GridRestProtocol {
@Override public void onKernalStart() {
// No-op.
}
+
+ /** {@inheritDoc} */
+ @Override public void onProcessorStart() {
+ // No-op.
+ }
}
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 20bf5c5..29f89a4 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
@@ -41,11 +41,13 @@ import org.apache.ignite.internal.processors.rest.client.message.GridClientClust
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;
+import org.apache.ignite.internal.processors.rest.client.message.GridClientNodeStateBeforeStartRequest;
import org.apache.ignite.internal.processors.rest.client.message.GridClientPingPacket;
import org.apache.ignite.internal.processors.rest.client.message.GridClientResponse;
import org.apache.ignite.internal.processors.rest.client.message.GridClientStateRequest;
import org.apache.ignite.internal.processors.rest.client.message.GridClientTaskRequest;
import org.apache.ignite.internal.processors.rest.client.message.GridClientTopologyRequest;
+import org.apache.ignite.internal.processors.rest.client.message.GridClientWarmUpRequest;
import org.apache.ignite.internal.processors.rest.handlers.cache.GridCacheRestMetrics;
import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisMessage;
import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisNioListener;
@@ -53,9 +55,11 @@ 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.GridRestClusterStateRequest;
+import org.apache.ignite.internal.processors.rest.request.GridRestNodeStateBeforeStartRequest;
import org.apache.ignite.internal.processors.rest.request.GridRestRequest;
import org.apache.ignite.internal.processors.rest.request.GridRestTaskRequest;
import org.apache.ignite.internal.processors.rest.request.GridRestTopologyRequest;
+import org.apache.ignite.internal.processors.rest.request.GridRestWarmUpRequest;
import org.apache.ignite.internal.util.nio.GridNioFuture;
import org.apache.ignite.internal.util.nio.GridNioServerListenerAdapter;
import org.apache.ignite.internal.util.nio.GridNioSession;
@@ -82,8 +86,10 @@ import static org.apache.ignite.internal.processors.rest.GridRestCommand.CLUSTER
import static org.apache.ignite.internal.processors.rest.GridRestCommand.CLUSTER_STATE;
import static org.apache.ignite.internal.processors.rest.GridRestCommand.EXE;
import static org.apache.ignite.internal.processors.rest.GridRestCommand.NODE;
+import static org.apache.ignite.internal.processors.rest.GridRestCommand.NODE_STATE_BEFORE_START;
import static org.apache.ignite.internal.processors.rest.GridRestCommand.NOOP;
import static org.apache.ignite.internal.processors.rest.GridRestCommand.TOPOLOGY;
+import static org.apache.ignite.internal.processors.rest.GridRestCommand.WARM_UP;
import static org.apache.ignite.internal.processors.rest.client.message.GridClientCacheRequest.GridCacheOperation.APPEND;
import static org.apache.ignite.internal.processors.rest.client.message.GridClientCacheRequest.GridCacheOperation.CAS;
import static org.apache.ignite.internal.processors.rest.client.message.GridClientCacheRequest.GridCacheOperation.GET;
@@ -416,6 +422,22 @@ public class GridTcpRestNioListener extends GridNioServerListenerAdapter<GridCli
}
else if (msg instanceof GridClientClusterNameRequest)
restReq = new GridRestClusterNameRequest();
+ else if (msg instanceof GridClientNodeStateBeforeStartRequest) {
+ GridClientNodeStateBeforeStartRequest reqClient = (GridClientNodeStateBeforeStartRequest)msg;
+
+ if (reqClient instanceof GridClientWarmUpRequest) {
+ GridClientWarmUpRequest warmUpReqClient = (GridClientWarmUpRequest)reqClient;
+
+ restReq = new GridRestWarmUpRequest().stopWarmUp(warmUpReqClient.stopWarmUp());
+
+ restReq.command(WARM_UP);
+ }
+ else {
+ restReq = new GridRestNodeStateBeforeStartRequest();
+
+ restReq.command(NODE_STATE_BEFORE_START);
+ }
+ }
if (restReq != null) {
restReq.destinationId(msg.destinationId());
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java
index 7e4637c..afb5525 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java
@@ -138,8 +138,8 @@ public class GridTcpRestProtocol extends GridRestProtocolAdapter {
}
/** {@inheritDoc} */
- @Override public void onKernalStart() {
- super.onKernalStart();
+ @Override public void onProcessorStart() {
+ super.onProcessorStart();
Map<Byte, GridClientMarshaller> marshMap = new HashMap<>();
@@ -151,7 +151,7 @@ public class GridTcpRestProtocol extends GridRestProtocolAdapter {
marshMap.put(GridClientZipOptimizedMarshaller.ID, new GridClientZipOptimizedMarshaller(optMarsh, providers));
try {
- IgnitePredicate<String> clsFilter = MarshallerUtils.classNameFilter(this.getClass().getClassLoader());
+ IgnitePredicate<String> clsFilter = MarshallerUtils.classNameFilter(getClass().getClassLoader());
marshMap.put(GridClientJdkMarshaller.ID, new GridClientJdkMarshaller(clsFilter));
}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUpConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestNodeStateBeforeStartRequest.java
similarity index 65%
copy from modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUpConfiguration.java
copy to modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestNodeStateBeforeStartRequest.java
index d050133..5e9c5e6 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUpConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestNodeStateBeforeStartRequest.java
@@ -15,13 +15,16 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.processors.cache.warmup;
+package org.apache.ignite.internal.processors.rest.request;
-import org.apache.ignite.configuration.WarmUpConfiguration;
+import org.apache.ignite.internal.util.typedef.internal.S;
/**
- * Configuration for {@link SimpleObservableWarmUp}.
+ * Request to manage and obtain information about node before its start.
*/
-class SimpleObservableWarmUpConfiguration implements WarmUpConfiguration {
- // No-op.
+public class GridRestNodeStateBeforeStartRequest extends GridRestRequest {
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(GridRestNodeStateBeforeStartRequest.class, this, super.toString());
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestWarmUpRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestWarmUpRequest.java
new file mode 100644
index 0000000..37c9722
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestWarmUpRequest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.util.typedef.internal.S;
+
+/**
+ * Grid warm-up request.
+ */
+public class GridRestWarmUpRequest extends GridRestNodeStateBeforeStartRequest {
+ /** Stop warm-up. */
+ private boolean stopWarmUp;
+
+ /**
+ * Return {@code true} to stop warm-up.
+ *
+ * @return {@code true} to stop warm-up.
+ */
+ public boolean stopWarmUp() {
+ return stopWarmUp;
+ }
+
+ /**
+ * Set need to stop warm-up.
+ *
+ * @param stopWarmUp {@code true} to stop warm-up.
+ * @return {@code this} instance.
+ */
+ public GridRestWarmUpRequest stopWarmUp(boolean stopWarmUp) {
+ this.stopWarmUp = stopWarmUp;
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(GridRestWarmUpRequest.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 f97d546..9815054 100644
--- a/modules/core/src/main/resources/META-INF/classnames.properties
+++ b/modules/core/src/main/resources/META-INF/classnames.properties
@@ -1630,6 +1630,8 @@ org.apache.ignite.internal.processors.rest.client.message.GridClientTaskResultBe
org.apache.ignite.internal.processors.rest.client.message.GridClientTopologyRequest
org.apache.ignite.internal.processors.rest.client.message.GridRouterRequest
org.apache.ignite.internal.processors.rest.client.message.GridRouterResponse
+org.apache.ignite.internal.processors.rest.client.message.GridClientNodeStateBeforeStartRequest
+org.apache.ignite.internal.processors.rest.client.message.GridClientWarmUpRequest
org.apache.ignite.internal.processors.rest.handlers.cache.GridCacheCommandHandler$2
org.apache.ignite.internal.processors.rest.handlers.cache.GridCacheCommandHandler$3
org.apache.ignite.internal.processors.rest.handlers.cache.GridCacheCommandHandler$4
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/BlockedWarmUpConfiguration.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/BlockedWarmUpConfiguration.java
index 079021c..6f20023 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/BlockedWarmUpConfiguration.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/BlockedWarmUpConfiguration.java
@@ -20,8 +20,8 @@ package org.apache.ignite.internal.processors.cache.warmup;
import org.apache.ignite.configuration.WarmUpConfiguration;
/**
- * Configuration for {@link BlockedWarmUp}.
+ * Configuration for {@link BlockedWarmUpStrategy}.
*/
-class BlockedWarmUpConfiguration implements WarmUpConfiguration {
+public class BlockedWarmUpConfiguration implements WarmUpConfiguration {
// No-op.
}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/BlockedWarmUp.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/BlockedWarmUpStrategy.java
similarity index 88%
rename from modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/BlockedWarmUp.java
rename to modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/BlockedWarmUpStrategy.java
index 25a1a3b..0244ba5 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/BlockedWarmUp.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/BlockedWarmUpStrategy.java
@@ -25,12 +25,12 @@ import org.apache.ignite.internal.util.typedef.internal.U;
/**
* Warm-up strategy that only waits for {@link #stop} call.
*/
-class BlockedWarmUp implements WarmUpStrategy<BlockedWarmUpConfiguration> {
+public class BlockedWarmUpStrategy implements WarmUpStrategy<BlockedWarmUpConfiguration> {
/** Stop latch. */
- final CountDownLatch stopLatch = new CountDownLatch(1);
+ public final CountDownLatch stopLatch = new CountDownLatch(1);
/** Start latch. */
- final CountDownLatch startLatch = new CountDownLatch(1);
+ public final CountDownLatch startLatch = new CountDownLatch(1);
/** {@inheritDoc} */
@Override public Class<BlockedWarmUpConfiguration> configClass() {
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUpConfiguration.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUpConfiguration.java
index d050133..0246ad9 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUpConfiguration.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUpConfiguration.java
@@ -20,7 +20,7 @@ package org.apache.ignite.internal.processors.cache.warmup;
import org.apache.ignite.configuration.WarmUpConfiguration;
/**
- * Configuration for {@link SimpleObservableWarmUp}.
+ * Configuration for {@link SimpleObservableWarmUpStrategy}.
*/
class SimpleObservableWarmUpConfiguration implements WarmUpConfiguration {
// No-op.
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUp.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUpStrategy.java
similarity index 94%
rename from modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUp.java
rename to modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUpStrategy.java
index e743dd5..ac327b4 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUp.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/SimpleObservableWarmUpStrategy.java
@@ -26,7 +26,7 @@ import org.apache.ignite.internal.processors.cache.persistence.DataRegion;
/**
* Warm-up strategy that only records which regions have visited it and how many times.
*/
-class SimpleObservableWarmUp implements WarmUpStrategy<SimpleObservableWarmUpConfiguration> {
+class SimpleObservableWarmUpStrategy implements WarmUpStrategy<SimpleObservableWarmUpConfiguration> {
/** Visited regions with a counter. */
final Map<String, AtomicInteger> visitRegions = new ConcurrentHashMap<>();
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/WarmUpSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/WarmUpSelfTest.java
index 55acf79..4591604 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/WarmUpSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/WarmUpSelfTest.java
@@ -202,10 +202,10 @@ public class WarmUpSelfTest extends GridCommonAbstractTest {
* Test checks that strategies are executed according to configuration.
* <p>
* Steps:
- * 1)Starting a node with a single region that has been configured for {@link SimpleObservableWarmUp};
+ * 1)Starting a node with a single region that has been configured for {@link SimpleObservableWarmUpStrategy};
* 2)Check that strategy was executed only for it region;
* 3)Restarting node with default {@link SimpleObservableWarmUpConfiguration};
- * 4)Checks that {@link SimpleObservableWarmUp} was only executed for persistent regions
+ * 4)Checks that {@link SimpleObservableWarmUpStrategy} was only executed for persistent regions
* that were not configured by {@link SimpleObservableWarmUpConfiguration}.
*
* @throws Exception If failed.
@@ -226,7 +226,7 @@ public class WarmUpSelfTest extends GridCommonAbstractTest {
startGrid(cfg);
WarmUpTestPluginProvider pluginProvider = (WarmUpTestPluginProvider)cfg.getPluginProviders()[0];
- SimpleObservableWarmUp observableWarmUp = (SimpleObservableWarmUp)pluginProvider.strats.get(0);
+ SimpleObservableWarmUpStrategy observableWarmUp = (SimpleObservableWarmUpStrategy)pluginProvider.strats.get(0);
assertEquals(1, observableWarmUp.visitRegions.size());
assertTrue(observableWarmUp.visitRegions.containsKey("2"));
@@ -251,7 +251,7 @@ public class WarmUpSelfTest extends GridCommonAbstractTest {
startGrid(cfg);
pluginProvider = (WarmUpTestPluginProvider)cfg.getPluginProviders()[0];
- observableWarmUp = (SimpleObservableWarmUp)pluginProvider.strats.get(0);
+ observableWarmUp = (SimpleObservableWarmUpStrategy)pluginProvider.strats.get(0);
assertEquals(2, observableWarmUp.visitRegions.size());
@@ -349,7 +349,7 @@ public class WarmUpSelfTest extends GridCommonAbstractTest {
IgniteInternalFuture<IgniteEx> stratFut = GridTestUtils.runAsync(() -> startGrid(cfg));
WarmUpTestPluginProvider pluginProvider = (WarmUpTestPluginProvider)cfg.getPluginProviders()[0];
- BlockedWarmUp strat = (BlockedWarmUp)pluginProvider.strats.get(1);
+ BlockedWarmUpStrategy strat = (BlockedWarmUpStrategy)pluginProvider.strats.get(1);
strat.startLatch.await(1, TimeUnit.MINUTES);
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/WarmUpTestPluginProvider.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/WarmUpTestPluginProvider.java
index ca8ff86..67c3553 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/WarmUpTestPluginProvider.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/warmup/WarmUpTestPluginProvider.java
@@ -28,11 +28,11 @@ import org.apache.ignite.plugin.PluginContext;
/**
* Test plugin provider for test strategies.
*/
-class WarmUpTestPluginProvider extends AbstractTestPluginProvider {
+public class WarmUpTestPluginProvider extends AbstractTestPluginProvider {
/** Collection of strategies. */
- final List<WarmUpStrategy<?>> strats = new ArrayList<>(Arrays.asList(
- new SimpleObservableWarmUp(),
- new BlockedWarmUp()
+ public final List<WarmUpStrategy<?>> strats = new ArrayList<>(Arrays.asList(
+ new SimpleObservableWarmUpStrategy(),
+ new BlockedWarmUpStrategy()
));
/** {@inheritDoc} */
diff --git a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
index 0a13460..c0f5887 100644
--- a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
+++ b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
@@ -165,6 +165,9 @@ If the file name isn't specified the output file name is: '<typeId>.bin'
Set new tracing configuration. If both --scope and --label are specified then add or override label specific configuration, if only --scope is specified, then override scope specific configuration. Print applied configuration.
control.(sh|bat) --tracing-configuration set (--scope DISCOVERY|EXCHANGE|COMMUNICATION|TX [--label] [--sampling-rate Decimal value between 0 and 1, where 0 means never and 1 means always. More or less reflects the probability of sampling specific trace.] [--included-scopes Set of scopes with comma as separator DISCOVERY|EXCHANGE|COMMUNICATION|TX])
+ Stop warm-up:
+ control.(sh|bat) --warm-up --stop
+
By default commands affecting the cluster require interactive confirmation.
Use --yes option to disable it.
diff --git a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
index 0a13460..c0f5887 100644
--- a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
+++ b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
@@ -165,6 +165,9 @@ If the file name isn't specified the output file name is: '<typeId>.bin'
Set new tracing configuration. If both --scope and --label are specified then add or override label specific configuration, if only --scope is specified, then override scope specific configuration. Print applied configuration.
control.(sh|bat) --tracing-configuration set (--scope DISCOVERY|EXCHANGE|COMMUNICATION|TX [--label] [--sampling-rate Decimal value between 0 and 1, where 0 means never and 1 means always. More or less reflects the probability of sampling specific trace.] [--included-scopes Set of scopes with comma as separator DISCOVERY|EXCHANGE|COMMUNICATION|TX])
+ Stop warm-up:
+ control.(sh|bat) --warm-up --stop
+
By default commands affecting the cluster require interactive confirmation.
Use --yes option to disable it.
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/PartitionLossTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/PartitionLossTest.cs
index d138654..c4d6e19 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/PartitionLossTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/PartitionLossTest.cs
@@ -20,7 +20,6 @@ namespace Apache.Ignite.Core.Tests.Cache
using System;
using System.Collections.Generic;
using System.Linq;
- using System.Threading;
using Apache.Ignite.Core.Cache;
using Apache.Ignite.Core.Cache.Affinity.Rendezvous;
using Apache.Ignite.Core.Cache.Configuration;
@@ -220,6 +219,9 @@ namespace Apache.Ignite.Core.Tests.Cache
Backups = 0,
WriteSynchronizationMode = CacheWriteSynchronizationMode.FullSync,
PartitionLossPolicy = policy,
+ RebalanceDelay = TimeSpan.Zero,
+ RebalanceMode = CacheRebalanceMode.Sync,
+ RebalanceThrottle = TimeSpan.Zero,
AffinityFunction = new RendezvousAffinityFunction
{
ExcludeNeighbors = false,
@@ -249,13 +251,7 @@ namespace Apache.Ignite.Core.Tests.Cache
// Wait for rebalance to complete.
var node = ignite.GetCluster().GetLocalNode();
Func<int, bool> isPrimary = x => affinity.IsPrimary(node, x);
-
- while (!keys.Any(isPrimary))
- {
- Thread.Sleep(10);
- }
-
- Thread.Sleep(100); // Some extra wait.
+ TestUtils.WaitForTrueCondition(() => keys.Any(isPrimary));
return keys.First(isPrimary);
}