/*
* JBoss, Home of Professional Open Source
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.test.messaging.jms.bridge;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
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.transaction.Transaction;
import javax.transaction.TransactionManager;
import org.jboss.messaging.core.logging.Logger;
import org.jboss.messaging.jms.bridge.QualityOfServiceMode;
import org.jboss.messaging.jms.bridge.impl.BridgeImpl;
import org.jboss.messaging.jms.client.JBossMessage;
import org.jboss.tm.TransactionManagerLocator;
/**
* A BridgeTest
*
* @author <a href="mailto:tim.fox@jboss.com">Tim Fox</a>
* @version <tt>$Revision$</tt>
*
* $Id$
*
*/
public class BridgeTest extends BridgeTestBase
{
private static final Logger log = Logger.getLogger(BridgeTest.class);
public BridgeTest(String name)
{
super(name);
}
// MaxBatchSize but no MaxBatchTime
public void testNoMaxBatchTime_AtMostOnce_P() throws Exception
{
testNoMaxBatchTime(QualityOfServiceMode.AT_MOST_ONCE, true);
}
public void testNoMaxBatchTime_DuplicatesOk_P() throws Exception
{
testNoMaxBatchTime(QualityOfServiceMode.DUPLICATES_OK, true);
}
public void testNoMaxBatchTime_OnceAndOnlyOnce_P() throws Exception
{
testNoMaxBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true);
}
public void testNoMaxBatchTime_AtMostOnce_NP() throws Exception
{
testNoMaxBatchTime(QualityOfServiceMode.AT_MOST_ONCE, false);
}
public void testNoMaxBatchTime_DuplicatesOk_NP() throws Exception
{
testNoMaxBatchTime(QualityOfServiceMode.DUPLICATES_OK, false);
}
public void testNoMaxBatchTime_OnceAndOnlyOnce_NP() throws Exception
{
testNoMaxBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false);
}
//Same server
// MaxBatchSize but no MaxBatchTime
public void testNoMaxBatchTimeSameServer_AtMostOnce_P() throws Exception
{
testNoMaxBatchTimeSameServer(QualityOfServiceMode.AT_MOST_ONCE, true);
}
public void testNoMaxBatchTimeSameServer_DuplicatesOk_P() throws Exception
{
testNoMaxBatchTimeSameServer(QualityOfServiceMode.DUPLICATES_OK, true);
}
public void testNoMaxBatchTimeSameServer_OnceAndOnlyOnce_P() throws Exception
{
testNoMaxBatchTimeSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true);
}
public void testNoMaxBatchTimeSameServer_AtMostOnce_NP() throws Exception
{
testNoMaxBatchTimeSameServer(QualityOfServiceMode.AT_MOST_ONCE, false);
}
public void testNoMaxBatchTimeSameServer_DuplicatesOk_NP() throws Exception
{
testNoMaxBatchTimeSameServer(QualityOfServiceMode.DUPLICATES_OK, false);
}
public void testNoMaxBatchTimeSameServer_OnceAndOnlyOnce_NP() throws Exception
{
testNoMaxBatchTimeSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false);
}
// MaxBatchTime but no MaxBatchSize
public void testMaxBatchTime_AtMostOnce_P() throws Exception
{
this.testMaxBatchTime(QualityOfServiceMode.AT_MOST_ONCE, true);
}
public void testMaxBatchTime_DuplicatesOk_P() throws Exception
{
this.testMaxBatchTime(QualityOfServiceMode.DUPLICATES_OK, true);
}
public void testMaxBatchTime_OnceAndOnlyOnce_P() throws Exception
{
testMaxBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true);
}
public void testMaxBatchTime_AtMostOnce_NP() throws Exception
{
this.testMaxBatchTime(QualityOfServiceMode.AT_MOST_ONCE, false);
}
public void testMaxBatchTime_DuplicatesOk_NP() throws Exception
{
this.testMaxBatchTime(QualityOfServiceMode.DUPLICATES_OK, false);
}
public void testMaxBatchTime_OnceAndOnlyOnce_NP() throws Exception
{
testMaxBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false);
}
// Same server
// MaxBatchTime but no MaxBatchSize
public void testMaxBatchTimeSameServer_AtMostOnce_P() throws Exception
{
this.testMaxBatchTimeSameServer(QualityOfServiceMode.AT_MOST_ONCE, true);
}
public void testMaxBatchTimeSameServer_DuplicatesOk_P() throws Exception
{
this.testMaxBatchTimeSameServer(QualityOfServiceMode.DUPLICATES_OK, true);
}
public void testMaxBatchTimeSameServer_OnceAndOnlyOnce_P() throws Exception
{
testMaxBatchTimeSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true);
}
public void testMaxBatchTimeSameServer_AtMostOnce_NP() throws Exception
{
this.testMaxBatchTimeSameServer(QualityOfServiceMode.AT_MOST_ONCE, false);
}
public void testMaxBatchTimeSameServer_DuplicatesOk_NP() throws Exception
{
this.testMaxBatchTimeSameServer(QualityOfServiceMode.DUPLICATES_OK, false);
}
public void testMaxBatchTimeSameServer_OnceAndOnlyOnce_NP() throws Exception
{
testMaxBatchTimeSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false);
}
// Stress with batch size of 50
public void testStress_AtMostOnce_P_50() throws Exception
{
testStress(QualityOfServiceMode.AT_MOST_ONCE, true, 50);
}
public void testStress_DuplicatesOk_P_50() throws Exception
{
testStress(QualityOfServiceMode.DUPLICATES_OK, true, 50);
}
public void testStress_OnceAndOnlyOnce_P_50() throws Exception
{
testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 50);
}
public void testStress_AtMostOnce_NP_50() throws Exception
{
testStress(QualityOfServiceMode.AT_MOST_ONCE, false, 50);
}
public void testStress_DuplicatesOk_NP_50() throws Exception
{
testStress(QualityOfServiceMode.DUPLICATES_OK, false, 50);
}
public void testStress_OnceAndOnlyOnce_NP_50() throws Exception
{
testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 50);
}
// Stress with batch size of 1
public void testStress_AtMostOnce_P_1() throws Exception
{
testStress(QualityOfServiceMode.AT_MOST_ONCE, true, 1);
}
public void testStress_DuplicatesOk_P_1() throws Exception
{
testStress(QualityOfServiceMode.DUPLICATES_OK, true, 1);
}
public void testStress_OnceAndOnlyOnce_P_1() throws Exception
{
testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 1);
}
public void testStress_AtMostOnce_NP_1() throws Exception
{
testStress(QualityOfServiceMode.AT_MOST_ONCE, false, 1);
}
public void testStress_DuplicatesOk_NP_1() throws Exception
{
testStress(QualityOfServiceMode.DUPLICATES_OK, false, 1);
}
public void testStress_OnceAndOnlyOnce_NP_1() throws Exception
{
testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 1);
}
// Max batch time
public void testStressMaxBatchTime_OnceAndOnlyOnce_NP() throws Exception
{
this.testStressBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 200);
}
public void testStressMaxBatchTime_OnceAndOnlyOnce_P() throws Exception
{
this.testStressBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 200);
}
// Stress on same server
// Stress with batch size of 50
public void testStressSameServer_AtMostOnce_P_50() throws Exception
{
testStressSameServer(QualityOfServiceMode.AT_MOST_ONCE, true, 50);
}
public void testStressSameServer_DuplicatesOk_P_50() throws Exception
{
testStressSameServer(QualityOfServiceMode.DUPLICATES_OK, true, 50);
}
public void testStressSameServer_OnceAndOnlyOnce_P_50() throws Exception
{
testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 50);
}
public void testStressSameServer_AtMostOnce_NP_50() throws Exception
{
testStressSameServer(QualityOfServiceMode.AT_MOST_ONCE, false, 50);
}
public void testStressSameServer_DuplicatesOk_NP_50() throws Exception
{
testStressSameServer(QualityOfServiceMode.DUPLICATES_OK, false, 50);
}
public void testStressSameServer_OnceAndOnlyOnce_NP_50() throws Exception
{
testStressSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 50);
}
// Stress with batch size of 1
public void testStressSameServer_AtMostOnce_P_1() throws Exception
{
testStressSameServer(QualityOfServiceMode.AT_MOST_ONCE, true, 1);
}
public void testStressSameServer_DuplicatesOk_P_1() throws Exception
{
testStressSameServer(QualityOfServiceMode.DUPLICATES_OK, true, 1);
}
public void testStressSameServer_OnceAndOnlyOnce_P_1() throws Exception
{
testStressSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 1);
}
public void testStressSameServer_AtMostOnce_NP_1() throws Exception
{
testStressSameServer(QualityOfServiceMode.AT_MOST_ONCE, false, 1);
}
public void testStressSameServer_DuplicatesOk_NP_1() throws Exception
{
testStressSameServer(QualityOfServiceMode.DUPLICATES_OK, false, 1);
}
public void testStressSameServer_OnceAndOnlyOnce_NP_1() throws Exception
{
testStressSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 1);
}
public void testParams() throws Exception
{
BridgeImpl bridge = null;
try
{
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 BridgeImpl(null, cff1, sourceQueueFactory, targetQueueFactory,
sourceUsername, sourcePassword, destUsername, destPassword,
selector, failureRetryInterval, maxRetries, qosMode,
batchSize, maxBatchTime,
subName, clientID, false);
}
catch (IllegalArgumentException e)
{
//Ok
}
try
{
bridge= new BridgeImpl(cff0, null, sourceQueueFactory, targetQueueFactory,
sourceUsername, sourcePassword, destUsername, destPassword,
selector, failureRetryInterval, maxRetries, qosMode,
batchSize, maxBatchTime,
subName, clientID, false);
}
catch (IllegalArgumentException e)
{
//Ok
}
try
{
bridge= new BridgeImpl(cff0, cff1, null, targetQueueFactory,
sourceUsername, sourcePassword, destUsername, destPassword,
selector, failureRetryInterval, maxRetries, qosMode,
batchSize, maxBatchTime,
subName, clientID, false);
}
catch (IllegalArgumentException e)
{
//Ok
}
try
{
bridge= new BridgeImpl(cff0, cff1, sourceQueueFactory, null,
sourceUsername, sourcePassword, destUsername, destPassword,
selector, failureRetryInterval, maxRetries, qosMode,
batchSize, maxBatchTime,
subName, clientID, false);
}
catch (IllegalArgumentException e)
{
//Ok
}
try
{
bridge= new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
sourceUsername, sourcePassword, destUsername, destPassword,
selector, -2, maxRetries, qosMode,
batchSize, maxBatchTime,
subName, clientID, false);
}
catch (IllegalArgumentException e)
{
//Ok
}
try
{
bridge= new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
sourceUsername, sourcePassword, destUsername, destPassword,
selector, -1, 10, qosMode,
batchSize, maxBatchTime,
subName, clientID, false);
}
catch (IllegalArgumentException e)
{
//Ok
}
try
{
bridge= new BridgeImpl(cff0, cff1, sourceQueueFactory, null,
sourceUsername, sourcePassword, destUsername, destPassword,
selector, failureRetryInterval, maxRetries, qosMode,
0, maxBatchTime,
subName, clientID, false);
}
catch (IllegalArgumentException e)
{
//Ok
}
try
{
bridge= new BridgeImpl(cff0, cff1, sourceQueueFactory, null,
sourceUsername, sourcePassword, destUsername, destPassword,
selector, failureRetryInterval, maxRetries, qosMode,
batchSize, -2,
subName, clientID, false);
}
catch (IllegalArgumentException e)
{
//Ok
}
}
finally
{
if (bridge != null)
{
bridge.stop();
}
}
}
public void testSelector() throws Exception
{
BridgeImpl bridge = null;
Connection connSource = null;
Connection connTarget = null;
try
{
final int NUM_MESSAGES = 10;
String selector = "vegetable='radish'";
bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
null, null, null, null,
selector, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
1, -1,
null, null, false);
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(1000);
assertNotNull(tm);
assertEquals("message" + i, tm.getText());
}
Message m = cons.receive(1000);
assertNull(m);
}
finally
{
if (connSource != null)
{
connSource.close();
}
if (connTarget != null)
{
connTarget.close();
}
if (bridge != null)
{
bridge.stop();
}
removeAllMessages(sourceQueue.getQueueName(), true, 0);
}
}
public void testStartBridgeWithJTATransactionAlreadyRunning() throws Exception
{
BridgeImpl bridge = null;
Transaction toResume = null;
Transaction started = null;
TransactionManager mgr = TransactionManagerLocator.getInstance().locate();
try
{
toResume = mgr.suspend();
mgr.begin();
started = mgr.getTransaction();
final int NUM_MESSAGES = 10;
bridge = new BridgeImpl(cff0, cff1, sourceTopicFactory, targetQueueFactory,
null, null, null, null,
null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
1, -1,
null, null, false);
bridge.start();
this.sendMessages(cf0, sourceTopic, 0, NUM_MESSAGES, false);
this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);
}
finally
{
if (started != null)
{
try
{
started.rollback();
}
catch (Exception e)
{
log.error("Failed to rollback", e);
}
}
if (toResume != null)
{
try
{
mgr.resume(toResume);
}
catch (Exception e)
{
log.error("Failed to resume", e);
}
}
if (bridge != null)
{
bridge.stop();
}
}
}
public void testNonDurableSubscriber() throws Exception
{
BridgeImpl bridge = null;
try
{
final int NUM_MESSAGES = 10;
bridge = new BridgeImpl(cff0, cff1, sourceTopicFactory, targetQueueFactory,
null, null, null, null,
null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
1, -1,
null, null, false);
bridge.start();
sendMessages(cf0, sourceTopic, 0, NUM_MESSAGES, false);
checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);
}
finally
{
if (bridge != null)
{
bridge.stop();
}
}
}
public void testDurableSubscriber() throws Exception
{
BridgeImpl bridge = null;
try
{
final int NUM_MESSAGES = 10;
bridge = new BridgeImpl(cff0, cff1, sourceTopicFactory, targetQueueFactory,
null, null, null, null,
null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
1, -1,
"subTest", "clientid123", false);
bridge.start();
sendMessages(cf0, sourceTopic, 0, NUM_MESSAGES, true);
checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);
}
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();
}
}
public void testMessageIDInHeaderOn() throws Exception
{
messageIDInHeader(true);
}
public void testMessageIDInHeaderOff() throws Exception
{
messageIDInHeader(false);
}
private void messageIDInHeader(boolean on) throws Exception
{
BridgeImpl bridge = null;
Connection connSource = null;
Connection connTarget = null;
try
{
final int NUM_MESSAGES = 10;
bridge = new BridgeImpl(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();
log.trace("Sending " + NUM_MESSAGES + " messages");
List 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 headers to make sure they get passed through ok
tm.setStringProperty("wib", "uhuh");
tm.setBooleanProperty("cheese", true);
tm.setIntProperty("Sausages", 23);
//We add some JMSX ones too
tm.setStringProperty("JMSXGroupID", "mygroup543");
tm.setIntProperty("JMSXGroupSeq", 777);
prod.send(tm);
ids1.add(tm.getJMSMessageID());
}
log.trace("Sent the first messages");
Session sessTarget = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer cons = sessTarget.createConsumer(targetQueue);
connTarget.start();
List msgs = new ArrayList();
for (int i = 0; i < NUM_MESSAGES; i++)
{
TextMessage tm = (TextMessage)cons.receive(5000);
assertNotNull(tm);
assertEquals("message" + i, tm.getText());
assertEquals("uhuh", tm.getStringProperty("wib"));
assertTrue(tm.getBooleanProperty("cheese"));
assertEquals(23, tm.getIntProperty("Sausages"));
assertEquals("mygroup543", tm.getStringProperty("JMSXGroupID"));
assertEquals(777, tm.getIntProperty("JMSXGroupSeq"));
if (on)
{
String header = tm.getStringProperty(JBossMessage.JBOSS_MESSAGING_BRIDGE_MESSAGE_ID_LIST);
assertNotNull(header);
assertEquals(ids1.get(i), header);
msgs.add(tm);
}
}
if (on)
{
//Now we send them again back to the source
Iterator iter = msgs.iterator();
List ids2 = new ArrayList();
while (iter.hasNext())
{
Message msg = (Message)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);
assertNotNull(tm);
assertEquals("message" + i, tm.getText());
assertEquals("uhuh", tm.getStringProperty("wib"));
assertTrue(tm.getBooleanProperty("cheese"));
assertEquals(23, tm.getIntProperty("Sausages"));
assertEquals("mygroup543", tm.getStringProperty("JMSXGroupID"));
assertEquals(777, tm.getIntProperty("JMSXGroupSeq"));
String header = tm.getStringProperty(JBossMessage.JBOSS_MESSAGING_BRIDGE_MESSAGE_ID_LIST);
assertNotNull(header);
assertEquals(ids1.get(i) + "," + ids2.get(i), header);
}
}
}
finally
{
if (bridge != null)
{
bridge.stop();
}
if (connSource != null)
{
connSource.close();
}
if (connTarget != null)
{
connTarget.close();
}
}
}
public void testPropertiesPreservedPOn() throws Exception
{
propertiesPreserved(true, true);
}
public void testPropertiesPreservedNPoff() throws Exception
{
propertiesPreserved(false, true);
}
public void testPropertiesPreservedNPOn() throws Exception
{
propertiesPreserved(false, true);
}
public void testPropertiesPreservedPoff() throws Exception
{
propertiesPreserved(true, true);
}
private void propertiesPreserved(boolean persistent, boolean messageIDInHeader) throws Exception
{
BridgeImpl bridge = null;
Connection connSource = null;
Connection connTarget = null;
try
{
final int NUM_MESSAGES = 10;
bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
null, null, null, null,
null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
1, -1,
null, null, messageIDInHeader);
bridge.start();
connSource = cf0.createConnection();
connTarget = cf1.createConnection();
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();
assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
tm = (TextMessage)cons.receive(1000);
assertNotNull(tm);
assertEquals("blahmessage", tm.getText());
assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
assertEquals(7, tm.getJMSPriority());
assertTrue(Math.abs(expiration - tm.getJMSExpiration()) < 100);
Message m = cons.receive(5000);
assertNull(m);
//Now do one with expiration = 0
tm = sessSource.createTextMessage("blahmessage2");
prod.setPriority(7);
prod.setTimeToLive(0);
prod.send(tm);
assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
tm = (TextMessage)cons.receive(1000);
assertNotNull(tm);
assertEquals("blahmessage2", tm.getText());
assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
assertEquals(7, tm.getJMSPriority());
assertEquals(0, tm.getJMSExpiration());
m = cons.receive(5000);
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(1000);
assertNotNull(tm);
assertEquals("blahmessage3", tm.getText());
assertEquals(myBool, tm.getBooleanProperty("mybool"));
assertEquals(myByte, tm.getByteProperty("mybyte"));
assertEquals(myDouble, tm.getDoubleProperty("mydouble"));
assertEquals(myFloat, tm.getFloatProperty("myfloat"));
assertEquals(myInt, tm.getIntProperty("myint"));
assertEquals(myLong, tm.getLongProperty("mylong"));
assertEquals(myShort, tm.getShortProperty("myshort"));
assertEquals(myString, tm.getStringProperty("mystring"));
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();
}
}
}
public void testNoMessageIDInHeader() throws Exception
{
BridgeImpl bridge = null;
Connection connSource = null;
Connection connTarget = null;
try
{
final int NUM_MESSAGES = 10;
bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
null, null, null, null,
null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
1, -1,
null, null, false);
bridge.start();
connSource = cf0.createConnection();
connTarget = cf1.createConnection();
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);
}
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);
assertNotNull(tm);
assertEquals("message" + i, tm.getText());
assertEquals("uhuh", tm.getStringProperty("wib"));
assertTrue(tm.getBooleanProperty("cheese"));
assertEquals(23, tm.getIntProperty("Sausages"));
String header = tm.getStringProperty(JBossMessage.JBOSS_MESSAGING_BRIDGE_MESSAGE_ID_LIST);
assertNull(header);
}
}
finally
{
if (bridge != null)
{
bridge.stop();
}
if (connSource != null)
{
connSource.close();
}
if (connTarget != null)
{
connTarget.close();
}
}
}
// Private -------------------------------------------------------------------------------
private void testStress(QualityOfServiceMode qosMode, boolean persistent, int batchSize) throws Exception
{
Connection connSource = null;
BridgeImpl bridge = null;
Thread t = null;
try
{
bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
null, null, null, null,
null, 5000, 10, qosMode,
batchSize, -1,
null, null, false);
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();
this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);
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)
{
log.error("Failed to close connection", e);
}
}
if (bridge != null)
{
bridge.stop();
}
}
}
private void testStressBatchTime(QualityOfServiceMode qosMode, boolean persistent, int maxBatchTime) throws Exception
{
Connection connSource = null;
BridgeImpl bridge = null;
Thread t = null;
try
{
bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
null, null, null, null,
null, 5000, 10, qosMode,
2, maxBatchTime,
null, null, false);
bridge.start();
connSource = cf0.createConnection();
Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer prod = sessSend.createProducer(sourceQueue);
final int NUM_MESSAGES = 5000;
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();
this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);
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)
{
log.error("Failed to close connection", e);
}
}
if (bridge != null)
{
bridge.stop();
}
}
}
//Both source and destination on same rm
private void testStressSameServer(QualityOfServiceMode qosMode, boolean persistent, int batchSize) throws Exception
{
Connection connSource = null;
BridgeImpl bridge = null;
Thread t = null;
try
{
bridge = new BridgeImpl(cff0, cff0, sourceQueueFactory, localTargetQueueFactory,
null, null, null, null,
null, 5000, 10, qosMode,
batchSize, -1,
null, null, false);
bridge.start();
connSource = cf0.createConnection();
Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer prod = sessSend.createProducer(sourceQueue);
final int NUM_MESSAGES = 2000;
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();
this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES);
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)
{
log.error("Failed to close connection", e);
}
}
if (bridge != null)
{
bridge.stop();
}
}
}
private void testNoMaxBatchTime(QualityOfServiceMode qosMode, boolean persistent) throws Exception
{
BridgeImpl bridge = null;
try
{
final int NUM_MESSAGES = 10;
bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
null, null, null, null,
null, 5000, 10, qosMode,
NUM_MESSAGES, -1,
null, null, false);
bridge.start();
//Send half the messges
this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES / 2, persistent);
//Verify none are received
this.checkEmpty(targetQueue, 1);
//Send the other half
this.sendMessages(cf0, sourceQueue, NUM_MESSAGES / 2, NUM_MESSAGES / 2, persistent);
//This should now be receivable
this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);
//Send another batch with one more than batch size
this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES + 1, persistent);
//Make sure only batch size are received
this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);
//Final batch
this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES - 1, persistent);
this.checkAllMessageReceivedInOrder(cf1, targetQueue, NUM_MESSAGES, 1);
this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES - 1);
}
finally
{
if (bridge != null)
{
log.info("Stopping bridge");
bridge.stop();
}
}
}
private void testNoMaxBatchTimeSameServer(QualityOfServiceMode qosMode, boolean persistent) throws Exception
{
BridgeImpl bridge = null;
try
{
final int NUM_MESSAGES = 10;
bridge = new BridgeImpl(cff0, cff0, sourceQueueFactory, localTargetQueueFactory,
null, null, null, null,
null, 5000, 10, qosMode,
NUM_MESSAGES, -1,
null, null, false);
bridge.start();
this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES / 2, persistent);
this.checkEmpty(targetQueue, 1);
//Send the other half
this.sendMessages(cf0, sourceQueue, NUM_MESSAGES / 2, NUM_MESSAGES /2, persistent);
//This should now be receivable
this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES);
this.checkEmpty(localTargetQueue, 0);
this.checkEmpty(sourceQueue, 0);
//Send another batch with one more than batch size
this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES + 1, persistent);
//Make sure only batch size are received
this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES);
//Final batch
this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES - 1, persistent);
this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, NUM_MESSAGES, 1);
this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES - 1);
}
finally
{
if (bridge != null)
{
bridge.stop();
}
}
}
private void testMaxBatchTime(QualityOfServiceMode qosMode, boolean persistent) throws Exception
{
BridgeImpl bridge = null;
try
{
final long MAX_BATCH_TIME = 3000;
final int MAX_BATCH_SIZE = 100000; // something big so it won't reach it
bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
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
this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES, persistent);
//Verify none are received
this.checkEmpty(targetQueue, 1);
//Messages should now be receivable
this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);
}
finally
{
if (bridge != null)
{
bridge.stop();
}
}
}
private void testMaxBatchTimeSameServer(QualityOfServiceMode qosMode, boolean persistent) throws Exception
{
BridgeImpl bridge = null;
try
{
final long MAX_BATCH_TIME = 3000;
final int MAX_BATCH_SIZE = 100000; // something big so it won't reach it
bridge = new BridgeImpl(cff0, cff0, 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
this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES, persistent);
//Verify none are received
this.checkEmpty(localTargetQueue, 0);;
//Messages should now be receivable
this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES);
}
finally
{
if (bridge != null)
{
bridge.stop();
}
}
}
// Inner classes -------------------------------------------------------------------
private static class StressSender implements Runnable
{
int numMessages;
Session sess;
MessageProducer prod;
Exception ex;
public void run()
{
try
{
for (int i = 0; i < numMessages; i++)
{
TextMessage tm = sess.createTextMessage("message" + i);
prod.send(tm);
log.trace("Sent message " + i);
}
}
catch (Exception e)
{
log.error("Failed to send", e);
ex = e;
}
}
}
}