/* * 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.extras.jms.bridge; import javax.jms.Connection; import javax.jms.DeliveryMode; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.TextMessage; import javax.management.MBeanServer; import javax.management.ObjectName; import javax.transaction.Transaction; import javax.transaction.TransactionManager; import java.lang.management.ManagementFactory; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.activemq.artemis.api.jms.ActiveMQJMSConstants; import org.apache.activemq.artemis.jms.bridge.ConnectionFactoryFactory; import org.apache.activemq.artemis.jms.bridge.QualityOfServiceMode; import org.apache.activemq.artemis.jms.bridge.impl.JMSBridgeImpl; import org.apache.activemq.artemis.jms.client.ActiveMQMessage; import org.apache.activemq.artemis.service.extensions.ServiceUtils; import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger; import org.apache.activemq.artemis.tests.integration.ra.DummyTransactionManager; import org.apache.activemq.artemis.utils.DefaultSensitiveStringCodec; import org.junit.Assert; import org.junit.Test; public class JMSBridgeTest extends BridgeTestBase { private static final IntegrationTestLogger log = IntegrationTestLogger.LOGGER; // MaxBatchSize but no MaxBatchTime @Test public void testNoMaxBatchTime_AtMostOnce_P() throws Exception { testNoMaxBatchTime(QualityOfServiceMode.AT_MOST_ONCE, true); } @Test public void testNoMaxBatchTime_DuplicatesOk_P() throws Exception { testNoMaxBatchTime(QualityOfServiceMode.DUPLICATES_OK, true); } @Test public void testNoMaxBatchTime_OnceAndOnlyOnce_P() throws Exception { testNoMaxBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true); } @Test public void testNoMaxBatchTime_AtMostOnce_NP() throws Exception { testNoMaxBatchTime(QualityOfServiceMode.AT_MOST_ONCE, false); } @Test public void testNoMaxBatchTime_DuplicatesOk_NP() throws Exception { testNoMaxBatchTime(QualityOfServiceMode.DUPLICATES_OK, false); } @Test public void testNoMaxBatchTime_OnceAndOnlyOnce_NP() throws Exception { testNoMaxBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false); } // Same server // MaxBatchSize but no MaxBatchTime @Test public void testNoMaxBatchTimeSameServer_AtMostOnce_P() throws Exception { testNoMaxBatchTimeSameServer(QualityOfServiceMode.AT_MOST_ONCE, true); } @Test public void testNoMaxBatchTimeSameServer_DuplicatesOk_P() throws Exception { testNoMaxBatchTimeSameServer(QualityOfServiceMode.DUPLICATES_OK, true); } @Test public void testNoMaxBatchTimeSameServer_OnceAndOnlyOnce_P() throws Exception { testNoMaxBatchTimeSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true); } @Test public void testNoMaxBatchTimeSameServer_AtMostOnce_NP() throws Exception { testNoMaxBatchTimeSameServer(QualityOfServiceMode.AT_MOST_ONCE, false); } @Test public void testNoMaxBatchTimeSameServer_DuplicatesOk_NP() throws Exception { testNoMaxBatchTimeSameServer(QualityOfServiceMode.DUPLICATES_OK, false); } @Test public void testNoMaxBatchTimeSameServer_OnceAndOnlyOnce_NP() throws Exception { testNoMaxBatchTimeSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false); } // MaxBatchTime but no MaxBatchSize @Test public void testMaxBatchTime_AtMostOnce_P() throws Exception { testMaxBatchTime(QualityOfServiceMode.AT_MOST_ONCE, true); } @Test public void testMaxBatchTime_DuplicatesOk_P() throws Exception { testMaxBatchTime(QualityOfServiceMode.DUPLICATES_OK, true); } @Test public void testMaxBatchTime_OnceAndOnlyOnce_P() throws Exception { testMaxBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true); } @Test public void testMaxBatchTime_AtMostOnce_NP() throws Exception { testMaxBatchTime(QualityOfServiceMode.AT_MOST_ONCE, false); } @Test public void testMaxBatchTime_DuplicatesOk_NP() throws Exception { testMaxBatchTime(QualityOfServiceMode.DUPLICATES_OK, false); } @Test public void testMaxBatchTime_OnceAndOnlyOnce_NP() throws Exception { testMaxBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false); } // Same server // MaxBatchTime but no MaxBatchSize @Test public void testMaxBatchTimeSameServer_AtMostOnce_P() throws Exception { testMaxBatchTimeSameServer(QualityOfServiceMode.AT_MOST_ONCE, true); } @Test public void testMaxBatchTimeSameServer_DuplicatesOk_P() throws Exception { testMaxBatchTimeSameServer(QualityOfServiceMode.DUPLICATES_OK, true); } @Test public void testMaxBatchTimeSameServer_OnceAndOnlyOnce_P() throws Exception { testMaxBatchTimeSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true); } @Test public void testMaxBatchTimeSameServer_AtMostOnce_NP() throws Exception { testMaxBatchTimeSameServer(QualityOfServiceMode.AT_MOST_ONCE, false); } @Test public void testMaxBatchTimeSameServer_DuplicatesOk_NP() throws Exception { testMaxBatchTimeSameServer(QualityOfServiceMode.DUPLICATES_OK, false); } @Test public void testMaxBatchTimeSameServer_OnceAndOnlyOnce_NP() throws Exception { testMaxBatchTimeSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false); } // Stress with batch size of 50 @Test public void testStress_AtMostOnce_P_50() throws Exception { testStress(QualityOfServiceMode.AT_MOST_ONCE, true, 50); } @Test public void testStress_DuplicatesOk_P_50() throws Exception { testStress(QualityOfServiceMode.DUPLICATES_OK, true, 50); } @Test public void testStress_OnceAndOnlyOnce_P_50() throws Exception { testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 50); } @Test public void testStress_AtMostOnce_NP_50() throws Exception { testStress(QualityOfServiceMode.AT_MOST_ONCE, false, 50); } @Test public void testStress_DuplicatesOk_NP_50() throws Exception { testStress(QualityOfServiceMode.DUPLICATES_OK, false, 50); } @Test public void testStress_OnceAndOnlyOnce_NP_50() throws Exception { testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 50); } // Stress with batch size of 1 @Test public void testStress_AtMostOnce_P_1() throws Exception { testStress(QualityOfServiceMode.AT_MOST_ONCE, true, 1); } @Test public void testStress_DuplicatesOk_P_1() throws Exception { testStress(QualityOfServiceMode.DUPLICATES_OK, true, 1); } @Test public void testStress_OnceAndOnlyOnce_P_1() throws Exception { testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 1); } @Test public void testStress_AtMostOnce_NP_1() throws Exception { testStress(QualityOfServiceMode.AT_MOST_ONCE, false, 1); } @Test public void testStress_DuplicatesOk_NP_1() throws Exception { testStress(QualityOfServiceMode.DUPLICATES_OK, false, 1); } @Test public void testStress_OnceAndOnlyOnce_NP_1() throws Exception { testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 1); } // Max batch time @Test public void testStressMaxBatchTime_OnceAndOnlyOnce_NP() throws Exception { testStressBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 200); } @Test public void testStressMaxBatchTime_OnceAndOnlyOnce_P() throws Exception { testStressBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 200); } // Stress on same server // Stress with batch size of 50 @Test public void testStressSameServer_AtMostOnce_P_50() throws Exception { testStressSameServer(QualityOfServiceMode.AT_MOST_ONCE, true, 50); } @Test public void testStressSameServer_DuplicatesOk_P_50() throws Exception { testStressSameServer(QualityOfServiceMode.DUPLICATES_OK, true, 50); } @Test public void testStressSameServer_OnceAndOnlyOnce_P_50() throws Exception { testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 50); } @Test public void testStressSameServer_AtMostOnce_NP_50() throws Exception { testStressSameServer(QualityOfServiceMode.AT_MOST_ONCE, false, 50); } @Test public void testStressSameServer_DuplicatesOk_NP_50() throws Exception { testStressSameServer(QualityOfServiceMode.DUPLICATES_OK, false, 50); } @Test public void testStressSameServer_OnceAndOnlyOnce_NP_50() throws Exception { testStressSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 50); } // Stress with batch size of 1 @Test public void testStressSameServer_AtMostOnce_P_1() throws Exception { testStressSameServer(QualityOfServiceMode.AT_MOST_ONCE, true, 1); } @Test public void testStressSameServer_DuplicatesOk_P_1() throws Exception { testStressSameServer(QualityOfServiceMode.DUPLICATES_OK, true, 1); } @Test public void testStressSameServer_OnceAndOnlyOnce_P_1() throws Exception { testStressSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 1); } @Test public void testStressSameServer_AtMostOnce_NP_1() throws Exception { testStressSameServer(QualityOfServiceMode.AT_MOST_ONCE, false, 1); } @Test public void testStressSameServer_DuplicatesOk_NP_1() throws Exception { testStressSameServer(QualityOfServiceMode.DUPLICATES_OK, false, 1); } @Test public void testStressSameServer_OnceAndOnlyOnce_NP_1() throws Exception { testStressSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 1); } @Test public void testStartBridgeFirst() throws Exception { //stop the source server, we want to start the bridge first jmsServer0.stop(); JMSBridgeImpl bridge = null; ConnectionFactoryFactory factInUse0 = cff0; ConnectionFactoryFactory factInUse1 = cff1; try { final int NUM_MESSAGES = 10; bridge = new JMSBridgeImpl(factInUse0, factInUse1, sourceQueueFactory, targetQueueFactory, null, null, null, null, null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE, NUM_MESSAGES, -1, null, null, false).setBridgeName("test-bridge"); bridge.start(); //now start the server jmsServer0.start(); createQueue("sourceQueue", 0); createQueue("localTargetQueue", 0); jmsServer0.createTopic(false, "sourceTopic", "/topic/sourceTopic"); // Send half the messages sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES / 2, false, false); // Verify none are received checkEmpty(targetQueue, 1); // Send the other half sendMessages(cf0, sourceQueue, NUM_MESSAGES / 2, NUM_MESSAGES / 2, false, false); // This should now be receivable checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES, false); // Send another batch with one more than batch size sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES + 1, false, false); // Make sure only batch size are received checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES, false); // Final batch sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES - 1, false, false); checkAllMessageReceivedInOrder(cf1, targetQueue, NUM_MESSAGES, 1, false); checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES - 1, false); } finally { if (bridge != null) { JMSBridgeTest.log.info("Stopping bridge"); bridge.stop(); } } } @Test public void testParams() throws Exception { JMSBridgeImpl bridge = null; QualityOfServiceMode qosMode = QualityOfServiceMode.AT_MOST_ONCE; int batchSize = 10; int maxBatchTime = -1; String sourceUsername = null; String sourcePassword = null; String destUsername = null; String destPassword = null; String selector = null; long failureRetryInterval = 5000; int maxRetries = 10; String subName = null; String clientID = null; try { bridge = new JMSBridgeImpl(null, cff1, sourceQueueFactory, targetQueueFactory, sourceUsername, sourcePassword, destUsername, destPassword, selector, failureRetryInterval, maxRetries, qosMode, batchSize, maxBatchTime, subName, clientID, false).setBridgeName("test-bridge"); fail("expected exception"); } catch (IllegalArgumentException e) { // Ok } finally { stopComponent(bridge); } try { bridge = new JMSBridgeImpl(cff0, null, sourceQueueFactory, targetQueueFactory, sourceUsername, sourcePassword, destUsername, destPassword, selector, failureRetryInterval, maxRetries, qosMode, batchSize, maxBatchTime, subName, clientID, false).setBridgeName("test-bridge"); fail("expected exception"); } catch (IllegalArgumentException e) { // Ok } finally { stopComponent(bridge); } try { bridge = new JMSBridgeImpl(cff0, cff1, null, targetQueueFactory, sourceUsername, sourcePassword, destUsername, destPassword, selector, failureRetryInterval, maxRetries, qosMode, batchSize, maxBatchTime, subName, clientID, false).setBridgeName("test-bridge"); fail("expected exception"); } catch (IllegalArgumentException e) { // Ok } finally { stopComponent(bridge); } try { bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, null, sourceUsername, sourcePassword, destUsername, destPassword, selector, failureRetryInterval, maxRetries, qosMode, batchSize, maxBatchTime, subName, clientID, false).setBridgeName("test-bridge"); fail("expected exception"); } catch (IllegalArgumentException e) { // Ok } finally { stopComponent(bridge); } try { bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory, sourceUsername, sourcePassword, destUsername, destPassword, selector, -2, maxRetries, qosMode, batchSize, maxBatchTime, subName, clientID, false).setBridgeName("test-bridge"); fail("expected exception"); } catch (IllegalArgumentException e) { // Ok } finally { stopComponent(bridge); } try { bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory, sourceUsername, sourcePassword, destUsername, destPassword, selector, -1, 10, qosMode, batchSize, maxBatchTime, subName, clientID, false).setBridgeName("test-bridge"); fail("expected exception"); } catch (IllegalArgumentException e) { // Ok } finally { stopComponent(bridge); } try { bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, null, sourceUsername, sourcePassword, destUsername, destPassword, selector, failureRetryInterval, maxRetries, qosMode, 0, maxBatchTime, subName, clientID, false).setBridgeName("test-bridge"); fail("expected exception"); } catch (IllegalArgumentException e) { // Ok } finally { stopComponent(bridge); } try { bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, null, sourceUsername, sourcePassword, destUsername, destPassword, selector, failureRetryInterval, maxRetries, qosMode, batchSize, -2, subName, clientID, false).setBridgeName("test-bridge"); fail("expected exception"); } catch (IllegalArgumentException e) { // Ok } finally { stopComponent(bridge); } } @Test public void testStartStopStart() throws Exception { JMSBridgeImpl bridge = null; Connection connSource = null; Connection connTarget = null; try { final int NUM_MESSAGES = 10; bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory, null, null, null, null, null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE, 1, -1, null, null, false).setBridgeName("test-bridge"); bridge.start(); bridge.stop(); bridge.start(); connSource = cf0.createConnection(); Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sessSend.createProducer(sourceQueue); for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = sessSend.createTextMessage("message" + i); prod.send(tm); } connTarget = cf1.createConnection(); Session sessRec = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer cons = sessRec.createConsumer(targetQueue); connTarget.start(); for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = (TextMessage) cons.receive(10000); Assert.assertNotNull(tm); Assert.assertEquals("message" + i, tm.getText()); } Message m = cons.receiveNoWait(); Assert.assertNull(m); } finally { if (connSource != null) { connSource.close(); } if (connTarget != null) { connTarget.close(); } if (bridge != null) { bridge.stop(); } removeAllMessages(sourceQueue.getQueueName(), 0); } } @Test public void testSelector() throws Exception { JMSBridgeImpl bridge = null; Connection connSource = null; Connection connTarget = null; try { final int NUM_MESSAGES = 10; String selector = "vegetable='radish'"; bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory, null, null, null, null, selector, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE, 1, -1, null, null, false).setBridgeName("test-bridge"); bridge.start(); connSource = cf0.createConnection(); Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sessSend.createProducer(sourceQueue); for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = sessSend.createTextMessage("message" + i); if (i >= NUM_MESSAGES / 2) { tm.setStringProperty("vegetable", "radish"); } else { tm.setStringProperty("vegetable", "cauliflower"); } prod.send(tm); } connTarget = cf1.createConnection(); Session sessRec = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer cons = sessRec.createConsumer(targetQueue); connTarget.start(); for (int i = NUM_MESSAGES / 2; i < NUM_MESSAGES; i++) { TextMessage tm = (TextMessage) cons.receive(10000); Assert.assertNotNull(tm); Assert.assertEquals("message" + i, tm.getText()); } Message m = cons.receiveNoWait(); Assert.assertNull(m); } finally { if (connSource != null) { connSource.close(); } if (connTarget != null) { connTarget.close(); } if (bridge != null) { bridge.stop(); } removeAllMessages(sourceQueue.getQueueName(), 0); } } @Test public void testMaskPassword() throws Exception { JMSBridgeImpl bridge = null; Connection connSource = null; Connection connTarget = null; DefaultSensitiveStringCodec codec = new DefaultSensitiveStringCodec(); String mask = (String) codec.encode("guest"); try { final int NUM_MESSAGES = 10; bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory, "guest", mask, "guest", mask, null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE, 1, -1, null, null, false).setBridgeName("test-bridge"); bridge.setUseMaskedPassword(true); bridge.start(); connSource = cf0.createConnection(); Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sessSend.createProducer(sourceQueue); for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = sessSend.createTextMessage("message" + i); prod.send(tm); } connTarget = cf1.createConnection(); Session sessRec = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer cons = sessRec.createConsumer(targetQueue); connTarget.start(); for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = (TextMessage) cons.receive(10000); Assert.assertNotNull(tm); Assert.assertEquals("message" + i, tm.getText()); } Message m = cons.receiveNoWait(); Assert.assertNull(m); } finally { if (connSource != null) { connSource.close(); } if (connTarget != null) { connTarget.close(); } if (bridge != null) { bridge.stop(); } removeAllMessages(sourceQueue.getQueueName(), 0); } } @Test public void testPasswordCodec() throws Exception { JMSBridgeImpl bridge = null; Connection connSource = null; Connection connTarget = null; DefaultSensitiveStringCodec codec = new DefaultSensitiveStringCodec(); Map<String, String> prop = new HashMap<>(); prop.put("key", "bridgekey"); codec.init(prop); String mask = (String) codec.encode("guest"); try { final int NUM_MESSAGES = 10; bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory, "guest", mask, "guest", mask, null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE, 1, -1, null, null, false).setBridgeName("test-bridge"); bridge.setUseMaskedPassword(true); bridge.setPasswordCodec(codec.getClass().getName() + ";key=bridgekey"); bridge.start(); connSource = cf0.createConnection(); Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sessSend.createProducer(sourceQueue); for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = sessSend.createTextMessage("message" + i); prod.send(tm); } connTarget = cf1.createConnection(); Session sessRec = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer cons = sessRec.createConsumer(targetQueue); connTarget.start(); for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = (TextMessage) cons.receive(10000); Assert.assertNotNull(tm); Assert.assertEquals("message" + i, tm.getText()); } Message m = cons.receiveNoWait(); Assert.assertNull(m); } finally { if (connSource != null) { connSource.close(); } if (connTarget != null) { connTarget.close(); } if (bridge != null) { bridge.stop(); } removeAllMessages(sourceQueue.getQueueName(), 0); } } @Test public void testStartBridgeWithJTATransactionAlreadyRunningLargeMessage() throws Exception { internalTestStartBridgeWithJTATransactionAlreadyRunning(true); } @Test public void testStartBridgeWithJTATransactionAlreadyRunningRegularMessage() throws Exception { internalTestStartBridgeWithJTATransactionAlreadyRunning(false); } public void internalTestStartBridgeWithJTATransactionAlreadyRunning(final boolean largeMessage) throws Exception { JMSBridgeImpl bridge = null; Transaction toResume = null; Transaction started = null; TransactionManager mgr = newTransactionManager(); try { toResume = mgr.suspend(); mgr.begin(); started = mgr.getTransaction(); final int NUM_MESSAGES = 10; bridge = new JMSBridgeImpl(cff0, cff1, sourceTopicFactory, targetQueueFactory, null, null, null, null, null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE, 1, -1, null, null, false).setBridgeName("test-bridge"); bridge.start(); sendMessages(cf0, sourceTopic, 0, NUM_MESSAGES, false, largeMessage); checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES, largeMessage); } finally { if (started != null) { try { started.rollback(); } catch (Exception e) { JMSBridgeTest.log.error("Failed to rollback", e); } } if (toResume != null) { try { mgr.resume(toResume); } catch (Exception e) { JMSBridgeTest.log.error("Failed to resume", e); } } if (bridge != null) { bridge.stop(); } } } @Test public void testNonDurableSubscriberLargeMessage() throws Exception { internalTestNonDurableSubscriber(true, 1); } @Test public void testNonDurableSubscriberRegularMessage() throws Exception { internalTestNonDurableSubscriber(false, 1); } public void internalTestNonDurableSubscriber(final boolean largeMessage, final int batchSize) throws Exception { JMSBridgeImpl bridge = null; try { final int NUM_MESSAGES = 10; bridge = new JMSBridgeImpl(cff0, cff1, sourceTopicFactory, targetQueueFactory, null, null, null, null, null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE, batchSize, -1, null, null, false).setBridgeName("test-bridge"); bridge.start(); sendMessages(cf0, sourceTopic, 0, NUM_MESSAGES, false, largeMessage); checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES, largeMessage); } finally { if (bridge != null) { bridge.stop(); } } } @Test public void testDurableSubscriberLargeMessage() throws Exception { internalTestDurableSubscriber(true, 1); } @Test public void testDurableSubscriberRegularMessage() throws Exception { internalTestDurableSubscriber(false, 1); } public void internalTestDurableSubscriber(final boolean largeMessage, final int batchSize) throws Exception { JMSBridgeImpl bridge = null; try { final int NUM_MESSAGES = 10; bridge = new JMSBridgeImpl(cff0, cff1, sourceTopicFactory, targetQueueFactory, null, null, null, null, null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE, batchSize, -1, "subTest", "clientid123", false).setBridgeName("test-bridge"); bridge.start(); sendMessages(cf0, sourceTopic, 0, NUM_MESSAGES, true, largeMessage); checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES, largeMessage); } finally { if (bridge != null) { bridge.stop(); } // Now unsubscribe Connection conn = cf0.createConnection(); conn.setClientID("clientid123"); Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); sess.unsubscribe("subTest"); conn.close(); } } @Test public void testMessageIDInHeaderOn() throws Exception { messageIDInHeader(true); } @Test public void testMessageIDInHeaderOff() throws Exception { messageIDInHeader(false); } private void messageIDInHeader(final boolean on) throws Exception { JMSBridgeImpl bridge = null; Connection connSource = null; Connection connTarget = null; try { final int NUM_MESSAGES = 10; bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory, null, null, null, null, null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE, 1, -1, null, null, on); bridge.start(); connSource = cf0.createConnection(); connTarget = cf1.createConnection(); JMSBridgeTest.log.trace("Sending " + NUM_MESSAGES + " messages"); List<String> ids1 = new ArrayList<>(); Session sessSource = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sessSource.createProducer(sourceQueue); for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = sessSource.createTextMessage("message" + i); // We add some properties to make sure they get passed through ok tm.setStringProperty("wib", "uhuh"); tm.setBooleanProperty("cheese", true); tm.setIntProperty("Sausages", 23); tm.setByteProperty("bacon", (byte) 12); tm.setDoubleProperty("toast", 17261762.12121d); tm.setFloatProperty("orange", 1212.1212f); tm.setLongProperty("blurg", 817217827L); tm.setShortProperty("stst", (short) 26363); //Set some JMS headers too //And also set a core props ((ActiveMQMessage) tm).getCoreMessage().putBytesProperty("bytes", new byte[]{1, 2, 3}); // We add some JMSX ones too tm.setStringProperty("JMSXGroupID", "mygroup543"); prod.send(tm); ids1.add(tm.getJMSMessageID()); } JMSBridgeTest.log.trace("Sent the first messages"); Session sessTarget = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer cons = sessTarget.createConsumer(targetQueue); connTarget.start(); List<TextMessage> msgs = new ArrayList<>(); for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = (TextMessage) cons.receive(5000); Assert.assertNotNull(tm); Assert.assertEquals("message" + i, tm.getText()); Assert.assertEquals("uhuh", tm.getStringProperty("wib")); Assert.assertTrue(tm.getBooleanProperty("cheese")); Assert.assertEquals(23, tm.getIntProperty("Sausages")); assertEquals((byte) 12, tm.getByteProperty("bacon")); assertEquals(17261762.12121d, tm.getDoubleProperty("toast"), 0.000000001); assertEquals(1212.1212f, tm.getFloatProperty("orange"), 0.000001); assertEquals(817217827L, tm.getLongProperty("blurg")); assertEquals((short) 26363, tm.getShortProperty("stst")); assertEqualsByteArrays(new byte[]{1, 2, 3}, ((ActiveMQMessage) tm).getCoreMessage().getBytesProperty("bytes")); Assert.assertEquals("mygroup543", tm.getStringProperty("JMSXGroupID")); if (on) { String header = tm.getStringProperty(ActiveMQJMSConstants.AMQ_MESSAGING_BRIDGE_MESSAGE_ID_LIST); Assert.assertNotNull(header); Assert.assertEquals(ids1.get(i), header); msgs.add(tm); } } if (on) { // Now we send them again back to the source Iterator<TextMessage> iter = msgs.iterator(); List<String> ids2 = new ArrayList<>(); while (iter.hasNext()) { Message msg = iter.next(); prod.send(msg); ids2.add(msg.getJMSMessageID()); } // And consume them again for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = (TextMessage) cons.receive(5000); Assert.assertNotNull(tm); Assert.assertEquals("message" + i, tm.getText()); Assert.assertEquals("uhuh", tm.getStringProperty("wib")); Assert.assertTrue(tm.getBooleanProperty("cheese")); Assert.assertEquals(23, tm.getIntProperty("Sausages")); assertEquals((byte) 12, tm.getByteProperty("bacon")); assertEquals(17261762.12121d, tm.getDoubleProperty("toast"), 0.000001); assertEquals(1212.1212f, tm.getFloatProperty("orange"), 0.0000001); assertEquals(817217827L, tm.getLongProperty("blurg")); assertEquals((short) 26363, tm.getShortProperty("stst")); assertEqualsByteArrays(new byte[]{1, 2, 3}, ((ActiveMQMessage) tm).getCoreMessage().getBytesProperty("bytes")); Assert.assertEquals("mygroup543", tm.getStringProperty("JMSXGroupID")); String header = tm.getStringProperty(ActiveMQJMSConstants.AMQ_MESSAGING_BRIDGE_MESSAGE_ID_LIST); Assert.assertNotNull(header); Assert.assertEquals(ids1.get(i) + "," + ids2.get(i), header); } } } finally { if (bridge != null) { bridge.stop(); } if (connSource != null) { connSource.close(); } if (connTarget != null) { connTarget.close(); } } } @Test public void testPropertiesPreservedPOn() throws Exception { propertiesPreserved(true, true); } @Test public void testPropertiesPreservedNPoff() throws Exception { propertiesPreserved(false, true); } @Test public void testPropertiesPreservedNPOn() throws Exception { propertiesPreserved(false, true); } @Test public void testPropertiesPreservedPoff() throws Exception { propertiesPreserved(true, true); } private void propertiesPreserved(final boolean persistent, final boolean messageIDInHeader) throws Exception { JMSBridgeImpl bridge = null; Connection connSource = null; Connection connTarget = null; try { final int NUM_MESSAGES = 10; bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory, null, null, null, null, null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE, 1, -1, null, null, messageIDInHeader).setBridgeName("test-bridge"); bridge.start(); connSource = cf0.createConnection(); connTarget = cf1.createConnection(); JMSBridgeTest.log.trace("Sending " + NUM_MESSAGES + " messages"); Session sessSource = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sessTarget = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer cons = sessTarget.createConsumer(targetQueue); connTarget.start(); MessageProducer prod = sessSource.createProducer(sourceQueue); prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT); TextMessage tm = sessSource.createTextMessage("blahmessage"); prod.setPriority(7); prod.setTimeToLive(1 * 60 * 60 * 1000); prod.send(tm); long expiration = tm.getJMSExpiration(); Assert.assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode()); tm = (TextMessage) cons.receive(1000); Assert.assertNotNull(tm); Assert.assertEquals("blahmessage", tm.getText()); Assert.assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode()); Assert.assertEquals(7, tm.getJMSPriority()); Assert.assertTrue(Math.abs(expiration - tm.getJMSExpiration()) < 100); Message m = cons.receive(5000); Assert.assertNull(m); // Now do one with expiration = 0 tm = sessSource.createTextMessage("blahmessage2"); prod.setPriority(7); prod.setTimeToLive(0); prod.send(tm); Assert.assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode()); tm = (TextMessage) cons.receive(1000); Assert.assertNotNull(tm); Assert.assertEquals("blahmessage2", tm.getText()); Assert.assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode()); Assert.assertEquals(7, tm.getJMSPriority()); Assert.assertEquals(0, tm.getJMSExpiration()); m = cons.receive(5000); Assert.assertNull(m); tm = sessSource.createTextMessage("blahmessage3"); final boolean myBool = false; final byte myByte = (byte) 23; final double myDouble = 17625765d; final float myFloat = 87127.23f; final int myInt = 123; final long myLong = 81728712; final short myShort = (short) 88; final String myString = "ojweodewj"; final String myJMSX = "aardvark"; tm.setBooleanProperty("mybool", myBool); tm.setByteProperty("mybyte", myByte); tm.setDoubleProperty("mydouble", myDouble); tm.setFloatProperty("myfloat", myFloat); tm.setIntProperty("myint", myInt); tm.setLongProperty("mylong", myLong); tm.setShortProperty("myshort", myShort); tm.setStringProperty("mystring", myString); tm.setStringProperty("JMSXMyNaughtyJMSXProperty", myJMSX); prod.send(tm); tm = (TextMessage) cons.receive(5000); Assert.assertNotNull(tm); Assert.assertEquals("blahmessage3", tm.getText()); Assert.assertEquals(myBool, tm.getBooleanProperty("mybool")); Assert.assertEquals(myByte, tm.getByteProperty("mybyte")); Assert.assertEquals(myDouble, tm.getDoubleProperty("mydouble"), 0.000001); Assert.assertEquals(myFloat, tm.getFloatProperty("myfloat"), 0.000001); Assert.assertEquals(myInt, tm.getIntProperty("myint")); Assert.assertEquals(myLong, tm.getLongProperty("mylong")); Assert.assertEquals(myShort, tm.getShortProperty("myshort")); Assert.assertEquals(myString, tm.getStringProperty("mystring")); Assert.assertEquals(myJMSX, tm.getStringProperty("JMSXMyNaughtyJMSXProperty")); m = cons.receive(5000); } finally { if (bridge != null) { bridge.stop(); } if (connSource != null) { connSource.close(); } if (connTarget != null) { connTarget.close(); } } } @Test public void testNoMessageIDInHeader() throws Exception { JMSBridgeImpl bridge = null; Connection connSource = null; Connection connTarget = null; try { final int NUM_MESSAGES = 10; bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory, null, null, null, null, null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE, 1, -1, null, null, false).setBridgeName("test-bridge"); bridge.start(); connSource = cf0.createConnection(); connTarget = cf1.createConnection(); JMSBridgeTest.log.trace("Sending " + NUM_MESSAGES + " messages"); Session sessSource = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sessSource.createProducer(sourceQueue); for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = sessSource.createTextMessage("message" + i); // We add some headers to make sure they get passed through ok tm.setStringProperty("wib", "uhuh"); tm.setBooleanProperty("cheese", true); tm.setIntProperty("Sausages", 23); prod.send(tm); } JMSBridgeTest.log.trace("Sent the first messages"); Session sessTarget = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer cons = sessTarget.createConsumer(targetQueue); connTarget.start(); for (int i = 0; i < NUM_MESSAGES; i++) { TextMessage tm = (TextMessage) cons.receive(5000); Assert.assertNotNull(tm); Assert.assertEquals("message" + i, tm.getText()); Assert.assertEquals("uhuh", tm.getStringProperty("wib")); Assert.assertTrue(tm.getBooleanProperty("cheese")); Assert.assertEquals(23, tm.getIntProperty("Sausages")); String header = tm.getStringProperty(ActiveMQJMSConstants.AMQ_MESSAGING_BRIDGE_MESSAGE_ID_LIST); Assert.assertNull(header); } } finally { if (bridge != null) { bridge.stop(); } if (connSource != null) { connSource.close(); } if (connTarget != null) { connTarget.close(); } } } // Private ------------------------------------------------------------------------------- private void testStress(final QualityOfServiceMode qosMode, final boolean persistent, final int batchSize) throws Exception { Connection connSource = null; JMSBridgeImpl bridge = null; Thread t = null; ConnectionFactoryFactory factInUse0 = cff0; ConnectionFactoryFactory factInUse1 = cff1; if (qosMode.equals(QualityOfServiceMode.ONCE_AND_ONLY_ONCE)) { factInUse0 = cff0xa; factInUse1 = cff1xa; ServiceUtils.setTransactionManager(newTransactionManager()); } try { bridge = new JMSBridgeImpl(factInUse0, factInUse1, sourceQueueFactory, targetQueueFactory, null, null, null, null, null, 5000, 10, qosMode, batchSize, -1, null, null, false).setBridgeName("test-bridge"); bridge.start(); connSource = cf0.createConnection(); Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sessSend.createProducer(sourceQueue); final int NUM_MESSAGES = 250; StressSender sender = new StressSender(); sender.sess = sessSend; sender.prod = prod; sender.numMessages = NUM_MESSAGES; prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT); t = new Thread(sender); t.start(); checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES, false); t.join(); if (sender.ex != null) { // An error occurred during the send throw sender.ex; } } finally { if (t != null) { t.join(10000); } if (connSource != null) { try { connSource.close(); } catch (Exception e) { JMSBridgeTest.log.error("Failed to close connection", e); } } if (bridge != null) { bridge.stop(); } } } private void testStressBatchTime(final QualityOfServiceMode qosMode, final boolean persistent, final int maxBatchTime) throws Exception { Connection connSource = null; JMSBridgeImpl bridge = null; Thread t = null; ConnectionFactoryFactory factInUse0 = cff0; ConnectionFactoryFactory factInUse1 = cff1; if (qosMode.equals(QualityOfServiceMode.ONCE_AND_ONLY_ONCE)) { factInUse0 = cff0xa; factInUse1 = cff1xa; ServiceUtils.setTransactionManager(newTransactionManager()); } try { bridge = new JMSBridgeImpl(factInUse0, factInUse1, sourceQueueFactory, targetQueueFactory, null, null, null, null, null, 5000, 10, qosMode, 2, maxBatchTime, null, null, false).setBridgeName("test-bridge"); bridge.start(); connSource = cf0.createConnection(); Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sessSend.createProducer(sourceQueue); final int NUM_MESSAGES = 500; StressSender sender = new StressSender(); sender.sess = sessSend; sender.prod = prod; sender.numMessages = NUM_MESSAGES; prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT); t = new Thread(sender); t.start(); checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES, false); t.join(); if (sender.ex != null) { // An error occurred during the send throw sender.ex; } } finally { if (t != null) { t.join(10000); } if (connSource != null) { try { connSource.close(); } catch (Exception e) { JMSBridgeTest.log.error("Failed to close connection", e); } } if (bridge != null) { bridge.stop(); } } } // Both source and destination on same rm private void testStressSameServer(final QualityOfServiceMode qosMode, final boolean persistent, final int batchSize) throws Exception { Connection connSource = null; JMSBridgeImpl bridge = null; Thread t = null; ConnectionFactoryFactory factInUse0 = cff0; if (qosMode.equals(QualityOfServiceMode.ONCE_AND_ONLY_ONCE)) { factInUse0 = cff0xa; } try { bridge = new JMSBridgeImpl(factInUse0, factInUse0, sourceQueueFactory, localTargetQueueFactory, null, null, null, null, null, 5000, 10, qosMode, batchSize, -1, null, null, false).setBridgeName("test-bridge"); bridge.start(); connSource = cf0.createConnection(); Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer prod = sessSend.createProducer(sourceQueue); final int NUM_MESSAGES = 200; StressSender sender = new StressSender(); sender.sess = sessSend; sender.prod = prod; sender.numMessages = NUM_MESSAGES; prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT); t = new Thread(sender); t.start(); checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES, false); t.join(); if (sender.ex != null) { // An error occurred during the send throw sender.ex; } } finally { if (t != null) { t.join(10000); } if (connSource != null) { try { connSource.close(); } catch (Exception e) { JMSBridgeTest.log.error("Failed to close connection", e); } } if (bridge != null) { bridge.stop(); } } } private void testNoMaxBatchTime(final QualityOfServiceMode qosMode, final boolean persistent) throws Exception { JMSBridgeImpl bridge = null; ConnectionFactoryFactory factInUse0 = cff0; ConnectionFactoryFactory factInUse1 = cff1; if (qosMode.equals(QualityOfServiceMode.ONCE_AND_ONLY_ONCE)) { factInUse0 = cff0xa; factInUse1 = cff1xa; ServiceUtils.setTransactionManager(newTransactionManager()); } try { final int NUM_MESSAGES = 10; bridge = new JMSBridgeImpl(factInUse0, factInUse1, sourceQueueFactory, targetQueueFactory, null, null, null, null, null, 5000, 10, qosMode, NUM_MESSAGES, -1, null, null, false).setBridgeName("test-bridge"); bridge.start(); // Send half the messages sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES / 2, persistent, false); // Verify none are received checkEmpty(targetQueue, 1); // Send the other half sendMessages(cf0, sourceQueue, NUM_MESSAGES / 2, NUM_MESSAGES / 2, persistent, false); // This should now be receivable checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES, false); // Send another batch with one more than batch size sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES + 1, persistent, false); // Make sure only batch size are received checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES, false); // Final batch sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES - 1, persistent, false); checkAllMessageReceivedInOrder(cf1, targetQueue, NUM_MESSAGES, 1, false); checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES - 1, false); } finally { if (bridge != null) { JMSBridgeTest.log.info("Stopping bridge"); bridge.stop(); } } } private void testNoMaxBatchTimeSameServer(final QualityOfServiceMode qosMode, final boolean persistent) throws Exception { JMSBridgeImpl bridge = null; ConnectionFactoryFactory factInUse0 = cff0; if (qosMode.equals(QualityOfServiceMode.ONCE_AND_ONLY_ONCE)) { factInUse0 = cff0xa; ServiceUtils.setTransactionManager(newTransactionManager()); } try { final int NUM_MESSAGES = 10; bridge = new JMSBridgeImpl(factInUse0, factInUse0, sourceQueueFactory, localTargetQueueFactory, null, null, null, null, null, 5000, 10, qosMode, NUM_MESSAGES, -1, null, null, false).setBridgeName("test-bridge"); bridge.start(); sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES / 2, persistent, false); checkEmpty(targetQueue, 1); // Send the other half sendMessages(cf0, sourceQueue, NUM_MESSAGES / 2, NUM_MESSAGES / 2, persistent, false); // This should now be receivable checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES, false); checkEmpty(localTargetQueue, 0); checkEmpty(sourceQueue, 0); // Send another batch with one more than batch size sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES + 1, persistent, false); // Make sure only batch size are received checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES, false); // Final batch sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES - 1, persistent, false); checkAllMessageReceivedInOrder(cf0, localTargetQueue, NUM_MESSAGES, 1, false); checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES - 1, false); } finally { if (bridge != null) { bridge.stop(); } } } private void testMaxBatchTime(final QualityOfServiceMode qosMode, final boolean persistent) throws Exception { JMSBridgeImpl bridge = null; ConnectionFactoryFactory factInUse0 = cff0; ConnectionFactoryFactory factInUse1 = cff1; if (qosMode.equals(QualityOfServiceMode.ONCE_AND_ONLY_ONCE)) { factInUse0 = cff0xa; factInUse1 = cff1xa; ServiceUtils.setTransactionManager(newTransactionManager()); } try { final long MAX_BATCH_TIME = 300; final int MAX_BATCH_SIZE = 100000; // something big so it won't reach it bridge = new JMSBridgeImpl(factInUse0, factInUse1, sourceQueueFactory, targetQueueFactory, null, null, null, null, null, 3000, 10, qosMode, MAX_BATCH_SIZE, MAX_BATCH_TIME, null, null, false).setBridgeName("test-bridge"); bridge.start(); final int NUM_MESSAGES = 10; // Send some message sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES, persistent, false); // Verify none are received checkEmpty(targetQueue, 1); // Messages should now be receivable checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES, false); } finally { if (bridge != null) { bridge.stop(); } } } private void testMaxBatchTimeSameServer(final QualityOfServiceMode qosMode, final boolean persistent) throws Exception { JMSBridgeImpl bridge = null; ConnectionFactoryFactory factInUse0 = cff0; if (qosMode.equals(QualityOfServiceMode.ONCE_AND_ONLY_ONCE)) { factInUse0 = cff0xa; ServiceUtils.setTransactionManager(newTransactionManager()); } try { final long MAX_BATCH_TIME = 300; final int MAX_BATCH_SIZE = 100000; // something big so it won't reach it bridge = new JMSBridgeImpl(factInUse0, factInUse0, sourceQueueFactory, localTargetQueueFactory, null, null, null, null, null, 3000, 10, qosMode, MAX_BATCH_SIZE, MAX_BATCH_TIME, null, null, false); bridge.start(); final int NUM_MESSAGES = 10; // Send some message // Send some message sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES, persistent, false); // Verify none are received checkEmpty(localTargetQueue, 0); // Messages should now be receivable checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES, false); } finally { if (bridge != null) { bridge.stop(); } } } @Test public void testSetTMClass() throws Exception { TransactionManagerLocatorImpl.setTransactionManager(new DummyTransactionManager()); JMSBridgeImpl bridge = null; try { bridge = new JMSBridgeImpl(cff0, cff0, sourceQueueFactory, localTargetQueueFactory, null, null, null, null, null, 3000, 10, QualityOfServiceMode.ONCE_AND_ONLY_ONCE, 10000, 3000, null, null, false).setBridgeName("test-bridge"); bridge.start(); } finally { if (bridge != null) { bridge.stop(); } } } @Test public void testMBeanServer() throws Exception { MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); ObjectName objectName = new ObjectName("example.jmsbridge:service=JMSBridge"); JMSBridgeImpl bridge = new JMSBridgeImpl(cff0, cff0, sourceQueueFactory, localTargetQueueFactory, null, null, null, null, null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE, 1, -1, null, null, false, mbeanServer, objectName.getCanonicalName()).setBridgeName("test-bridge"); Assert.assertTrue(mbeanServer.isRegistered(objectName)); bridge.destroy(); Assert.assertFalse(mbeanServer.isRegistered(objectName)); } public TransactionManager getNewTm() { return newTransactionManager(); } // Inner classes ------------------------------------------------------------------- private static class StressSender implements Runnable { int numMessages; Session sess; MessageProducer prod; Exception ex; @Override public void run() { try { for (int i = 0; i < numMessages; i++) { TextMessage tm = sess.createTextMessage("message" + i); prod.send(tm); JMSBridgeTest.log.trace("Sent message " + i); } } catch (Exception e) { JMSBridgeTest.log.error("Failed to send", e); ex = e; } } } }