Search in sources :

Example 1 with TcpDiscoveryNodeAddFinishedMessage

use of org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddFinishedMessage in project ignite by apache.

the class TcpDiscoveryNodeJoinAndFailureTest method testConnectingNodesStopIfNoConnectedNodeIsPresented.

/**
 * If whole ring fails but two server nodes both in CONNECTING state remain alive they should not hang
 * indefinitely sending join requests to each other.
 *
 * @see <a href="https://issues.apache.org/jira/browse/IGNITE-11621">IGNITE-11621</a>
 * with comments provides detailed description of this corner case.
 *
 * @throws Exception If failed.
 */
@Test
@WithSystemProperty(key = IgniteSystemProperties.IGNITE_DUMP_THREADS_ON_FAILURE, value = "false")
public void testConnectingNodesStopIfNoConnectedNodeIsPresented() throws Exception {
    /*
            Test reproduces the needed behavior (two nodes in CONNECTING state) doing the following:
                - it starts two regular nodes, node0 (coordinator) and node1 (just another server) with special
                  discovery SPIs;
                - when node1 receives NodeAddFinished for subsequently started node2, it doesn't send it to the node
                  but closes disco socket to node2 leaving it in CONNECTING state and generating NodeFailed for it.
                  Also at this moment node3 is started;
                - when node0 receives this NodeFailed it fails (because special SPI throws an exception) and stops;
                - when node1 receives another join request from node2 or NodeAdded from node3 reaches it back,
                  node1's special SPI also throws an exception so it goes down as well;
                - as a result, both node2 and node3 get stuck in CONNECTING state and as they use special IpFinders
                  they see each other and are able to send join requests to each other back and forth.

            The whole purpose of the test is to verify that these two nodes won't stuck in CONNECTING state forever
            and will eventually stop.
         */
    usePortFromNodeName = true;
    final AtomicInteger joinReqsCntr = new AtomicInteger(0);
    final AtomicReference<IgniteInternalFuture> futureRef = new AtomicReference();
    final UUID node2Id = UUID.randomUUID();
    final TcpDiscoverySpi node0SpecialSpi = new TcpDiscoverySpi() {

        @Override
        protected void startMessageProcess(TcpDiscoveryAbstractMessage msg) {
            if (msg instanceof TcpDiscoveryNodeFailedMessage) {
                TcpDiscoveryNodeFailedMessage failedMsg = (TcpDiscoveryNodeFailedMessage) msg;
                UUID failedNodeId = failedMsg.failedNodeId();
                if (failedNodeId.equals(node2Id))
                    throw new RuntimeException("Stop node0 exception");
            }
            if (msg instanceof TcpDiscoveryJoinRequestMessage) {
                TcpDiscoveryJoinRequestMessage joinReq = (TcpDiscoveryJoinRequestMessage) msg;
                if (joinReq.node().id().equals(node2Id))
                    joinReqsCntr.incrementAndGet();
            }
        }
    };
    final TcpDiscoverySpi node1SpecialSpi = new TcpDiscoverySpi() {

        @Override
        protected void startMessageProcess(TcpDiscoveryAbstractMessage msg) {
            if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) {
                TcpDiscoveryNodeAddFinishedMessage finishedMsg = (TcpDiscoveryNodeAddFinishedMessage) msg;
                UUID nodeId = finishedMsg.nodeId();
                if (nodeId.equals(node2Id)) {
                    Object workerObj = GridTestUtils.getFieldValue(impl, "msgWorker");
                    OutputStream out = GridTestUtils.getFieldValue(workerObj, "out");
                    try {
                        out.close();
                        log.warning("Out to 'sick' node closed");
                    } catch (Exception ignored) {
                    // No-op.
                    }
                    futureRef.set(GridTestUtils.runAsync(() -> {
                        try {
                            startGrid(NODE_WITH_PORT_ID_3);
                        } catch (Exception ignored) {
                        // NO-op.
                        }
                    }));
                }
            }
            if (msg instanceof TcpDiscoveryJoinRequestMessage) {
                TcpDiscoveryJoinRequestMessage joinReq = (TcpDiscoveryJoinRequestMessage) msg;
                int joinReqsCount = joinReqsCntr.get();
                if (joinReq.node().id().equals(node2Id) && joinReqsCount == 1)
                    throw new RuntimeException("Stop node1 exception by subsequent join req");
            }
            if (msg instanceof TcpDiscoveryNodeAddedMessage) {
                TcpDiscoveryNodeAddedMessage addedMsg = (TcpDiscoveryNodeAddedMessage) msg;
                if (addedMsg.node().discoveryPort() == 47503)
                    throw new RuntimeException("Stop node1 exception by new node added msg");
            }
        }
    };
    specialSpi = node0SpecialSpi;
    startGrid(NODE_WITH_PORT_ID_0);
    specialSpi = node1SpecialSpi;
    startGrid(NODE_WITH_PORT_ID_1);
    specialIpFinder0 = new TcpDiscoveryVmIpFinder(false);
    ((TcpDiscoveryVmIpFinder) specialIpFinder0).setAddresses(Arrays.asList("127.0.0.1:47501", "127.0.0.1:47503"));
    specialIpFinder1 = new TcpDiscoveryVmIpFinder(false);
    ((TcpDiscoveryVmIpFinder) specialIpFinder1).setAddresses(Arrays.asList("127.0.0.1:47502"));
    specialSpi = null;
    nodeId = node2Id;
    boolean expectedExceptionThrown = false;
    try {
        startGrid(NODE_WITH_PORT_ID_2);
    } catch (Exception e) {
        Throwable cause0 = e.getCause();
        assertNotNull(cause0);
        Throwable cause1 = cause0.getCause();
        assertNotNull(cause1);
        String errorMsg = cause1.getMessage();
        assertTrue("Expected error message was not found: " + errorMsg, errorMsg.contains("Failed to connect to any address from IP finder"));
        expectedExceptionThrown = true;
    }
    assertTrue("Expected exception was not thrown.", expectedExceptionThrown);
    IgniteInternalFuture startGridFut = futureRef.get();
    if (startGridFut != null)
        startGridFut.get();
}
Also used : TcpDiscoveryVmIpFinder(org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder) OutputStream(java.io.OutputStream) AtomicReference(java.util.concurrent.atomic.AtomicReference) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) TcpDiscoveryNodeFailedMessage(org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeFailedMessage) TcpDiscoveryNodeAddFinishedMessage(org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddFinishedMessage) TcpDiscoveryAbstractMessage(org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryAbstractMessage) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TcpDiscoveryNodeAddedMessage(org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddedMessage) UUID(java.util.UUID) TcpDiscoveryJoinRequestMessage(org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryJoinRequestMessage) GridCommonAbstractTest(org.apache.ignite.testframework.junits.common.GridCommonAbstractTest) Test(org.junit.Test) WithSystemProperty(org.apache.ignite.testframework.junits.WithSystemProperty)

Aggregations

OutputStream (java.io.OutputStream)1 UUID (java.util.UUID)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)1 TcpDiscoveryVmIpFinder (org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder)1 TcpDiscoveryAbstractMessage (org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryAbstractMessage)1 TcpDiscoveryJoinRequestMessage (org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryJoinRequestMessage)1 TcpDiscoveryNodeAddFinishedMessage (org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddFinishedMessage)1 TcpDiscoveryNodeAddedMessage (org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddedMessage)1 TcpDiscoveryNodeFailedMessage (org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeFailedMessage)1 WithSystemProperty (org.apache.ignite.testframework.junits.WithSystemProperty)1 GridCommonAbstractTest (org.apache.ignite.testframework.junits.common.GridCommonAbstractTest)1 Test (org.junit.Test)1