use of org.apache.ignite.internal.managers.discovery.IgniteDiscoverySpi in project ignite by apache.
the class CacheLateAffinityAssignmentTest method testNodeLeaveExchangeWaitAffinityMessage.
/**
* @throws Exception If failed.
*/
@Test
public void testNodeLeaveExchangeWaitAffinityMessage() throws Exception {
System.setProperty(IGNITE_EXCHANGE_COMPATIBILITY_VER_1, "true");
try {
Ignite ignite0 = startServer(0, 1);
startServer(1, 2);
startServer(2, 3);
checkAffinity(3, topVer(3, 1), true);
checkOrderCounters(3, topVer(3, 1));
startClient(3, 4);
checkAffinity(4, topVer(4, 0), true);
DiscoverySpiTestListener lsnr = new DiscoverySpiTestListener();
((IgniteDiscoverySpi) ignite0.configuration().getDiscoverySpi()).setInternalListener(lsnr);
lsnr.blockCustomEvent(CacheAffinityChangeMessage.class);
stopGrid(1);
List<IgniteInternalFuture<?>> futs = affFutures(3, topVer(5, 0));
U.sleep(1000);
for (IgniteInternalFuture<?> fut : futs) assertFalse(fut.isDone());
lsnr.stopBlockCustomEvents();
checkAffinity(3, topVer(5, 0), false);
checkOrderCounters(3, topVer(5, 0));
} finally {
System.clearProperty(IGNITE_EXCHANGE_COMPATIBILITY_VER_1);
}
}
use of org.apache.ignite.internal.managers.discovery.IgniteDiscoverySpi in project ignite by apache.
the class GridCacheProcessor method backwardCompatibleSplitter.
/**
* If not all nodes in cluster support splitted cache configurations it returns old format splitter.
* In other case it returns default splitter.
*
* @return Cache configuration splitter with or without old format support depending on cluster state.
*/
private CacheConfigurationSplitter backwardCompatibleSplitter() {
IgniteDiscoverySpi spi = (IgniteDiscoverySpi) ctx.discovery().getInjectedDiscoverySpi();
boolean oldFormat = !spi.allNodesSupport(IgniteFeatures.SPLITTED_CACHE_CONFIGURATIONS);
return splitter(oldFormat);
}
use of org.apache.ignite.internal.managers.discovery.IgniteDiscoverySpi in project ignite by apache.
the class GridClusterStateProcessor method changeGlobalState.
/**
* @param state New cluster state.
* @param forceDeactivation If {@code true}, cluster deactivation will be forced.
* @param baselineNodes New baseline nodes.
* @param forceChangeBaselineTopology Force change baseline topology.
* @param isAutoAdjust Auto adjusting baseline flag.
* @return State change future.
* @see ClusterState#INACTIVE
*/
public IgniteInternalFuture<?> changeGlobalState(ClusterState state, boolean forceDeactivation, Collection<? extends BaselineNode> baselineNodes, boolean forceChangeBaselineTopology, boolean isAutoAdjust) {
if (ctx.maintenanceRegistry().isMaintenanceMode()) {
return new GridFinishedFuture<>(new IgniteCheckedException("Failed to " + prettyStr(state) + " (node is in maintenance mode)."));
}
BaselineTopology blt = (compatibilityMode && !forceChangeBaselineTopology) ? null : calculateNewBaselineTopology(state, baselineNodes, forceChangeBaselineTopology);
boolean isBaselineAutoAdjustEnabled = isBaselineAutoAdjustEnabled();
if (forceChangeBaselineTopology && isBaselineAutoAdjustEnabled != isAutoAdjust)
throw new BaselineAdjustForbiddenException(isBaselineAutoAdjustEnabled);
if (ctx.isDaemon() || ctx.clientNode())
return sendComputeChangeGlobalState(state, forceDeactivation, blt, forceChangeBaselineTopology);
if (cacheProc.transactions().tx() != null || sharedCtx.lockedTopologyVersion(null) != null) {
return new GridFinishedFuture<>(new IgniteCheckedException("Failed to " + prettyStr(state) + " (must invoke the method outside of an active transaction)."));
}
DiscoveryDataClusterState curState = globalState;
if (!curState.transition() && curState.state() == state) {
if (!state.active() || BaselineTopology.equals(curState.baselineTopology(), blt))
return new GridFinishedFuture<>();
}
GridChangeGlobalStateFuture startedFut = null;
GridChangeGlobalStateFuture fut = stateChangeFut.get();
while (fut == null || fut.isDone()) {
fut = new GridChangeGlobalStateFuture(UUID.randomUUID(), state, ctx);
if (stateChangeFut.compareAndSet(null, fut)) {
startedFut = fut;
break;
} else
fut = stateChangeFut.get();
}
if (startedFut == null) {
if (fut.state != state) {
return new GridFinishedFuture<>(new IgniteCheckedException("Failed to " + prettyStr(state) + ", because another state change operation is currently in progress: " + prettyStr(fut.state)));
} else
return fut;
}
List<StoredCacheData> storedCfgs = null;
if (activate(curState.state(), state) && !inMemoryMode) {
try {
Map<String, StoredCacheData> cfgs = ctx.cache().context().pageStore().readCacheConfigurations();
if (!F.isEmpty(cfgs)) {
storedCfgs = new ArrayList<>(cfgs.values());
IgniteDiscoverySpi spi = (IgniteDiscoverySpi) ctx.discovery().getInjectedDiscoverySpi();
boolean splittedCacheCfgs = spi.allNodesSupport(IgniteFeatures.SPLITTED_CACHE_CONFIGURATIONS);
storedCfgs = storedCfgs.stream().map(storedCacheData -> splittedCacheCfgs ? storedCacheData.withSplittedCacheConfig(ctx.cache().splitter()) : storedCacheData.withOldCacheConfig(ctx.cache().enricher())).collect(Collectors.toList());
}
} catch (IgniteCheckedException e) {
U.error(log, "Failed to read stored cache configurations: " + e, e);
startedFut.onDone(e);
return startedFut;
}
}
ChangeGlobalStateMessage msg = new ChangeGlobalStateMessage(startedFut.requestId, ctx.localNodeId(), storedCfgs, state, forceDeactivation, blt, forceChangeBaselineTopology, System.currentTimeMillis());
IgniteInternalFuture<?> resFut = wrapStateChangeFuture(startedFut, msg);
try {
U.log(log, "Sending " + prettyStr(state) + " request with BaselineTopology " + blt);
ctx.discovery().sendCustomEvent(msg);
if (ctx.isStopping()) {
startedFut.onDone(new IgniteCheckedException("Failed to execute " + prettyStr(state) + " request , node is stopping."));
}
} catch (IgniteCheckedException e) {
U.error(log, "Failed to send global state change request: " + prettyStr(state), e);
startedFut.onDone(e);
}
return resFut;
}
use of org.apache.ignite.internal.managers.discovery.IgniteDiscoverySpi in project ignite by apache.
the class IgniteClientReconnectStopTest method testStopWhenDisconnected.
/**
* @throws Exception If failed.
*/
@Test
public void testStopWhenDisconnected() throws Exception {
Ignite client = startClientGrid(serverCount());
assertTrue(client.cluster().localNode().isClient());
Ignite srv = clientRouter(client);
DiscoverySpi srvSpi = spi0(srv);
final CountDownLatch disconnectLatch = new CountDownLatch(1);
final CountDownLatch reconnectLatch = new CountDownLatch(1);
final IgniteDiscoverySpi clientSpi = spi0(client);
DiscoverySpiTestListener lsnr = new DiscoverySpiTestListener();
clientSpi.setInternalListener(lsnr);
log.info("Block reconnect.");
lsnr.startBlockJoin();
client.events().localListen(new IgnitePredicate<Event>() {
@Override
public boolean apply(Event evt) {
if (evt.type() == EVT_CLIENT_NODE_DISCONNECTED) {
info("Disconnected: " + evt);
disconnectLatch.countDown();
} else if (evt.type() == EVT_CLIENT_NODE_RECONNECTED) {
info("Reconnected: " + evt);
reconnectLatch.countDown();
}
return true;
}
}, EVT_CLIENT_NODE_DISCONNECTED, EVT_CLIENT_NODE_RECONNECTED);
srvSpi.failNode(client.cluster().localNode().id(), null);
waitReconnectEvent(disconnectLatch);
IgniteFuture<?> reconnectFut = null;
try {
client.getOrCreateCache(new CacheConfiguration<>(DEFAULT_CACHE_NAME));
fail();
} catch (IgniteClientDisconnectedException e) {
log.info("Expected operation exception: " + e);
reconnectFut = e.reconnectFuture();
}
assertNotNull(reconnectFut);
client.close();
try {
reconnectFut.get();
fail();
} catch (IgniteException e) {
log.info("Expected reconnect exception: " + e);
}
}
use of org.apache.ignite.internal.managers.discovery.IgniteDiscoverySpi in project ignite by apache.
the class InboundConnectionHandler method onFirstMessage.
/**
* @param ses Session.
* @param msg Message.
*/
private void onFirstMessage(final GridNioSession ses, Message msg) {
UUID sndId;
ConnectionKey connKey;
if (msg instanceof NodeIdMessage) {
sndId = U.bytesToUuid(((NodeIdMessage) msg).nodeIdBytes(), 0);
connKey = new ConnectionKey(sndId, 0, -1);
} else {
assert msg instanceof HandshakeMessage : msg;
HandshakeMessage msg0 = (HandshakeMessage) msg;
sndId = ((HandshakeMessage) msg).nodeId();
connKey = new ConnectionKey(sndId, msg0.connectionIndex(), msg0.connectCount());
}
if (log.isDebugEnabled())
log.debug("Remote node ID received: " + sndId);
final ClusterNode rmtNode = nodeGetter.apply(sndId);
if (rmtNode == null) {
DiscoverySpi discoverySpi = igniteExSupplier.get().configuration().getDiscoverySpi();
boolean unknownNode = true;
if (discoverySpi instanceof TcpDiscoverySpi) {
TcpDiscoverySpi tcpDiscoverySpi = (TcpDiscoverySpi) discoverySpi;
ClusterNode node0 = tcpDiscoverySpi.getNode0(sndId);
if (node0 != null) {
assert node0.isClient() : node0;
if (node0.version().compareTo(VERSION_SINCE_CLIENT_COULD_WAIT_TO_CONNECT) >= 0)
unknownNode = false;
}
} else if (discoverySpi instanceof IgniteDiscoverySpi)
unknownNode = !((IgniteDiscoverySpi) discoverySpi).knownNode(sndId);
if (unknownNode) {
U.warn(log, "Close incoming connection, unknown node [nodeId=" + sndId + ", ses=" + ses + ']');
ses.send(new RecoveryLastReceivedMessage(UNKNOWN_NODE)).listen(fut -> ses.close());
} else
ses.send(new RecoveryLastReceivedMessage(NEED_WAIT)).listen(fut -> ses.close());
return;
}
ses.addMeta(CONSISTENT_ID_META, rmtNode.consistentId());
final ConnectionKey old = ses.addMeta(CONN_IDX_META, connKey);
assert old == null;
ClusterNode locNode = locNodeSupplier.get();
if (ses.remoteAddress() == null)
return;
assert msg instanceof HandshakeMessage : msg;
HandshakeMessage msg0 = (HandshakeMessage) msg;
if (log.isDebugEnabled()) {
log.debug("Received handshake message [locNodeId=" + locNode.id() + ", rmtNodeId=" + sndId + ", msg=" + msg0 + ']');
}
if (isChannelConnIdx(msg0.connectionIndex()))
ses.send(new RecoveryLastReceivedMessage(0));
else if (cfg.usePairedConnections() && usePairedConnections(rmtNode, attributeNames.pairedConnection())) {
final GridNioRecoveryDescriptor recoveryDesc = nioSrvWrapper.inRecoveryDescriptor(rmtNode, connKey);
ConnectClosureNew c = new ConnectClosureNew(ses, recoveryDesc, rmtNode);
boolean reserve = recoveryDesc.tryReserve(msg0.connectCount(), c);
if (reserve)
connectedNew(recoveryDesc, ses, true);
else {
if (c.failed) {
ses.send(new RecoveryLastReceivedMessage(ALREADY_CONNECTED));
closeStaleConnections(connKey);
}
}
} else {
assert connKey.connectionIndex() >= 0 : connKey;
GridCommunicationClient[] curClients = clientPool.clientFor(sndId);
GridCommunicationClient oldClient = curClients != null && connKey.connectionIndex() < curClients.length ? curClients[connKey.connectionIndex()] : null;
if (oldClient instanceof GridTcpNioCommunicationClient) {
if (log.isInfoEnabled())
log.info("Received incoming connection when already connected " + "to this node, rejecting [locNode=" + locNode.id() + ", rmtNode=" + sndId + ']');
ses.send(new RecoveryLastReceivedMessage(ALREADY_CONNECTED));
closeStaleConnections(connKey);
return;
}
GridFutureAdapter<GridCommunicationClient> fut = new GridFutureAdapter<>();
GridFutureAdapter<GridCommunicationClient> oldFut = clientPool.putIfAbsentFut(connKey, fut);
final GridNioRecoveryDescriptor recoveryDesc = nioSrvWrapper.inRecoveryDescriptor(rmtNode, connKey);
if (oldFut == null) {
curClients = clientPool.clientFor(sndId);
oldClient = curClients != null && connKey.connectionIndex() < curClients.length ? curClients[connKey.connectionIndex()] : null;
if (oldClient instanceof GridTcpNioCommunicationClient) {
assert oldClient.connectionIndex() == connKey.connectionIndex() : oldClient;
if (log.isInfoEnabled())
log.info("Received incoming connection when already connected " + "to this node, rejecting [locNode=" + locNode.id() + ", rmtNode=" + sndId + ']');
ses.send(new RecoveryLastReceivedMessage(ALREADY_CONNECTED));
closeStaleConnections(connKey);
fut.onDone(oldClient);
return;
}
boolean reserved = recoveryDesc.tryReserve(msg0.connectCount(), new ConnectClosure(ses, recoveryDesc, rmtNode, connKey, msg0, true, fut));
if (log.isDebugEnabled()) {
log.debug("Received incoming connection from remote node " + "[rmtNode=" + rmtNode.id() + ", reserved=" + reserved + ", recovery=" + recoveryDesc + ']');
}
if (reserved) {
try {
GridTcpNioCommunicationClient client = connected(recoveryDesc, ses, rmtNode, msg0.received(), true, true);
fut.onDone(client);
} finally {
clientPool.removeFut(connKey, fut);
}
}
} else {
if (oldFut instanceof ConnectFuture && locNode.order() < rmtNode.order()) {
if (log.isInfoEnabled()) {
log.info("Received incoming connection from remote node while " + "connecting to this node, rejecting [locNode=" + locNode.id() + ", locNodeOrder=" + locNode.order() + ", rmtNode=" + rmtNode.id() + ", rmtNodeOrder=" + rmtNode.order() + ']');
}
ses.send(new RecoveryLastReceivedMessage(ALREADY_CONNECTED));
} else {
boolean reserved = recoveryDesc.tryReserve(msg0.connectCount(), new ConnectClosure(ses, recoveryDesc, rmtNode, connKey, msg0, true, fut));
GridTcpNioCommunicationClient client = null;
if (reserved)
client = connected(recoveryDesc, ses, rmtNode, msg0.received(), true, true);
if (oldFut instanceof ConnectionRequestFuture && !oldFut.isDone())
oldFut.onDone(client);
}
}
}
}
Aggregations