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 9823b0e IGNITE-11332 Added ability to drop node from discovery through JMX - Fixes #6120. 9823b0e is described below commit 9823b0e8a47fadfaad357c2debc440d679061ab1 Author: Evgeny Stanilovskiy <estanilovs...@gridgain.com> AuthorDate: Tue Feb 26 15:46:26 2019 +0300 IGNITE-11332 Added ability to drop node from discovery through JMX - Fixes #6120. Signed-off-by: Alexey Goncharuk <alexey.goncha...@gmail.com> --- .../ignite/spi/discovery/DiscoverySpiMBean.java | 8 ++ .../ignite/spi/discovery/tcp/TcpDiscoverySpi.java | 18 ++++ .../discovery/tcp/TcpDiscoverySpiMBeanTest.java | 97 ++++++++++++++++++++++ .../spi/discovery/zk/ZookeeperDiscoverySpi.java | 18 ++++ 4 files changed, 141 insertions(+) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/DiscoverySpiMBean.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/DiscoverySpiMBean.java index d86a497..069fdad 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/DiscoverySpiMBean.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/DiscoverySpiMBean.java @@ -81,4 +81,12 @@ public interface DiscoverySpiMBean { */ @MXBeanDescription("Local node formatted as a string.") public String getLocalNodeFormatted(); + + /** + * Exclude node from discovery. + * + * @param nodeId Node id string. + */ + @MXBeanDescription("Exclude node from cluster.") + public void excludeNode(String nodeId); } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java index 981a2e4..b5f08a4 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java @@ -2503,6 +2503,24 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter implements IgniteDiscovery } /** {@inheritDoc} */ + @Override public void excludeNode(String nodeId) { + UUID node; + + try { + node = UUID.fromString(nodeId); + } + catch (IllegalArgumentException e) { + U.error(log, "Failed to parse node ID: " + nodeId, e); + + return; + } + + String msg = "Node excluded, node=" + nodeId + "using JMX interface, initiator=" + getLocalNodeId(); + + impl.failNode(node, msg); + } + + /** {@inheritDoc} */ @Override public void dumpDebugInfo() { impl.dumpDebugInfo(log); } diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpiMBeanTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpiMBeanTest.java index 1a1b6d1..5222897 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpiMBeanTest.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpiMBeanTest.java @@ -17,18 +17,31 @@ package org.apache.ignite.spi.discovery.tcp; +import org.apache.ignite.Ignite; +import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.events.Event; import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.util.typedef.G; import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; import org.apache.ignite.testframework.GridStringLogger; +import org.apache.ignite.testframework.GridTestUtils; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import javax.management.JMX; import javax.management.MBeanServer; import javax.management.ObjectName; import java.lang.management.ManagementFactory; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; + import org.junit.Test; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.apache.ignite.events.EventType.EVT_NODE_FAILED; +import static org.apache.ignite.events.EventType.EVT_NODE_SEGMENTED; + /** * Tests TcpDiscoverySpiMBean. */ @@ -45,6 +58,10 @@ public class TcpDiscoverySpiMBeanTest extends GridCommonAbstractTest { TcpDiscoverySpi tcpSpi = new TcpDiscoverySpi(); tcpSpi.setIpFinder(IP_FINDER); cfg.setDiscoverySpi(tcpSpi); + + if ("client".equals(igniteInstanceName)) + cfg.setClientMode(true); + cfg.setGridLogger(strLog); return cfg; @@ -81,4 +98,84 @@ public class TcpDiscoverySpiMBeanTest extends GridCommonAbstractTest { stopAllGrids(); } } + + /** + * Tests TcpDiscoverySpiMBean#excludeNode. + * + * @throws Exception if fails. + */ + @Test + public void testNodeExclusion() throws Exception { + try { + int srvCnt = 2; + + IgniteEx grid0 = (IgniteEx)startGrids(srvCnt); + + IgniteEx client; + + client = startGrid("client"); + + MBeanServer srv = ManagementFactory.getPlatformMBeanServer(); + + ObjectName spiName = U.makeMBeanName(grid0.context().igniteInstanceName(), "SPIs", + TcpDiscoverySpi.class.getSimpleName()); + + TcpDiscoverySpiMBean bean = JMX.newMBeanProxy(srv, spiName, TcpDiscoverySpiMBean.class); + + assertEquals(grid0.cluster().forServers().nodes().size(), srvCnt); + + assertEquals(grid0.cluster().forClients().nodes().size(), 1); + + UUID clientId = client.localNode().id(); + + bean.excludeNode(clientId.toString()); + + assertTrue(GridTestUtils.waitForCondition(() -> + grid0.cluster().forClients().nodes().size() == 1, 5_000)); + + assertTrue(GridTestUtils.waitForCondition(() -> + grid0.cluster().forClients().node(clientId) == null, 5_000)); + + assertTrue(strLog.toString().contains("Node excluded, node=")); + + bean.excludeNode(new UUID(0, 0).toString()); + + bean.excludeNode("fakeUUID"); + + assertEquals(grid0.cluster().forServers().nodes().size(), srvCnt); + + ClusterNode node = grid0.cluster().forServers().nodes().stream().filter(n -> n.id() != grid0.localNode().id()) + .findFirst().get(); + + assertNotNull(node); + + final CountDownLatch cnt = new CountDownLatch(1); + + Ignite segmentedNode = G.allGrids().stream().filter(id -> id.cluster().localNode().id().equals(node.id())) + .findAny().get(); + + assertNotNull(segmentedNode); + + segmentedNode.events().localListen(new IgnitePredicate<Event>() { + @Override public boolean apply(Event evt) { + cnt.countDown(); + + return false; + } + }, EVT_NODE_SEGMENTED); + + bean.excludeNode(node.id().toString()); + + assertTrue(GridTestUtils.waitForCondition(() -> + grid0.cluster().forServers().nodes().size() == srvCnt - 1, 5_000)); + + assertTrue("Next node have to be failed within failureDetectionTimeout", + cnt.await(grid0.configuration().getFailureDetectionTimeout() + 3000, MILLISECONDS)); + + bean.excludeNode(grid0.localNode().id().toString()); + } + finally { + stopAllGrids(); + } + } } diff --git a/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpi.java b/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpi.java index 6326770..44ce423 100644 --- a/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpi.java +++ b/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpi.java @@ -624,6 +624,24 @@ public class ZookeeperDiscoverySpi extends IgniteSpiAdapter implements IgniteDis } /** {@inheritDoc} */ + @Override public void excludeNode(String nodeId) { + UUID node; + + try { + node = UUID.fromString(nodeId); + } + catch (IllegalArgumentException e) { + U.error(log, "Failed to parse node ID: " + nodeId, e); + + return; + } + + String msg = "Node excluded, node=" + nodeId + "using JMX interface, initiator=" + getLocalNodeId(); + + impl.failNode(node, msg); + } + + /** {@inheritDoc} */ @Override public String getZkConnectionString() { return zkConnectionString; }