/* * 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.activemq.artemis.tests.integration.cluster.bridge; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.activemq.artemis.api.core.ActiveMQException; import org.apache.activemq.artemis.api.core.ActiveMQExceptionType; import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.TransportConfiguration; import org.apache.activemq.artemis.api.core.client.ActiveMQClient; import org.apache.activemq.artemis.api.core.client.ClientConsumer; import org.apache.activemq.artemis.api.core.client.ClientMessage; import org.apache.activemq.artemis.api.core.client.ClientProducer; import org.apache.activemq.artemis.api.core.client.ClientSession; import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; import org.apache.activemq.artemis.api.core.client.ServerLocator; import org.apache.activemq.artemis.api.core.management.QueueControl; import org.apache.activemq.artemis.api.core.management.ResourceNames; import org.apache.activemq.artemis.core.config.BridgeConfiguration; import org.apache.activemq.artemis.core.config.CoreQueueConfiguration; import org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnector; import org.apache.activemq.artemis.core.server.ActiveMQServer; import org.apache.activemq.artemis.core.server.NodeManager; import org.apache.activemq.artemis.core.server.Queue; import org.apache.activemq.artemis.core.server.cluster.Bridge; import org.apache.activemq.artemis.core.server.cluster.impl.BridgeImpl; import org.apache.activemq.artemis.core.server.impl.InVMNodeManager; import org.apache.activemq.artemis.core.server.management.ManagementService; import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection; import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger; import org.junit.Before; import org.junit.Test; public class BridgeReconnectTest extends BridgeTestBase { private static final IntegrationTestLogger log = IntegrationTestLogger.LOGGER; private static final int NUM_MESSAGES = 100; Map<String, Object> server0Params; Map<String, Object> server1Params; Map<String, Object> server2Params; ActiveMQServer server0; ActiveMQServer server1; ActiveMQServer server2; ServerLocator locator; ClientSession session0; ClientSession session1; ClientSession session2; private TransportConfiguration server1tc; private Map<String, TransportConfiguration> connectors; private ArrayList<String> staticConnectors; final String bridgeName = "bridge1"; final String testAddress = "testAddress"; final String queueName = "queue0"; final String forwardAddress = "forwardAddress"; final long retryInterval = 50; final double retryIntervalMultiplier = 1d; final int confirmationWindowSize = 1024; int reconnectAttempts = 3; @Override @Before public void setUp() throws Exception { super.setUp(); server0Params = new HashMap<>(); server1Params = new HashMap<>(); server2Params = new HashMap<>(); connectors = new HashMap<>(); server1 = createActiveMQServer(1, isNetty(), server1Params); server1tc = new TransportConfiguration(getConnector(), server1Params, "server1tc"); connectors.put(server1tc.getName(), server1tc); staticConnectors = new ArrayList<>(); staticConnectors.add(server1tc.getName()); } protected boolean isNetty() { return false; } /** * @return */ private String getConnector() { if (isNetty()) { return NETTY_CONNECTOR_FACTORY; } return INVM_CONNECTOR_FACTORY; } /** * Backups must successfully deploy its bridges on fail-over. * * @see https://bugzilla.redhat.com/show_bug.cgi?id=900764 */ @Test public void testFailoverDeploysBridge() throws Exception { NodeManager nodeManager = new InVMNodeManager(false); server0 = createActiveMQServer(0, server0Params, isNetty(), nodeManager); server2 = createBackupActiveMQServer(2, server2Params, isNetty(), 0, nodeManager); TransportConfiguration server0tc = new TransportConfiguration(getConnector(), server0Params, "server0tc"); TransportConfiguration server2tc = new TransportConfiguration(getConnector(), server2Params, "server2tc"); connectors.put(server2tc.getName(), server2tc); server0.getConfiguration().setConnectorConfigurations(connectors); server1.getConfiguration().setConnectorConfigurations(connectors); server2.getConfiguration().setConnectorConfigurations(connectors); reconnectAttempts = -1; BridgeConfiguration bridgeConfiguration = createBridgeConfig(); bridgeConfiguration.setQueueName(queueName); List<BridgeConfiguration> bridgeConfigs = new ArrayList<>(); bridgeConfigs.add(bridgeConfiguration); server0.getConfiguration().setBridgeConfigurations(bridgeConfigs); server2.getConfiguration().setBridgeConfigurations(bridgeConfigs); CoreQueueConfiguration queueConfig0 = new CoreQueueConfiguration().setAddress(testAddress).setName(queueName); List<CoreQueueConfiguration> queueConfigs0 = new ArrayList<>(); queueConfigs0.add(queueConfig0); server1.getConfiguration().setQueueConfigurations(queueConfigs0); CoreQueueConfiguration queueConfig1 = new CoreQueueConfiguration().setAddress(forwardAddress).setName(queueName); List<CoreQueueConfiguration> queueConfigs1 = new ArrayList<>(); queueConfigs1.add(queueConfig1); server0.getConfiguration().setQueueConfigurations(queueConfigs1); server2.getConfiguration().setQueueConfigurations(queueConfigs1); startServers(); waitForServerStart(server0); server0.stop(true); waitForServerStart(server2); locator = addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(server0tc, server2tc)); ClientSessionFactory csf0 = addSessionFactory(locator.createSessionFactory(server2tc)); session0 = csf0.createSession(false, true, true); Map<String, Bridge> bridges = server2.getClusterManager().getBridges(); assertTrue("backup must deploy bridge on failover", !bridges.isEmpty()); } // Fail bridge and reconnecting immediately @Test public void testFailoverAndReconnectImmediately() throws Exception { NodeManager nodeManager = new InVMNodeManager(false); server0 = createActiveMQServer(0, server0Params, isNetty(), nodeManager); server2 = createBackupActiveMQServer(2, server2Params, isNetty(), 0, nodeManager); TransportConfiguration server0tc = new TransportConfiguration(getConnector(), server0Params, "server0tc"); TransportConfiguration server2tc = new TransportConfiguration(getConnector(), server2Params, "server2tc"); connectors.put(server2tc.getName(), server2tc); server0.getConfiguration().setConnectorConfigurations(connectors); server1.getConfiguration().setConnectorConfigurations(connectors); reconnectAttempts = 1; BridgeConfiguration bridgeConfiguration = createBridgeConfig(); List<BridgeConfiguration> bridgeConfigs = new ArrayList<>(); bridgeConfigs.add(bridgeConfiguration); server0.getConfiguration().setBridgeConfigurations(bridgeConfigs); CoreQueueConfiguration queueConfig0 = new CoreQueueConfiguration().setAddress(testAddress).setName(queueName); List<CoreQueueConfiguration> queueConfigs0 = new ArrayList<>(); queueConfigs0.add(queueConfig0); server0.getConfiguration().setQueueConfigurations(queueConfigs0); CoreQueueConfiguration queueConfig1 = new CoreQueueConfiguration().setAddress(forwardAddress).setName(queueName); List<CoreQueueConfiguration> queueConfigs1 = new ArrayList<>(); queueConfigs1.add(queueConfig1); server1.getConfiguration().setQueueConfigurations(queueConfigs1); server2.getConfiguration().setQueueConfigurations(queueConfigs1); startServers(); BridgeReconnectTest.log.info("** failing connection"); // Now we will simulate a failure of the bridge connection between server0 and server1 server0.stop(true); waitForServerStart(server2); locator = addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(server0tc, server2tc)); ClientSessionFactory csf0 = addSessionFactory(locator.createSessionFactory(server2tc)); session0 = csf0.createSession(false, true, true); ClientProducer prod0 = session0.createProducer(testAddress); ClientSessionFactory csf2 = addSessionFactory(locator.createSessionFactory(server2tc)); session2 = csf2.createSession(false, true, true); ClientConsumer cons2 = session2.createConsumer(queueName); session2.start(); final int numMessages = NUM_MESSAGES; SimpleString propKey = new SimpleString("propkey"); for (int i = 0; i < numMessages; i++) { ClientMessage message = session0.createMessage(true); message.putIntProperty(propKey, i); prod0.send(message); } for (int i = 0; i < numMessages; i++) { ClientMessage r1 = cons2.receive(1500); assertNotNull(r1); assertEquals(i, r1.getObjectProperty(propKey)); } closeServers(); assertNoMoreConnections(); } private BridgeConfiguration createBridgeConfig() { return new BridgeConfiguration().setName(bridgeName).setQueueName(queueName).setForwardingAddress(forwardAddress).setRetryInterval(retryInterval).setRetryIntervalMultiplier(retryIntervalMultiplier).setReconnectAttempts(reconnectAttempts).setReconnectAttemptsOnSameNode(0).setConfirmationWindowSize(confirmationWindowSize).setStaticConnectors(staticConnectors).setPassword(CLUSTER_PASSWORD); } // Fail bridge and attempt failover a few times before succeeding @Test public void testFailoverAndReconnectAfterAFewTries() throws Exception { NodeManager nodeManager = new InVMNodeManager(false); server0 = createActiveMQServer(0, server0Params, isNetty(), nodeManager); server2 = createBackupActiveMQServer(2, server2Params, isNetty(), 0, nodeManager); TransportConfiguration server2tc = new TransportConfiguration(getConnector(), server2Params, "server2tc"); connectors.put(server2tc.getName(), server2tc); server0.getConfiguration().setConnectorConfigurations(connectors); server1.getConfiguration().setConnectorConfigurations(connectors); BridgeConfiguration bridgeConfiguration = createBridgeConfig(); List<BridgeConfiguration> bridgeConfigs = new ArrayList<>(); bridgeConfigs.add(bridgeConfiguration); server0.getConfiguration().setBridgeConfigurations(bridgeConfigs); CoreQueueConfiguration queueConfig0 = new CoreQueueConfiguration().setAddress(testAddress).setName(queueName); List<CoreQueueConfiguration> queueConfigs0 = new ArrayList<>(); queueConfigs0.add(queueConfig0); server0.getConfiguration().setQueueConfigurations(queueConfigs0); CoreQueueConfiguration queueConfig1 = new CoreQueueConfiguration().setAddress(forwardAddress).setName(queueName); List<CoreQueueConfiguration> queueConfigs1 = new ArrayList<>(); queueConfigs1.add(queueConfig1); server1.getConfiguration().setQueueConfigurations(queueConfigs1); server2.getConfiguration().setQueueConfigurations(queueConfigs1); startServers(); // Now we will simulate a failure of the bridge connection between server0 and server1 server0.stop(true); locator = addServerLocator(ActiveMQClient.createServerLocatorWithHA(server2tc)).setReconnectAttempts(100); ClientSessionFactory csf0 = addSessionFactory(locator.createSessionFactory(server2tc)); session0 = csf0.createSession(false, true, true); ClientSessionFactory csf2 = addSessionFactory(locator.createSessionFactory(server2tc)); session2 = csf2.createSession(false, true, true); ClientProducer prod0 = session0.createProducer(testAddress); ClientConsumer cons2 = session2.createConsumer(queueName); session2.start(); final int numMessages = NUM_MESSAGES; SimpleString propKey = new SimpleString("propkey"); for (int i = 0; i < numMessages; i++) { ClientMessage message = session0.createMessage(false); message.putIntProperty(propKey, i); prod0.send(message); } for (int i = 0; i < numMessages; i++) { ClientMessage r1 = cons2.receive(1500); assertNotNull(r1); assertEquals(i, r1.getObjectProperty(propKey)); } closeServers(); assertNoMoreConnections(); } // Fail bridge and reconnect same node, no backup specified @Test public void testReconnectSameNode() throws Exception { server0 = createActiveMQServer(0, isNetty(), server0Params); TransportConfiguration server0tc = new TransportConfiguration(getConnector(), server0Params, "server0tc"); server0.getConfiguration().setConnectorConfigurations(connectors); server1.getConfiguration().setConnectorConfigurations(connectors); BridgeConfiguration bridgeConfiguration = createBridgeConfig(); List<BridgeConfiguration> bridgeConfigs = new ArrayList<>(); bridgeConfigs.add(bridgeConfiguration); server0.getConfiguration().setBridgeConfigurations(bridgeConfigs); CoreQueueConfiguration queueConfig0 = new CoreQueueConfiguration().setAddress(testAddress).setName(queueName); List<CoreQueueConfiguration> queueConfigs0 = new ArrayList<>(); queueConfigs0.add(queueConfig0); server0.getConfiguration().setQueueConfigurations(queueConfigs0); CoreQueueConfiguration queueConfig1 = new CoreQueueConfiguration().setAddress(forwardAddress).setName(queueName); List<CoreQueueConfiguration> queueConfigs1 = new ArrayList<>(); queueConfigs1.add(queueConfig1); server1.getConfiguration().setQueueConfigurations(queueConfigs1); startServers(); locator = addServerLocator(ActiveMQClient.createServerLocatorWithHA(server0tc, server1tc)); ClientSessionFactory csf0 = locator.createSessionFactory(server0tc); session0 = csf0.createSession(false, true, true); ClientSessionFactory csf1 = locator.createSessionFactory(server1tc); session1 = csf1.createSession(false, true, true); ClientProducer prod0 = session0.createProducer(testAddress); ClientConsumer cons1 = session1.createConsumer(queueName); session1.start(); // Now we will simulate a failure of the bridge connection between server0 and server1 Bridge bridge = server0.getClusterManager().getBridges().get(bridgeName); assertNotNull(bridge); RemotingConnection forwardingConnection = getForwardingConnection(bridge); InVMConnector.failOnCreateConnection = true; InVMConnector.numberOfFailures = reconnectAttempts - 1; forwardingConnection.fail(new ActiveMQNotConnectedException()); forwardingConnection = getForwardingConnection(bridge); forwardingConnection.fail(new ActiveMQNotConnectedException()); final ManagementService managementService = server0.getManagementService(); QueueControl coreQueueControl = (QueueControl) managementService.getResource(ResourceNames.QUEUE + queueName); assertEquals(0, coreQueueControl.getDeliveringCount()); final int numMessages = NUM_MESSAGES; SimpleString propKey = new SimpleString("propkey"); for (int i = 0; i < numMessages; i++) { ClientMessage message = session0.createMessage(false); message.putIntProperty(propKey, i); prod0.send(message); } for (int i = 0; i < numMessages; i++) { ClientMessage r1 = cons1.receive(1500); assertNotNull(r1); assertEquals(i, r1.getObjectProperty(propKey)); } closeServers(); assertNoMoreConnections(); } // We test that we can pause more than client failure check period (to prompt the pinger to failing) // before reconnecting @Test public void testShutdownServerCleanlyAndReconnectSameNodeWithSleep() throws Exception { testShutdownServerCleanlyAndReconnectSameNode(true); } @Test public void testShutdownServerCleanlyAndReconnectSameNode() throws Exception { testShutdownServerCleanlyAndReconnectSameNode(false); } private void testShutdownServerCleanlyAndReconnectSameNode(final boolean sleep) throws Exception { server0 = createActiveMQServer(0, isNetty(), server0Params); TransportConfiguration server0tc = new TransportConfiguration(getConnector(), server0Params, "server0tc"); server0.getConfiguration().setConnectorConfigurations(connectors); server1.getConfiguration().setConnectorConfigurations(connectors); reconnectAttempts = -1; final long clientFailureCheckPeriod = 1000; BridgeConfiguration bridgeConfiguration = new BridgeConfiguration().setName(bridgeName).setQueueName(queueName).setForwardingAddress(forwardAddress).setClientFailureCheckPeriod(clientFailureCheckPeriod).setRetryInterval(retryInterval).setRetryIntervalMultiplier(retryIntervalMultiplier).setReconnectAttempts(reconnectAttempts).setReconnectAttemptsOnSameNode(0).setConfirmationWindowSize(confirmationWindowSize).setStaticConnectors(staticConnectors).setPassword(CLUSTER_PASSWORD); List<BridgeConfiguration> bridgeConfigs = new ArrayList<>(); bridgeConfigs.add(bridgeConfiguration); server0.getConfiguration().setBridgeConfigurations(bridgeConfigs); CoreQueueConfiguration queueConfig0 = new CoreQueueConfiguration().setAddress(testAddress).setName(queueName); List<CoreQueueConfiguration> queueConfigs0 = new ArrayList<>(); queueConfigs0.add(queueConfig0); server0.getConfiguration().setQueueConfigurations(queueConfigs0); CoreQueueConfiguration queueConfig1 = new CoreQueueConfiguration().setAddress(forwardAddress).setName(queueName); List<CoreQueueConfiguration> queueConfigs1 = new ArrayList<>(); queueConfigs1.add(queueConfig1); server1.getConfiguration().setQueueConfigurations(queueConfigs1); startServers(); waitForServerStart(server0); waitForServerStart(server1); locator = addServerLocator(ActiveMQClient.createServerLocatorWithHA(server0tc, server1tc)); ClientSessionFactory csf0 = locator.createSessionFactory(server0tc); session0 = csf0.createSession(false, true, true); ClientProducer prod0 = session0.createProducer(testAddress); BridgeReconnectTest.log.info("stopping server1"); server1.stop(); if (sleep) { Thread.sleep(2 * clientFailureCheckPeriod); } BridgeReconnectTest.log.info("restarting server1"); server1.start(); BridgeReconnectTest.log.info("server 1 restarted"); ClientSessionFactory csf1 = locator.createSessionFactory(server1tc); session1 = csf1.createSession(false, true, true); ClientConsumer cons1 = session1.createConsumer(queueName); session1.start(); final int numMessages = NUM_MESSAGES; SimpleString propKey = new SimpleString("propkey"); for (int i = 0; i < numMessages; i++) { ClientMessage message = session0.createMessage(false); message.putIntProperty(propKey, i); prod0.send(message); } BridgeReconnectTest.log.info("sent messages"); for (int i = 0; i < numMessages; i++) { ClientMessage r1 = cons1.receive(30000); assertNotNull("received expected msg", r1); assertEquals("property value matches", i, r1.getObjectProperty(propKey)); BridgeReconnectTest.log.info("got message " + r1.getObjectProperty(propKey)); } BridgeReconnectTest.log.info("got messages"); closeServers(); assertNoMoreConnections(); } /** * @throws Exception */ private void closeServers() throws Exception { if (session0 != null) session0.close(); if (session1 != null) session1.close(); if (session2 != null) session2.close(); if (locator != null) { locator.close(); } server0.stop(); server1.stop(); if (server2 != null) server2.stop(); } private void assertNoMoreConnections() { assertEquals(0, server0.getRemotingService().getConnections().size()); assertEquals(0, server1.getRemotingService().getConnections().size()); if (server2 != null) assertEquals(0, server2.getRemotingService().getConnections().size()); } @Test public void testFailoverThenFailAgainAndReconnect() throws Exception { server0 = createActiveMQServer(0, isNetty(), server0Params); TransportConfiguration server0tc = new TransportConfiguration(getConnector(), server0Params, "server0tc"); server0.getConfiguration().setConnectorConfigurations(connectors); BridgeConfiguration bridgeConfiguration = createBridgeConfig(); List<BridgeConfiguration> bridgeConfigs = new ArrayList<>(); bridgeConfigs.add(bridgeConfiguration); server0.getConfiguration().setBridgeConfigurations(bridgeConfigs); CoreQueueConfiguration queueConfig0 = new CoreQueueConfiguration().setAddress(testAddress).setName(queueName); List<CoreQueueConfiguration> queueConfigs0 = new ArrayList<>(); queueConfigs0.add(queueConfig0); server0.getConfiguration().setQueueConfigurations(queueConfigs0); CoreQueueConfiguration queueConfig1 = new CoreQueueConfiguration().setAddress(forwardAddress).setName(queueName); List<CoreQueueConfiguration> queueConfigs1 = new ArrayList<>(); queueConfigs1.add(queueConfig1); server1.getConfiguration().setQueueConfigurations(queueConfigs1); startServers(); locator = addServerLocator(ActiveMQClient.createServerLocatorWithHA(server0tc, server1tc)); ClientSessionFactory csf0 = locator.createSessionFactory(server0tc); session0 = csf0.createSession(false, true, true); ClientSessionFactory csf1 = locator.createSessionFactory(server1tc); session1 = csf1.createSession(false, true, true); ClientProducer prod0 = session0.createProducer(testAddress); ClientConsumer cons1 = session1.createConsumer(queueName); session1.start(); Bridge bridge = server0.getClusterManager().getBridges().get(bridgeName); RemotingConnection forwardingConnection = getForwardingConnection(bridge); InVMConnector.failOnCreateConnection = true; InVMConnector.numberOfFailures = reconnectAttempts - 1; forwardingConnection.fail(new ActiveMQNotConnectedException()); final int numMessages = NUM_MESSAGES; SimpleString propKey = new SimpleString("propkey"); for (int i = 0; i < numMessages; i++) { ClientMessage message = session0.createMessage(false); message.putIntProperty(propKey, i); prod0.send(message); } int outOfOrder = -1; int supposed = -1; for (int i = 0; i < numMessages; i++) { ClientMessage r1 = cons1.receive(1500); assertNotNull(r1); if (outOfOrder == -1 && i != r1.getIntProperty(propKey).intValue()) { outOfOrder = r1.getIntProperty(propKey).intValue(); supposed = i; } } if (outOfOrder != -1) { fail("Message " + outOfOrder + " was received out of order, it was supposed to be " + supposed); } log.info("=========== second failure, sending message"); // Fail again - should reconnect forwardingConnection = ((BridgeImpl) bridge).getForwardingConnection(); InVMConnector.failOnCreateConnection = true; InVMConnector.numberOfFailures = reconnectAttempts - 1; forwardingConnection.fail(new ActiveMQException(ActiveMQExceptionType.UNBLOCKED)); for (int i = 0; i < numMessages; i++) { ClientMessage message = session0.createMessage(false); message.putIntProperty(propKey, i); prod0.send(message); } for (int i = 0; i < numMessages; i++) { ClientMessage r1 = cons1.receive(1500); assertNotNull("Didn't receive message", r1); if (outOfOrder == -1 && i != r1.getIntProperty(propKey).intValue()) { outOfOrder = r1.getIntProperty(propKey).intValue(); supposed = i; } } if (outOfOrder != -1) { fail("Message " + outOfOrder + " was received out of order, it was supposed to be " + supposed); } closeServers(); assertNoMoreConnections(); } @Test public void testDeliveringCountOnBridgeConnectionFailure() throws Exception { server0 = createActiveMQServer(0, isNetty(), server0Params); TransportConfiguration server0tc = new TransportConfiguration(getConnector(), server0Params, "server0tc"); server0.getConfiguration().setConnectorConfigurations(connectors); BridgeConfiguration bridgeConfiguration = createBridgeConfig(); List<BridgeConfiguration> bridgeConfigs = new ArrayList<>(); bridgeConfigs.add(bridgeConfiguration); server0.getConfiguration().setBridgeConfigurations(bridgeConfigs); CoreQueueConfiguration queueConfig0 = new CoreQueueConfiguration().setAddress(testAddress).setName(queueName); List<CoreQueueConfiguration> queueConfigs0 = new ArrayList<>(); queueConfigs0.add(queueConfig0); server0.getConfiguration().setQueueConfigurations(queueConfigs0); CoreQueueConfiguration queueConfig1 = new CoreQueueConfiguration().setAddress(forwardAddress).setName(queueName); List<CoreQueueConfiguration> queueConfigs1 = new ArrayList<>(); queueConfigs1.add(queueConfig1); server1.getConfiguration().setQueueConfigurations(queueConfigs1); startServers(); locator = addServerLocator(ActiveMQClient.createServerLocatorWithHA(server0tc, server1tc)); ClientSessionFactory csf0 = locator.createSessionFactory(server0tc); session0 = csf0.createSession(false, true, true); ClientSessionFactory csf1 = locator.createSessionFactory(server1tc); session1 = csf1.createSession(false, true, true); ClientProducer prod0 = session0.createProducer(testAddress); session1.start(); Bridge bridge = server0.getClusterManager().getBridges().get(bridgeName); RemotingConnection forwardingConnection = getForwardingConnection(bridge); InVMConnector.failOnCreateConnection = true; InVMConnector.numberOfFailures = reconnectAttempts - 1; //forwardingConnection.fail(new ActiveMQNotConnectedException()); final int numMessages = NUM_MESSAGES; SimpleString propKey = new SimpleString("propkey"); final Queue queue = (Queue) server0.getPostOffice().getBinding(new SimpleString(queueName)).getBindable(); System.out.println("DeliveringCount: " + queue.getDeliveringCount()); for (int i = 0; i < numMessages; i++) { ClientMessage message = session0.createMessage(false); message.putIntProperty(propKey, i); prod0.send(message); if (i == 50) { forwardingConnection.fail(new ActiveMQException(ActiveMQExceptionType.UNBLOCKED)); } } for (int i = 0; i < 100 && queue.getDeliveringCount() != 0; i++) { Thread.sleep(10); } System.out.println("Check.. DeliveringCount: " + queue.getDeliveringCount()); assertEquals("Delivering count of a source queue should be zero on connection failure", 0, queue.getDeliveringCount()); closeServers(); assertNoMoreConnections(); } private void startServers() throws Exception { if (server2 != null) server2.start(); server1.start(); server0.start(); } private RemotingConnection getForwardingConnection(final Bridge bridge) throws Exception { long start = System.currentTimeMillis(); do { RemotingConnection forwardingConnection = ((BridgeImpl) bridge).getForwardingConnection(); if (forwardingConnection != null) { return forwardingConnection; } Thread.sleep(10); } while (System.currentTimeMillis() - start < 50000); throw new IllegalStateException("Failed to get forwarding connection"); } }