diff options
| author | Rafael H. Schloming <rhs@apache.org> | 2008-08-15 03:40:49 +0000 |
|---|---|---|
| committer | Rafael H. Schloming <rhs@apache.org> | 2008-08-15 03:40:49 +0000 |
| commit | b6a376a4797e4988cdae48e0e5395a9b1f4e9f85 (patch) | |
| tree | dc41b190202b592d35579af35cc8b18bb1f1b702 /java/client | |
| parent | c521097d6d6f44e437e2ce67f5a8ae66706e4476 (diff) | |
| download | qpid-python-b6a376a4797e4988cdae48e0e5395a9b1f4e9f85.tar.gz | |
updated qpid.0-10/java to match trunk/qpid/java@686097
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/branches/qpid.0-10@686136 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/client')
216 files changed, 5106 insertions, 18637 deletions
diff --git a/java/client/build.xml b/java/client/build.xml index aeadfa2f0f..abeb3ec903 100644 --- a/java/client/build.xml +++ b/java/client/build.xml @@ -21,11 +21,10 @@ <project name="AMQ Client" default="build"> <property name="module.depends" value="common"/> - <property name="module.test.depends" value="broker junit-toolkit"/> <import file="../module.xml"/> - <property name="output.dir" value="${module.precompiled}/org/apache/qpidity/filter/selector"/> + <property name="output.dir" value="${module.precompiled}/org/apache/qpid/filter/selector"/> <target name="precompile"> <mkdir dir="${output.dir}"/> diff --git a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/DeclareQueue.java b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/DeclareQueue.java index 8bb27847ce..b16a7fa7c3 100755 --- a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/DeclareQueue.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/DeclareQueue.java @@ -1,8 +1,8 @@ package org.apache.qpid.example.amqpexample.direct; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.Session; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.Session; /** * This creates a queue a queue and binds it to the diff --git a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/DirectProducer.java b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/DirectProducer.java index 7329792a2b..2793e567ea 100755 --- a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/DirectProducer.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/DirectProducer.java @@ -2,14 +2,15 @@ package org.apache.qpid.example.amqpexample.direct; import java.nio.ByteBuffer; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.nclient.util.MessageListener; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageAcceptMode; -import org.apache.qpidity.transport.MessageAcquireMode; +import org.apache.qpid.api.Message; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.nclient.util.MessageListener; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.transport.MessageAcceptMode; +import org.apache.qpid.transport.MessageAcquireMode; public class DirectProducer implements MessageListener { @@ -67,16 +68,14 @@ public class DirectProducer implements MessageListener for (int i=0; i<10; i++) { - session.messageTransfer("amq.direct", MessageAcceptMode.EXPLICIT,MessageAcquireMode.PRE_ACQUIRED); - session.header(deliveryProps); - session.data("Message " + i); - session.endData(); + session.messageTransfer("amq.direct", MessageAcceptMode.EXPLICIT,MessageAcquireMode.PRE_ACQUIRED, + new Header(deliveryProps), + "Message " + i); } - session.messageTransfer("amq.direct", MessageAcceptMode.EXPLICIT, MessageAcquireMode.PRE_ACQUIRED); - session.header(deliveryProps); - session.data("That's all, folks!"); - session.endData(); + session.messageTransfer("amq.direct", MessageAcceptMode.EXPLICIT, MessageAcquireMode.PRE_ACQUIRED, + new Header(deliveryProps), + "That's all, folks!"); // confirm completion session.sync(); diff --git a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java index b199c3a69a..081fbf2521 100755 --- a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java @@ -2,14 +2,14 @@ package org.apache.qpid.example.amqpexample.direct; import java.nio.ByteBuffer; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.nclient.util.MessageListener; -import org.apache.qpidity.nclient.util.MessagePartListenerAdapter; - -import org.apache.qpidity.transport.MessageCreditUnit; +import org.apache.qpid.api.Message; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.nclient.util.MessageListener; +import org.apache.qpid.nclient.util.MessagePartListenerAdapter; + +import org.apache.qpid.transport.MessageCreditUnit; /** * This listens to messages on a queue and terminates diff --git a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/DeclareQueue.java b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/DeclareQueue.java index 67f24148d8..9af5f21e66 100755 --- a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/DeclareQueue.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/DeclareQueue.java @@ -1,8 +1,8 @@ package org.apache.qpid.example.amqpexample.fanout; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.Session; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.Session; /** * This creates a queue a queue and binds it to the diff --git a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/FannoutProducer.java b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/FannoutProducer.java index 4c647fde36..41038d3e53 100755 --- a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/FannoutProducer.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/FannoutProducer.java @@ -1,11 +1,12 @@ package org.apache.qpid.example.amqpexample.fanout; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageAcceptMode; -import org.apache.qpidity.transport.MessageAcquireMode; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.transport.MessageAcceptMode; +import org.apache.qpid.transport.MessageAcquireMode; public class FannoutProducer { @@ -34,16 +35,13 @@ public class FannoutProducer for (int i=0; i<10; i++) { - session.messageTransfer("amq.fanout", MessageAcceptMode.EXPLICIT, MessageAcquireMode.PRE_ACQUIRED); - session.header(deliveryProps); - session.data("Message " + i); - session.endData(); + session.messageTransfer("amq.fanout", MessageAcceptMode.EXPLICIT, MessageAcquireMode.PRE_ACQUIRED, + new Header(deliveryProps), "Message " + i); } - session.messageTransfer("amq.fanout", MessageAcceptMode.EXPLICIT, MessageAcquireMode.PRE_ACQUIRED); - session.header(deliveryProps); - session.data("That's all, folks!"); - session.endData(); + session.messageTransfer("amq.fanout", MessageAcceptMode.EXPLICIT, MessageAcquireMode.PRE_ACQUIRED, + new Header(deliveryProps), + "That's all, folks!"); // confirm completion session.sync(); diff --git a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java index 1feb5cfe23..7942ce5ca3 100755 --- a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java @@ -2,16 +2,16 @@ package org.apache.qpid.example.amqpexample.fanout; import java.nio.ByteBuffer; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.nclient.util.MessageListener; -import org.apache.qpidity.nclient.util.MessagePartListenerAdapter; - -import org.apache.qpidity.transport.MessageAcceptMode; -import org.apache.qpidity.transport.MessageAcquireMode; -import org.apache.qpidity.transport.MessageCreditUnit; +import org.apache.qpid.api.Message; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.nclient.util.MessageListener; +import org.apache.qpid.nclient.util.MessagePartListenerAdapter; + +import org.apache.qpid.transport.MessageAcceptMode; +import org.apache.qpid.transport.MessageAcquireMode; +import org.apache.qpid.transport.MessageCreditUnit; /** * This listens to messages on a queue and terminates diff --git a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java index f26e5418b4..2e4edfbe6f 100755 --- a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java @@ -2,14 +2,14 @@ package org.apache.qpid.example.amqpexample.pubsub; import java.nio.ByteBuffer; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.nclient.util.MessageListener; -import org.apache.qpidity.nclient.util.MessagePartListenerAdapter; -import org.apache.qpidity.transport.MessageCreditUnit; -import org.apache.qpidity.transport.Option; +import org.apache.qpid.api.Message; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.nclient.util.MessageListener; +import org.apache.qpid.nclient.util.MessagePartListenerAdapter; +import org.apache.qpid.transport.MessageCreditUnit; +import org.apache.qpid.transport.Option; public class TopicListener implements MessageListener @@ -55,7 +55,7 @@ public class TopicListener implements MessageListener Session.TRANSFER_CONFIRM_MODE_NOT_REQUIRED, Session.TRANSFER_ACQUIRE_MODE_PRE_ACQUIRE, new MessagePartListenerAdapter(this), - null, Option.NO_OPTION); + null, Option.NONE); // issue credits // XXX: need to be able to set to null session.messageFlow(queueName, MessageCreditUnit.BYTE, Session.MESSAGE_FLOW_MAX_BYTES); diff --git a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicPublisher.java b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicPublisher.java index c960643504..caec886642 100755 --- a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicPublisher.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicPublisher.java @@ -1,11 +1,12 @@ package org.apache.qpid.example.amqpexample.pubsub; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageAcceptMode; -import org.apache.qpidity.transport.MessageAcquireMode; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.transport.MessageAcceptMode; +import org.apache.qpid.transport.MessageAcquireMode; public class TopicPublisher { @@ -18,20 +19,17 @@ public class TopicPublisher deliveryProps.setRoutingKey(routing_key); for (int i=0; i<5; i++) { - session.messageTransfer("amq.topic", MessageAcceptMode.EXPLICIT, MessageAcquireMode.PRE_ACQUIRED); - session.header(deliveryProps); - session.data("Message " + i); - session.endData(); + session.messageTransfer("amq.topic", MessageAcceptMode.EXPLICIT, MessageAcquireMode.PRE_ACQUIRED, + new Header(deliveryProps), "Message " + i); } } public void noMoreMessages(Session session) { - session.messageTransfer("amq.topic", MessageAcceptMode.EXPLICIT, MessageAcquireMode.PRE_ACQUIRED); - session.header(new DeliveryProperties().setRoutingKey("control")); - session.data("That's all, folks!"); - session.endData(); + session.messageTransfer("amq.topic", MessageAcceptMode.EXPLICIT, MessageAcquireMode.PRE_ACQUIRED, + new Header(new DeliveryProperties().setRoutingKey("control")), + "That's all, folks!"); } public static void main(String[] args) diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify index afcd30af88..0541e490b6 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify @@ -2,12 +2,13 @@ # The JMS producer doesn't create qeueues so utilising the c++ declare_queues cpp=$CPP/direct -direct_consumer_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer +direct_consumer_java() +{ +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer } direct_producer_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer } clients $cpp/declare_queues direct_producer_java direct_consumer_java diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_cpp_java b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_cpp_java index 85c8a12903..d581c4c1aa 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_cpp_java +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_cpp_java @@ -2,7 +2,7 @@ cpp=$CPP/direct direct_consumer_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer } clients $cpp/declare_queues $cpp/direct_producer direct_consumer_java diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_cpp b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_cpp index 8cea77025e..573cac6986 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_cpp +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_cpp @@ -2,7 +2,7 @@ cpp=$CPP/direct direct_producer_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer } clients $cpp/declare_queues direct_producer_java $cpp/listener diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_python b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_python index 5fedcb10e5..61c033e969 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_python +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_python @@ -1,8 +1,8 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify -py=$PYTHON/direct +py=$PYTHON_EXAMPLES/direct direct_producer_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer } clients $py/declare_queues.py direct_producer_java $py/direct_consumer.py diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_python_java b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_python_java index 7914665baf..4182331f3f 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_python_java +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_python_java @@ -1,8 +1,8 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify -py=$PYTHON/direct +py=$PYTHON_EXAMPLES/direct direct_consumer_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer } clients $py/declare_queues.py $py/direct_producer.py direct_consumer_java diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify index 69528a0cf9..2edc1ced02 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify @@ -3,11 +3,11 @@ cpp=$CPP/fanout fanout_listener_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1 +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1 } fanout_producer_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer } background "can receive messages" fanout_listener_java fanoutQueue1 diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_cpp_java b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_cpp_java index 3e0d7534bc..de057ea3b1 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_cpp_java +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_cpp_java @@ -3,7 +3,7 @@ cpp=$CPP/fanout fanout_listener_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1 +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1 } background "can receive messages" fanout_listener_java fanoutQueue1 diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_cpp b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_cpp index c1e1585ac3..dab6114572 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_cpp +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_cpp @@ -3,7 +3,7 @@ cpp=$CPP/fanout fanout_producer_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer } background "Listening" $cpp/listener diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_python b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_python index b57cb4af38..1641d88354 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_python +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_python @@ -1,9 +1,9 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify # The JMS producer doesn't create qeueues so utilising the c++ declare_queues -py=$PYTHON/fanout +py=$PYTHON_EXAMPLES/fanout fanout_producer_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer } background "Subscribed" $py/fanout_consumer.py diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_python_java b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_python_java index e10d077dfb..0f05663985 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_python_java +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_python_java @@ -1,9 +1,9 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify # The JMS producer doesn't create qeueues so utilising the c++ declare_queues -py=$PYTHON/fanout +py=$PYTHON_EXAMPLES/fanout fanout_listener_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1 +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1 } background "can receive messages" fanout_listener_java fanoutQueue1 diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify index 3e2a1b9b04..cceb565dfc 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify @@ -2,11 +2,11 @@ cpp=$CPP/pub-sub topic_listener_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener } topic_publisher_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher } background "can receive messages" topic_listener_java diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_cpp_java b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_cpp_java index f189290fda..9276b3e21b 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_cpp_java +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_cpp_java @@ -2,7 +2,7 @@ cpp=$CPP/pub-sub topic_listener_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener } background "can receive messages" topic_listener_java diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_cpp b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_cpp index 87743681f4..af22b3b82c 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_cpp +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_cpp @@ -2,7 +2,7 @@ cpp=$CPP/pub-sub topic_publisher_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher } background "Listening" $cpp/topic_listener diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_python b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_python index a8daf6ba30..3758e0f014 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_python +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_python @@ -1,8 +1,8 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify -py=$PYTHON/pubsub +py=$PYTHON_EXAMPLES/pubsub topic_publisher_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher } background "Queues created" $py/topic_subscriber.py diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_python_java b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_python_java index fc8f526145..c2b516f376 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_python_java +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_python_java @@ -1,8 +1,8 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify -py=$PYTHON/pubsub +py=$PYTHON_EXAMPLES/pubsub topic_listener_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener } background "can receive messages" topic_listener_java diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify index b3b0735d53..daf84c8ff9 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify @@ -2,11 +2,11 @@ cpp=$CPP/pub-sub client_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client } server_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server } background "can receive messages" server_java diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_cpp_java b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_cpp_java index 4551b9ab0c..6ef1b3b7e3 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_cpp_java +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_cpp_java @@ -1,8 +1,9 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify cpp=$CPP/request-response -client_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client +client_java() +{ +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client } background "Waiting" $cpp/server diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_cpp b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_cpp index 27510dc3f7..2513eb691b 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_cpp +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_cpp @@ -2,7 +2,7 @@ cpp=$CPP/request-response server_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server } background "can receive messages" server_java diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_python b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_python index 01bec87cab..0760952527 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_python +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_python @@ -1,8 +1,8 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify -py=$PYTHON/request-response +py=$PYTHON_EXAMPLES/request-response server_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server } background "can receive messages" server_java diff --git a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_python_java b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_python_java index 92a33f4a1e..6ea526e914 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_python_java +++ b/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_python_java @@ -1,8 +1,8 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify -py=$PYTHON/request-response +py=$PYTHON_EXAMPLES/request-response client_java(){ -java -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client +java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client } background "Request server running" $py/server.py diff --git a/java/client/pom.xml b/java/client/pom.xml index bcce3e1d3b..2ad41d96cd 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -112,7 +112,7 @@ <configuration> <sourceDirectory>${basedir}/src/main/grammar</sourceDirectory> <outputDirectory>${basedir}/target/generated-sources</outputDirectory> - <packageName>org.apache.qpidity.filter.selector</packageName> + <packageName>org.apache.qpid.filter.selector</packageName> </configuration> <goals> <goal>javacc</goal> @@ -237,16 +237,16 @@ <artifactId>maven-javadoc-plugin</artifactId> <configuration> <excludePackageNames> - org.apache.qpid.*:org.apache.qpidity.njms:org.apache.qpidity.njms.*:org.apache.qpidity.nclient.impl + org.apache.qpid.*:org.apache.qpid.njms:org.apache.qpid.njms.*:org.apache.qpid.nclient.impl </excludePackageNames> <groups> <group> <title>API</title> - <packages>org.apache.qpidity.nclient</packages> + <packages>org.apache.qpid.nclient</packages> </group> <group> <title>Utility Package</title> - <packages>org.apache.qpidity.nclient.util</packages> + <packages>org.apache.qpid.nclient.util</packages> </group> </groups> </configuration> diff --git a/java/client/src/main/grammar/SelectorParser.jj b/java/client/src/main/grammar/SelectorParser.jj index a72da526ae..b45cf1a487 100644 --- a/java/client/src/main/grammar/SelectorParser.jj +++ b/java/client/src/main/grammar/SelectorParser.jj @@ -61,20 +61,20 @@ PARSER_BEGIN(SelectorParser) *
*/
-package org.apache.qpidity.filter.selector;
+package org.apache.qpid.filter.selector;
import java.io.StringReader;
import java.util.ArrayList;
-import org.apache.qpidity.QpidException;
-import org.apache.qpidity.filter.ArithmeticExpression;
-import org.apache.qpidity.filter.BooleanExpression;
-import org.apache.qpidity.filter.ComparisonExpression;
-import org.apache.qpidity.filter.ConstantExpression;
-import org.apache.qpidity.filter.Expression;
-import org.apache.qpidity.filter.LogicExpression;
-import org.apache.qpidity.filter.PropertyExpression;
-import org.apache.qpidity.filter.UnaryExpression;
+import org.apache.qpid.QpidException;
+import org.apache.qpid.filter.ArithmeticExpression;
+import org.apache.qpid.filter.BooleanExpression;
+import org.apache.qpid.filter.ComparisonExpression;
+import org.apache.qpid.filter.ConstantExpression;
+import org.apache.qpid.filter.Expression;
+import org.apache.qpid.filter.LogicExpression;
+import org.apache.qpid.filter.PropertyExpression;
+import org.apache.qpid.filter.UnaryExpression;
/**
* JMS Selector Parser generated by JavaCC
diff --git a/java/client/src/main/java/client.log4j b/java/client/src/main/java/client.log4j index a5531bb874..19cc946118 100644 --- a/java/client/src/main/java/client.log4j +++ b/java/client/src/main/java/client.log4j @@ -21,15 +21,10 @@ log4j.rootLogger=${root.logging.level} #log4j.logger.org.apache.qpid=${amqj.logging.level}, console
#log4j.additivity.org.apache.qpid=false
-#log4j.logger.org.apache.qpidity.transport=TRACE, console
log4j.logger.org.apache.qpid=ERROR, console
log4j.additivity.org.apache.qpid=false
-log4j.logger.org.apache.qpidity=ERROR, console
-log4j.additivity.org.apache.qpidity=false
-
-#log4j.logger.org.apache.qpidity.transport=DEBUG, console
#log4j.logger.org.apache.qpid.client.message.AbstractBytesTypedMessage=DEBUG, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java index a504fb2c27..27294562e5 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java @@ -36,7 +36,6 @@ import org.apache.qpid.jms.ConnectionURL; import org.apache.qpid.jms.FailoverPolicy; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.url.URLSyntaxException; -import org.apache.qpidity.transport.TransportConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,7 +57,9 @@ import javax.naming.Reference; import javax.naming.Referenceable; import javax.naming.StringRefAddr; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; import java.net.ConnectException; +import java.net.UnknownHostException; import java.nio.channels.UnresolvedAddressException; import java.text.MessageFormat; import java.util.*; @@ -78,7 +79,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect public AMQSession get(int channelId) { - if((channelId & FAST_CHANNEL_ACCESS_MASK) == 0) + if ((channelId & FAST_CHANNEL_ACCESS_MASK) == 0) { return _fastAccessSessions[channelId]; } @@ -91,7 +92,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect public AMQSession put(int channelId, AMQSession session) { AMQSession oldVal; - if((channelId & FAST_CHANNEL_ACCESS_MASK) == 0) + if ((channelId & FAST_CHANNEL_ACCESS_MASK) == 0) { oldVal = _fastAccessSessions[channelId]; _fastAccessSessions[channelId] = session; @@ -100,11 +101,11 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect { oldVal = _slowAccessSessions.put(channelId, session); } - if((oldVal != null) && (session == null)) + if ((oldVal != null) && (session == null)) { _size--; } - else if((oldVal == null) && (session != null)) + else if ((oldVal == null) && (session != null)) { _size++; } @@ -113,13 +114,12 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect } - public AMQSession remove(int channelId) { AMQSession session; - if((channelId & FAST_CHANNEL_ACCESS_MASK) == 0) + if ((channelId & FAST_CHANNEL_ACCESS_MASK) == 0) { - session = _fastAccessSessions[channelId]; + session = _fastAccessSessions[channelId]; _fastAccessSessions[channelId] = null; } else @@ -127,7 +127,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect session = _slowAccessSessions.remove(channelId); } - if(session != null) + if (session != null) { _size--; } @@ -139,9 +139,9 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect { ArrayList<AMQSession> values = new ArrayList<AMQSession>(size()); - for(int i = 0; i < 16; i++) + for (int i = 0; i < 16; i++) { - if(_fastAccessSessions[i] != null) + if (_fastAccessSessions[i] != null) { values.add(_fastAccessSessions[i]); } @@ -160,14 +160,13 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect { _size = 0; _slowAccessSessions.clear(); - for(int i = 0; i<16; i++) + for (int i = 0; i < 16; i++) { _fastAccessSessions[i] = null; } } } - private static final Logger _logger = LoggerFactory.getLogger(AMQConnection.class); protected AtomicInteger _idFactory = new AtomicInteger(0); @@ -209,7 +208,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect /** The virtual path to connect to on the AMQ server */ private String _virtualHost; - protected ExceptionListener _exceptionListener; @@ -232,11 +230,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect protected boolean _connected; /* - * The last error code that occured on the connection. Used to return the correct exception to the client - */ - protected AMQException _lastAMQException = null; - - /* * The connection meta data */ private QpidConnectionMetaData _connectionMetaData; @@ -255,7 +248,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect private ProtocolVersion _protocolVersion = ProtocolVersion.v0_9; // FIXME TGM, shouldn't need this protected AMQConnectionDelegate _delegate; - + // this connection maximum number of prefetched messages private long _maxPrefetch; @@ -337,20 +330,20 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect /** * @todo Some horrible stuff going on here with setting exceptions to be non-null to detect if an exception - * was thrown during the connection! Intention not clear. Use a flag anyway, not exceptions... Will fix soon. + * was thrown during the connection! Intention not clear. Use a flag anyway, not exceptions... Will fix soon. */ public AMQConnection(ConnectionURL connectionURL, SSLConfiguration sslConfig) throws AMQException { // set this connection maxPrefetch if (connectionURL.getOption(ConnectionURL.AMQ_MAXPREFETCH) != null) { - _maxPrefetch = Long.parseLong( connectionURL.getOption(ConnectionURL.AMQ_MAXPREFETCH)); + _maxPrefetch = Long.parseLong(connectionURL.getOption(ConnectionURL.AMQ_MAXPREFETCH)); } else { // use the defaul value set for all connections _maxPrefetch = Long.valueOf(System.getProperties().getProperty(ClientProperties.MAX_PREFETCH_PROP_NAME, - ClientProperties.MAX_PREFETCH_DEFAULT)); + ClientProperties.MAX_PREFETCH_DEFAULT)); } if (connectionURL.getOption(ConnectionURL.AMQ_SYNC_PERSISTENCE) != null) @@ -367,37 +360,13 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect BrokerDetails brokerDetails = _failoverPolicy.getNextBrokerDetails(); if (brokerDetails.getTransport().equals(BrokerDetails.VM)) { - _delegate = new AMQConnectionDelegate_0_8(this); + _delegate = new AMQConnectionDelegate_8_0(this); } else { - // We always assume that the broker supports the lates AMQ protocol verions - // thie is currently 0.10 - // TODO: use this code once we have switch to 0.10 - // getDelegate(); _delegate = new AMQConnectionDelegate_0_10(this); } - final ArrayList<JMSException> exceptions = new ArrayList<JMSException>(); - - class Listener implements ExceptionListener - { - public void onException(JMSException e) - { - exceptions.add(e); - } - } - - try - { - setExceptionListener(new Listener()); - } - catch (JMSException e) - { - // Shouldn't happen - throw new AMQException(null, null, e); - } - if (_logger.isInfoEnabled()) { _logger.info("Connection:" + connectionURL); @@ -437,47 +406,40 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect _temporaryTopicExchangeName = connectionURL.getTemporaryTopicExchangeName(); } - - _protocolHandler = new AMQProtocolHandler(this); + _protocolHandler = new AMQProtocolHandler(this); // We are not currently connected _connected = false; - Exception lastException = new Exception(); - lastException.initCause(new ConnectException()); - - // TMG FIXME this seems... wrong... boolean retryAllowed = true; - while (!_connected && retryAllowed ) + Exception connectionException = null; + while (!_connected && retryAllowed) { + ProtocolVersion pe = null; try { - makeBrokerConnection(brokerDetails); - lastException = null; - _connected = true; + pe = makeBrokerConnection(brokerDetails); } - catch (AMQProtocolException pe) + catch (Exception e) { if (_logger.isInfoEnabled()) { - _logger.info(pe.getMessage()); - _logger.info("Trying broker supported protocol version: " + - TransportConstants.getVersionMajor() + "." + - TransportConstants.getVersionMinor()); + _logger.info("Unable to connect to broker at " + + _failoverPolicy.getCurrentBrokerDetails(), + e); } - // we need to check whether we have a delegate for the supported protocol - getDelegate(); + connectionException = e; } - catch (Exception e) - { - lastException = e; - if (_logger.isInfoEnabled()) - { - _logger.info("Unable to connect to broker at " + _failoverPolicy.getCurrentBrokerDetails(), - e.getCause()); - } - retryAllowed = _failoverPolicy.failoverAllowed(); + if (pe != null) + { + // reset the delegate to the version returned by the + // broker + initDelegate(pe); + } + else if (!_connected) + { + retryAllowed = _failoverPolicy.failoverAllowed(); brokerDetails = _failoverPolicy.getNextBrokerDetails(); } } @@ -490,39 +452,17 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect if (!_connected) { String message = null; - try - { - Thread.sleep(150); - } - catch (InterruptedException e) - { - // Eat it, we've hopefully got all the exceptions if this happened - } - if (exceptions.size() > 0) - { - JMSException e = exceptions.get(0); - int code = -1; - try - { - code = new Integer(e.getErrorCode()).intValue(); - } - catch (NumberFormatException nfe) - { - // Ignore this, we have some error codes and messages swapped around - } - throw new AMQConnectionFailureException(AMQConstant.getConstant(code), - e.getMessage(), e); - } - else if (lastException != null) + if (connectionException != null) { - if (lastException.getCause() != null) + if (connectionException.getCause() != null) { - message = lastException.getCause().getMessage(); + message = connectionException.getCause().getMessage(); + connectionException.getCause().printStackTrace(); } else { - message = lastException.getMessage(); + message = connectionException.getMessage(); } } @@ -534,27 +474,23 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect } else // can only be "" if getMessage() returned it therfore lastException != null { - message = "Unable to Connect:" + lastException.getClass(); + message = "Unable to Connect:" + connectionException.getClass(); } } - AMQException e = new AMQConnectionFailureException(message, null); - - if (lastException != null) + for (Throwable th = connectionException; th != null; th = th.getCause()) { - if (lastException instanceof UnresolvedAddressException) + if (th instanceof UnresolvedAddressException || + th instanceof UnknownHostException) { - e = new AMQUnresolvedAddressException(message, _failoverPolicy.getCurrentBrokerDetails().toString(), - null); + throw new AMQUnresolvedAddressException + (message, + _failoverPolicy.getCurrentBrokerDetails().toString(), + connectionException); } - - if (e.getCause() != null) - { - e.initCause(lastException); - } } - throw e; + throw new AMQConnectionFailureException(message, connectionException); } _connectionMetaData = new QpidConnectionMetaData(this); @@ -572,23 +508,41 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect return ((cause instanceof ConnectException) || (cause instanceof UnresolvedAddressException)); } - private void getDelegate() throws AMQProtocolException + private void initDelegate(ProtocolVersion pe) throws AMQProtocolException { try { - Class c = Class.forName("org.apache.qpid.client.AMQConnectionDelegate_" + - TransportConstants.getVersionMajor() + "_" + - TransportConstants.getVersionMinor()); - Class partypes[] = new Class[1]; + Class c = Class.forName(String.format + ("org.apache.qpid.client.AMQConnectionDelegate_%s_%s", + pe.getMajorVersion(), pe.getMinorVersion())); + Class partypes[] = new Class[1]; partypes[0] = AMQConnection.class; _delegate = (AMQConnectionDelegate) c.getConstructor(partypes).newInstance(this); } - catch (Exception e) + catch (ClassNotFoundException e) + { + throw new AMQProtocolException + (AMQConstant.UNSUPPORTED_CLIENT_PROTOCOL_ERROR, + String.format("Protocol: %s.%s is rquired by the broker but is not " + + "currently supported by this client library implementation", + pe.getMajorVersion(), pe.getMinorVersion()), + e); + } + catch (NoSuchMethodException e) + { + throw new RuntimeException("unable to locate constructor for delegate", e); + } + catch (InstantiationException e) + { + throw new RuntimeException("error instantiating delegate", e); + } + catch (IllegalAccessException e) + { + throw new RuntimeException("error accessing delegate", e); + } + catch (InvocationTargetException e) { - throw new AMQProtocolException(AMQConstant.UNSUPPORTED_CLIENT_PROTOCOL_ERROR, - "Protocol: " + TransportConstants.getVersionMajor() + "." - + TransportConstants.getVersionMinor() + " is rquired by the broker but is not " + - "currently supported by this client library implementation", e); + throw new RuntimeException("error invoking delegate", e); } } @@ -669,9 +623,9 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect return false; } - public void makeBrokerConnection(BrokerDetails brokerDetail) throws IOException, AMQException + public ProtocolVersion makeBrokerConnection(BrokerDetails brokerDetail) throws IOException, AMQException { - _delegate.makeBrokerConnection(brokerDetail); + return _delegate.makeBrokerConnection(brokerDetail); } /** @@ -879,7 +833,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect } } - } } @@ -904,14 +857,14 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect } } - public void close() throws JMSException + public void close() throws JMSException { close(DEFAULT_TIMEOUT); } public void close(long timeout) throws JMSException { - close(new ArrayList<AMQSession>(_sessions.values()),timeout); + close(new ArrayList<AMQSession>(_sessions.values()), timeout); } public void close(List<AMQSession> sessions, long timeout) throws JMSException @@ -924,12 +877,12 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect private void doClose(List<AMQSession> sessions, long timeout) throws JMSException { - synchronized(_sessionCreationLock) + synchronized (_sessionCreationLock) { - if(!sessions.isEmpty()) + if (!sessions.isEmpty()) { AMQSession session = sessions.remove(0); - synchronized(session.getMessageDeliveryLock()) + synchronized (session.getMessageDeliveryLock()) { doClose(sessions, timeout); } @@ -1132,7 +1085,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect { return _sessions; } - + public String getUsername() { return _username; @@ -1309,6 +1262,8 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect if (cause instanceof IOException) { closer = !_closed.getAndSet(true); + + _protocolHandler.getProtocolSession().notifyError(je); } if (_exceptionListener != null) @@ -1351,7 +1306,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect { if (cause instanceof AMQException) { - return ((AMQException)cause).isHardError(); + return ((AMQException) cause).isHardError(); } return true; @@ -1367,24 +1322,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect _sessions.remove(channelId); } - /** - * For all sessions, and for all consumers in those sessions, resubscribe. This is called during failover handling. - * The caller must hold the failover mutex before calling this method. - */ - public void resubscribeSesssions() throws JMSException, AMQException, FailoverException - { - ArrayList sessions = new ArrayList(_sessions.values()); - _logger.info(MessageFormat.format("Resubscribing sessions = {0} sessions.size={1}", sessions, sessions.size())); // FIXME: removeKey? - for (Iterator it = sessions.iterator(); it.hasNext();) - { - AMQSession s = (AMQSession) it.next(); - // _protocolHandler.addSessionByChannel(s.getChannelId(), s); - reopenChannel(s.getChannelId(), s.getDefaultPrefetchHigh(), s.getDefaultPrefetchLow(), s.getTransacted()); - s.resubscribe(); - s.setFlowControl(true); - } - } - public String toString() { StringBuffer buf = new StringBuffer("AMQConnection:\n"); @@ -1495,7 +1432,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect */ public long getMaxPrefetch() { - return _maxPrefetch; + return _maxPrefetch; } /** diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java index 07bd7ea0ae..7f36ec6e99 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java @@ -27,12 +27,13 @@ import javax.jms.XASession; import org.apache.qpid.AMQException; import org.apache.qpid.client.failover.FailoverException; +import org.apache.qpid.framing.ProtocolVersion; import org.apache.qpid.jms.BrokerDetails; import org.apache.qpid.jms.Session; public interface AMQConnectionDelegate { - public void makeBrokerConnection(BrokerDetails brokerDetail) throws IOException, AMQException; + public ProtocolVersion makeBrokerConnection(BrokerDetails brokerDetail) throws IOException, AMQException; public Session createSession(final boolean transacted, final int acknowledgeMode, final int prefetchHigh, final int prefetchLow) throws JMSException; diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java index 61c06df7a5..a2df2f3cf2 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java @@ -9,13 +9,14 @@ import org.apache.qpid.AMQException; import org.apache.qpid.AMQProtocolException; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.client.failover.FailoverException; +import org.apache.qpid.framing.ProtocolVersion; import org.apache.qpid.jms.BrokerDetails; import org.apache.qpid.jms.Session; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.ClosedListener; -import org.apache.qpidity.ErrorCode; -import org.apache.qpidity.QpidException; -import org.apache.qpidity.ProtocolException; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.ClosedListener; +import org.apache.qpid.ErrorCode; +import org.apache.qpid.QpidException; +import org.apache.qpid.transport.ProtocolVersionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,7 +35,7 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Closed /** * The QpidConeection instance that is mapped with thie JMS connection. */ - org.apache.qpidity.nclient.Connection _qpidConnection; + org.apache.qpid.nclient.Connection _qpidConnection; //--- constructor public AMQConnectionDelegate_0_10(AMQConnection conn) @@ -101,7 +102,7 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Closed * @throws IOException * @throws AMQException */ - public void makeBrokerConnection(BrokerDetails brokerDetail) throws IOException, AMQException + public ProtocolVersion makeBrokerConnection(BrokerDetails brokerDetail) throws IOException, AMQException { _qpidConnection = Client.createConnection(); try @@ -115,15 +116,18 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Closed _qpidConnection.connect(brokerDetail.getHost(), brokerDetail.getPort(), _conn.getVirtualHost(), _conn.getUsername(), _conn.getPassword()); _qpidConnection.setClosedListener(this); + _conn._connected = true; } - catch(ProtocolException pe) + catch(ProtocolVersionException pe) { - throw new AMQProtocolException(null, pe.getMessage(), pe); + return new ProtocolVersion(pe.getMajor(), pe.getMinor()); } catch (QpidException e) { throw new AMQException(AMQConstant.CHANNEL_ERROR, "cannot connect to broker", e); } + + return null; } /** diff --git a/java/client/src/main/java/org/apache/qpid/client/state/StateListener.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_9.java index df207a0a23..d95e2e3dff 100644..100755 --- a/java/client/src/main/java/org/apache/qpid/client/state/StateListener.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_9.java @@ -7,9 +7,9 @@ * 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 @@ -18,13 +18,15 @@ * under the License. * */ -package org.apache.qpid.client.state; +package org.apache.qpid.client; -import org.apache.qpid.AMQException; -public interface StateListener +public class AMQConnectionDelegate_0_9 extends AMQConnectionDelegate_8_0 { - void stateChanged(AMQState oldState, AMQState newState) throws AMQException; - void error(Throwable t); + public AMQConnectionDelegate_0_9(AMQConnection conn) + { + super(conn); + } + } diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_8.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java index 637cff5b7e..2ec8737d16 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_8.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java @@ -25,7 +25,9 @@ import java.net.ConnectException; import java.nio.channels.UnresolvedAddressException; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.EnumSet; import java.util.Iterator; +import java.util.Set; import javax.jms.JMSException; import javax.jms.XASession; @@ -35,21 +37,24 @@ import org.apache.qpid.client.failover.FailoverException; import org.apache.qpid.client.failover.FailoverProtectedOperation; import org.apache.qpid.client.failover.FailoverRetrySupport; import org.apache.qpid.client.state.AMQState; +import org.apache.qpid.client.state.StateWaiter; import org.apache.qpid.client.transport.TransportConnection; import org.apache.qpid.framing.BasicQosBody; import org.apache.qpid.framing.BasicQosOkBody; import org.apache.qpid.framing.ChannelOpenBody; import org.apache.qpid.framing.ChannelOpenOkBody; +import org.apache.qpid.framing.ProtocolVersion; import org.apache.qpid.framing.TxSelectBody; import org.apache.qpid.framing.TxSelectOkBody; import org.apache.qpid.jms.BrokerDetails; import org.apache.qpid.jms.ChannelLimitReachedException; +import org.apache.qpid.transport.network.io.IoTransport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class AMQConnectionDelegate_0_8 implements AMQConnectionDelegate +public class AMQConnectionDelegate_8_0 implements AMQConnectionDelegate { - private static final Logger _logger = LoggerFactory.getLogger(AMQConnectionDelegate_0_8.class); + private static final Logger _logger = LoggerFactory.getLogger(AMQConnectionDelegate_8_0.class); private AMQConnection _conn; @@ -59,7 +64,7 @@ public class AMQConnectionDelegate_0_8 implements AMQConnectionDelegate } - public AMQConnectionDelegate_0_8(AMQConnection conn) + public AMQConnectionDelegate_8_0(AMQConnection conn) { _conn = conn; } @@ -76,24 +81,36 @@ public class AMQConnectionDelegate_0_8 implements AMQConnectionDelegate return ((cause instanceof ConnectException) || (cause instanceof UnresolvedAddressException)); } - public void makeBrokerConnection(BrokerDetails brokerDetail) throws IOException, AMQException + public ProtocolVersion makeBrokerConnection(BrokerDetails brokerDetail) throws AMQException, IOException { - try + final Set<AMQState> openOrClosedStates = + EnumSet.of(AMQState.CONNECTION_OPEN, AMQState.CONNECTION_CLOSED); + + + StateWaiter waiter = _conn._protocolHandler.createWaiter(openOrClosedStates); + + // TODO: use system property thingy for this + if (System.getProperty("UseTransportIo", "false").equals("false")) { TransportConnection.getInstance(brokerDetail).connect(_conn._protocolHandler, brokerDetail); - // this blocks until the connection has been set up or when an error - // has prevented the connection being set up - _conn._protocolHandler.attainState(AMQState.CONNECTION_OPEN); - _conn._failoverPolicy.attainedConnection(); - - // Again this should be changed to a suitable notify - _conn._connected = true; + } + else + { + _conn.getProtocolHandler().createIoTransportSession(brokerDetail); } - catch (AMQException e) + + // this blocks until the connection has been set up or when an error + // has prevented the connection being set up + + AMQState state = waiter.await(); + + if(state == AMQState.CONNECTION_OPEN) { - _conn._lastAMQException = e; - throw e; + _conn._failoverPolicy.attainedConnection(); + _conn._connected = true; } + + return null; } public org.apache.qpid.jms.Session createSession(final boolean transacted, final int acknowledgeMode, final int prefetch) diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionFactory.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionFactory.java index fd8063e99b..01a915f2cc 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionFactory.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionFactory.java @@ -38,7 +38,6 @@ import javax.naming.spi.ObjectFactory; import org.apache.qpid.jms.ConnectionURL; import org.apache.qpid.url.AMQBindingURL; import org.apache.qpid.url.URLSyntaxException; -import org.apache.qpidity.transport.TransportConstants; public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory, @@ -294,14 +293,23 @@ public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionF public Connection createConnection(String userName, String password) throws JMSException { + return createConnection(userName, password, null); + } + + public Connection createConnection(String userName, String password, String id) throws JMSException + { try { if (_connectionDetails != null) { _connectionDetails.setUsername(userName); _connectionDetails.setPassword(password); - - if (_connectionDetails.getClientName() == null || _connectionDetails.getClientName().equals("")) + + if (id != null && !id.equals("")) + { + _connectionDetails.setClientName(id); + } + else if (_connectionDetails.getClientName() == null || _connectionDetails.getClientName().equals("")) { _connectionDetails.setClientName(getUniqueClientID()); } @@ -309,7 +317,7 @@ public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionF } else { - return new AMQConnection(_host, _port, userName, password, getUniqueClientID(), _virtualPath); + return new AMQConnection(_host, _port, userName, password, (id != null ? id : getUniqueClientID()), _virtualPath); } } catch (Exception e) @@ -434,23 +442,15 @@ public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionF */ public XAConnection createXAConnection() throws JMSException { - if (TransportConstants.getVersionMajor() == 0 && - TransportConstants.getVersionMinor() == 8) + try { - throw new UnsupportedOperationException("This protocol version does not support XA operations"); + return new XAConnectionImpl(_connectionDetails, _sslConfig); } - else + catch (Exception e) { - try - { - return new XAConnectionImpl(_connectionDetails, _sslConfig); - } - catch (Exception e) - { - JMSException jmse = new JMSException("Error creating connection: " + e.getMessage()); - jmse.setLinkedException(e); - throw jmse; - } + JMSException jmse = new JMSException("Error creating connection: " + e.getMessage()); + jmse.setLinkedException(e); + throw jmse; } } diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java index 0ac73d7460..21b63c1fdb 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java @@ -289,7 +289,7 @@ public class AMQConnectionURL implements ConnectionURL public static void main(String[] args) throws URLSyntaxException { String url2 = - "amqp://ritchiem:bob@temp?brokerlist='tcp://localhost:5672;jcp://fancyserver:3000/',failover='roundrobin'"; + "amqp://ritchiem:bob@temp/testHost?brokerlist='tcp://localhost:5672;tcp://fancyserver:3000/',failover='roundrobin'"; // "amqp://user:pass@clientid/virtualhost?brokerlist='tcp://host:1?option1=\'value\',option2=\'value\';vm://:3?option1=\'value\'',failover='method?option1=\'value\',option2='value''"; ConnectionURL connectionurl2 = new AMQConnectionURL(url2); diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java b/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java index 52080112c9..6c78b754bb 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java @@ -65,9 +65,9 @@ public abstract class AMQDestination implements Destination, Referenceable private static final int IS_EXCLUSIVE_MASK = 0x2; private static final int IS_AUTODELETE_MASK = 0x4; - public static final Integer QUEUE_TYPE = Integer.valueOf(1); - public static final Integer TOPIC_TYPE = Integer.valueOf(2); - public static final Integer UNKNOWN_TYPE = Integer.valueOf(3); + public static final int QUEUE_TYPE = 1; + public static final int TOPIC_TYPE = 2; + public static final int UNKNOWN_TYPE = 3; protected AMQDestination(String url) throws URISyntaxException { diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java index 3b51fb8db0..5203a27f42 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java @@ -63,63 +63,54 @@ import org.apache.qpid.AMQDisconnectedException; import org.apache.qpid.AMQException; import org.apache.qpid.AMQInvalidArgumentException; import org.apache.qpid.AMQInvalidRoutingKeyException; -import org.apache.qpid.AMQUndeliveredException; import org.apache.qpid.client.failover.FailoverException; import org.apache.qpid.client.failover.FailoverNoopSupport; import org.apache.qpid.client.failover.FailoverProtectedOperation; import org.apache.qpid.client.failover.FailoverRetrySupport; -import org.apache.qpid.client.message.AbstractJMSMessage; -import org.apache.qpid.client.message.JMSBytesMessage; -import org.apache.qpid.client.message.JMSMapMessage; -import org.apache.qpid.client.message.JMSObjectMessage; -import org.apache.qpid.client.message.JMSStreamMessage; -import org.apache.qpid.client.message.JMSTextMessage; -import org.apache.qpid.client.message.MessageFactoryRegistry; -import org.apache.qpid.client.message.ReturnMessage; -import org.apache.qpid.client.message.UnprocessedMessage; +import org.apache.qpid.client.message.*; import org.apache.qpid.client.protocol.AMQProtocolHandler; import org.apache.qpid.client.util.FlowControllingBlockingQueue; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.AMQState; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.FieldTableFactory; import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.jms.Session; -import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.url.AMQBindingURL; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * * <p/><table id="crc"><caption>CRC Card</caption> * <tr><th> Responsibilities <th> Collaborations * <tr><td> * </table> * * @todo Different FailoverSupport implementation are needed on the same method call, in different situations. For - * example, when failing-over and reestablishing the bindings, the bind cannot be interrupted by a second - * fail-over, if it fails with an exception, the fail-over process should also fail. When binding outside of - * the fail-over process, the retry handler could be used to automatically retry the operation once the connection - * has been reestablished. All fail-over protected operations should be placed in private methods, with - * FailoverSupport passed in by the caller to provide the correct support for the calling context. Sometimes the - * fail-over process sets a nowait flag and uses an async method call instead. - * + * example, when failing-over and reestablishing the bindings, the bind cannot be interrupted by a second + * fail-over, if it fails with an exception, the fail-over process should also fail. When binding outside of + * the fail-over process, the retry handler could be used to automatically retry the operation once the connection + * has been reestablished. All fail-over protected operations should be placed in private methods, with + * FailoverSupport passed in by the caller to provide the correct support for the calling context. Sometimes the + * fail-over process sets a nowait flag and uses an async method call instead. * @todo Two new objects created on every failover supported method call. Consider more efficient ways of doing this, - * after looking at worse bottlenecks first. + * after looking at worse bottlenecks first. */ -public abstract class AMQSession extends Closeable implements Session, QueueSession, TopicSession +public abstract class AMQSession<C extends BasicMessageConsumer, P extends BasicMessageProducer> extends Closeable implements Session, QueueSession, TopicSession { - public static final class IdToConsumerMap + + + public static final class IdToConsumerMap<C extends BasicMessageConsumer> { private final BasicMessageConsumer[] _fastAccessConsumers = new BasicMessageConsumer[16]; - private final ConcurrentHashMap<Integer, BasicMessageConsumer> _slowAccessConsumers = new ConcurrentHashMap<Integer, BasicMessageConsumer>(); - + private final ConcurrentHashMap<Integer, C> _slowAccessConsumers = new ConcurrentHashMap<Integer, C>(); - public BasicMessageConsumer get(int id) + public C get(int id) { - if((id & 0xFFFFFFF0) == 0) + if ((id & 0xFFFFFFF0) == 0) { - return _fastAccessConsumers[id]; + return (C) _fastAccessConsumers[id]; } else { @@ -127,12 +118,12 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess } } - public BasicMessageConsumer put(int id, BasicMessageConsumer consumer) + public C put(int id, C consumer) { - BasicMessageConsumer oldVal; - if((id & 0xFFFFFFF0) == 0) + C oldVal; + if ((id & 0xFFFFFFF0) == 0) { - oldVal = _fastAccessConsumers[id]; + oldVal = (C) _fastAccessConsumers[id]; _fastAccessConsumers[id] = consumer; } else @@ -144,13 +135,12 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess } - - public BasicMessageConsumer remove(int id) + public C remove(int id) { - BasicMessageConsumer consumer; - if((id & 0xFFFFFFF0) == 0) + C consumer; + if ((id & 0xFFFFFFF0) == 0) { - consumer = _fastAccessConsumers[id]; + consumer = (C) _fastAccessConsumers[id]; _fastAccessConsumers[id] = null; } else @@ -162,15 +152,15 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess } - public Collection<BasicMessageConsumer> values() + public Collection<C> values() { - ArrayList<BasicMessageConsumer> values = new ArrayList<BasicMessageConsumer>(); + ArrayList<C> values = new ArrayList<C>(); - for(int i = 0; i < 16; i++) + for (int i = 0; i < 16; i++) { - if(_fastAccessConsumers[i] != null) + if (_fastAccessConsumers[i] != null) { - values.add(_fastAccessConsumers[i]); + values.add((C) _fastAccessConsumers[i]); } } values.addAll(_slowAccessConsumers.values()); @@ -178,11 +168,10 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess return values; } - public void clear() { _slowAccessConsumers.clear(); - for(int i = 0; i<16; i++) + for (int i = 0; i < 16; i++) { _fastAccessConsumers[i] = null; } @@ -192,8 +181,6 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess /** Used for debugging. */ private static final Logger _logger = LoggerFactory.getLogger(AMQSession.class); - /** Used for debugging in the dispatcher. */ - private static final Logger _dispatcherLogger = LoggerFactory.getLogger(Dispatcher.class); /** The default maximum number of prefetched message at which to suspend the channel. */ public static final int DEFAULT_PREFETCH_HIGH_MARK = 5000; @@ -243,7 +230,6 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess /** Holds this session unique identifier, used to distinguish it from other sessions. */ protected int _channelId; - /** @todo This does not appear to be set? */ private int _ticket; /** Holds the high mark for prefetched message, at which the session is suspended. */ @@ -270,8 +256,8 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * Holds a mapping from message consumers to their identifying names, so that their subscriptions may be looked * up in the {@link #_subscriptions} map. */ - protected final ConcurrentHashMap<BasicMessageConsumer, String> _reverseSubscriptionMap = - new ConcurrentHashMap<BasicMessageConsumer, String>(); + protected final ConcurrentHashMap<C, String> _reverseSubscriptionMap = + new ConcurrentHashMap<C, String>(); /** * Used to hold incoming messages. @@ -280,19 +266,13 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess */ protected final FlowControllingBlockingQueue _queue; - /** - * Holds the highest received delivery tag. - */ + /** Holds the highest received delivery tag. */ private final AtomicLong _highestDeliveryTag = new AtomicLong(-1); - /** - * All the not yet acknowledged message tags - */ + /** All the not yet acknowledged message tags */ protected ConcurrentLinkedQueue<Long> _unacknowledgedMessageTags = new ConcurrentLinkedQueue<Long>(); - /** - * All the delivered message tags - */ + /** All the delivered message tags */ protected ConcurrentLinkedQueue<Long> _deliveredMessageTags = new ConcurrentLinkedQueue<Long>(); /** Holds the dispatcher thread for this session. */ @@ -314,16 +294,16 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * Maps from identifying tags to message consumers, in order to pass dispatch incoming messages to the right * consumer. */ - protected final IdToConsumerMap _consumers = new IdToConsumerMap(); - - //Map<AMQShortString, BasicMessageConsumer> _consumers = - //new ConcurrentHashMap<AMQShortString, BasicMessageConsumer>(); + protected final IdToConsumerMap<C> _consumers = new IdToConsumerMap<C>(); + + //Map<AMQShortString, BasicMessageConsumer> _consumers = + //new ConcurrentHashMap<AMQShortString, BasicMessageConsumer>(); /** * Contains a list of consumers which have been removed but which might still have * messages to acknowledge, eg in client ack or transacted modes */ - private CopyOnWriteArrayList<BasicMessageConsumer> _removedConsumers = new CopyOnWriteArrayList<BasicMessageConsumer>(); + private CopyOnWriteArrayList<C> _removedConsumers = new CopyOnWriteArrayList<C>(); /** Provides a count of consumers on destinations, in order to be able to know if a destination has consumers. */ private ConcurrentHashMap<Destination, AtomicInteger> _destinationConsumerCount = @@ -377,10 +357,8 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess /** Session state : used to detect if commit is a) required b) allowed , i.e. does the tx span failover. */ private boolean _dirty; - /** Has failover occured on this session */ - private boolean _failedOver; - - + /** Has failover occured on this session with outstanding actions to commit? */ + private boolean _failedOverDirty; private static final class FlowControlIndicator { @@ -388,7 +366,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess public synchronized void setFlowControl(boolean flowControl) { - _flowControl= flowControl; + _flowControl = flowControl; notify(); } @@ -412,7 +390,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * @param defaultPrefetchHighMark The maximum number of messages to prefetched before suspending the session. * @param defaultPrefetchLowMark The number of prefetched messages at which to resume the session. */ - AMQSession(AMQConnection con, int channelId, boolean transacted, int acknowledgeMode, + protected AMQSession(AMQConnection con, int channelId, boolean transacted, int acknowledgeMode, MessageFactoryRegistry messageFactoryRegistry, int defaultPrefetchHighMark, int defaultPrefetchLowMark) { @@ -445,21 +423,25 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess new FlowControllingBlockingQueue(_defaultPrefetchHighMark, _defaultPrefetchLowMark, new FlowControllingBlockingQueue.ThresholdListener() { + private final AtomicBoolean _suspendState = new AtomicBoolean(); + public void aboveThreshold(int currentValue) { - _logger.debug( - "Above threshold(" + _defaultPrefetchHighMark - + ") so suspending channel. Current value is " + currentValue); - new Thread(new SuspenderRunner(true)).start(); + _logger.debug( + "Above threshold(" + _defaultPrefetchHighMark + + ") so suspending channel. Current value is " + currentValue); + _suspendState.set(true); + new Thread(new SuspenderRunner(_suspendState)).start(); } public void underThreshold(int currentValue) { - _logger.debug( - "Below threshold(" + _defaultPrefetchLowMark - + ") so unsuspending channel. Current value is " + currentValue); - new Thread(new SuspenderRunner(false)).start(); + _logger.debug( + "Below threshold(" + _defaultPrefetchLowMark + + ") so unsuspending channel. Current value is " + currentValue); + _suspendState.set(false); + new Thread(new SuspenderRunner(_suspendState)).start(); } }); @@ -499,10 +481,30 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess close(-1); } + public void checkNotClosed() throws JMSException + { + try + { + super.checkNotClosed(); + } + catch (IllegalStateException ise) + { + // if the Connection has closed then we should throw any exception that has occured that we were not waiting for + AMQStateManager manager = _connection.getProtocolHandler().getStateManager(); + + if (manager.getCurrentState().equals(AMQState.CONNECTION_CLOSED) && manager.getLastException() != null) + { + ise.setLinkedException(manager.getLastException()); + } + + throw ise; + } + } + public BytesMessage createBytesMessage() throws JMSException { checkNotClosed(); - return new JMSBytesMessage(); + return new JMSBytesMessage(getMessageDelegateFactory()); } /** @@ -515,7 +517,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess if (isClosed()) { throw new IllegalStateException("Session is already closed"); - } + } else if (hasFailedOver()) { throw new IllegalStateException("has failed over"); @@ -560,39 +562,35 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * @param exchangeName The exchange to bind the queue on. * * @throws AMQException If the queue cannot be bound for any reason. - * * @todo Be aware of possible changes to parameter order as versions change. - * * @todo Document the additional arguments that may be passed in the field table. Are these for headers exchanges? */ public void bindQueue(final AMQShortString queueName, final AMQShortString routingKey, final FieldTable arguments, - final AMQShortString exchangeName,final AMQDestination destination) throws AMQException + final AMQShortString exchangeName, final AMQDestination destination) throws AMQException { /*new FailoverRetrySupport<Object, AMQException>(new FailoverProtectedOperation<Object, AMQException>()*/ new FailoverNoopSupport<Object, AMQException>(new FailoverProtectedOperation<Object, AMQException>() { public Object execute() throws AMQException, FailoverException { - sendQueueBind(queueName,routingKey,arguments,exchangeName,destination); + sendQueueBind(queueName, routingKey, arguments, exchangeName, destination); return null; } }, _connection).execute(); } - - public void addBindingKey(BasicMessageConsumer consumer, AMQDestination amqd, String routingKey) throws AMQException + public void addBindingKey(C consumer, AMQDestination amqd, String routingKey) throws AMQException { - if( consumer.getQueuename() != null) + if (consumer.getQueuename() != null) { - bindQueue(consumer.getQueuename(), new AMQShortString(routingKey), new FieldTable(), amqd.getExchangeName(),amqd); + bindQueue(consumer.getQueuename(), new AMQShortString(routingKey), new FieldTable(), amqd.getExchangeName(), amqd); } } public abstract void sendQueueBind(final AMQShortString queueName, final AMQShortString routingKey, final FieldTable arguments, - final AMQShortString exchangeName,AMQDestination destination) throws AMQException, FailoverException; + final AMQShortString exchangeName, AMQDestination destination) throws AMQException, FailoverException; /** - * Closes the session. * * <p/>Note that this operation succeeds automatically if a fail-over interupts the sycnronous request to close @@ -602,14 +600,11 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * @param timeout The timeout in milliseconds to wait for the session close acknoledgement from the broker. * * @throws JMSException If the JMS provider fails to close the session due to some internal error. - * * @todo Be aware of possible changes to parameter order as versions change. - * * @todo Not certain about the logic of ignoring the failover exception, because the channel won't be - * re-opened. May need to examine this more carefully. - * + * re-opened. May need to examine this more carefully. * @todo Note that taking the failover mutex doesn't prevent this operation being interrupted by a failover, - * because the failover process sends the failover event before acquiring the mutex itself. + * because the failover process sends the failover event before acquiring the mutex itself. */ public void close(long timeout) throws JMSException { @@ -617,13 +612,13 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); _logger.info("Closing session: " + this); // + ":" - // + Arrays.asList(stackTrace).subList(3, stackTrace.length - 1)); + // + Arrays.asList(stackTrace).subList(3, stackTrace.length - 1)); } // Ensure we only try and close an open session. if (!_closed.getAndSet(true)) { - synchronized (_connection.getFailoverMutex()) + synchronized (getFailoverMutex()) { // We must close down all producers and consumers in an orderly fashion. This is the only method // that can be called from a different thread of control from the one controlling the session. @@ -634,7 +629,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess try { - sendClose(timeout); + sendClose(timeout); } catch (AMQException e) { @@ -685,7 +680,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess if (!_closed.getAndSet(true)) { - synchronized (_connection.getFailoverMutex()) + synchronized (getFailoverMutex()) { synchronized (_messageDeliveryLock) { @@ -701,7 +696,6 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess amqe = new AMQException("Closing session forcibly", e); } - _connection.deregisterSession(_channelId); closeProducersAndConsumers(amqe); } @@ -719,12 +713,11 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * @throws JMSException If the JMS provider fails to commit the transaction due to some internal error. This does * not mean that the commit is known to have failed, merely that it is not known whether it * failed or not. - * * @todo Be aware of possible changes to parameter order as versions change. */ public void commit() throws JMSException { - checkTransacted(); + checkTransacted(); try { @@ -743,6 +736,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess } // Commits outstanding messages and acknowledgments sendCommit(); + markClean(); } catch (AMQException e) { @@ -756,11 +750,12 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess public abstract void sendCommit() throws AMQException, FailoverException; - public void confirmConsumerCancelled(AMQShortString consumerTag) + + public void confirmConsumerCancelled(int consumerTag) { // Remove the consumer from the map - BasicMessageConsumer consumer = _consumers.get(consumerTag.toIntValue()); + C consumer = _consumers.get(consumerTag); if (consumer != null) { if (!consumer.isNoConsume()) // Normal Consumer @@ -788,10 +783,8 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess // consumer.markClosed(); - - if (consumer.isAutoClose()) - { + { // There is a small window where the message is between the two queues in the dispatcher. if (consumer.isClosed()) { @@ -802,6 +795,10 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess deregisterConsumer(consumer); } + else + { + _queue.add(new CloseConsumerMessage(consumer)); + } } } } @@ -847,7 +844,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess false, false); } - public MessageConsumer createExclusiveConsumer(Destination destination) throws JMSException + public C createExclusiveConsumer(Destination destination) throws JMSException { checkValidDestination(destination); @@ -855,7 +852,6 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess false, false); } - public MessageConsumer createConsumer(Destination destination, String messageSelector) throws JMSException { checkValidDestination(destination); @@ -873,7 +869,6 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess messageSelector, null, false, false); } - public MessageConsumer createExclusiveConsumer(Destination destination, String messageSelector, boolean noLocal) throws JMSException { @@ -883,7 +878,6 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess messageSelector, null, false, false); } - public MessageConsumer createConsumer(Destination destination, int prefetch, boolean noLocal, boolean exclusive, String selector) throws JMSException { @@ -920,7 +914,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess public abstract TopicSubscriber createDurableSubscriber(Topic topic, String name) throws JMSException; public TopicSubscriber createDurableSubscriber(Topic topic, String name, String messageSelector, boolean noLocal) - throws JMSException + throws JMSException { checkNotClosed(); checkValidTopic(topic); @@ -929,8 +923,8 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess _subscriptions.get(name).close(); } AMQTopic dest = AMQTopic.createDurableTopic((AMQTopic) topic, name, _connection); - BasicMessageConsumer consumer = (BasicMessageConsumer) createConsumer(dest, messageSelector, noLocal); - TopicSubscriberAdaptor subscriber = new TopicSubscriberAdaptor(dest, consumer); + C consumer = (C) createConsumer(dest, messageSelector, noLocal); + TopicSubscriberAdaptor<C> subscriber = new TopicSubscriberAdaptor(dest, consumer); _subscriptions.put(name, subscriber); _reverseSubscriptionMap.put(subscriber.getMessageConsumer(), name); @@ -940,7 +934,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess public MapMessage createMapMessage() throws JMSException { checkNotClosed(); - return new JMSMapMessage(); + return new JMSMapMessage(getMessageDelegateFactory()); } public javax.jms.Message createMessage() throws JMSException @@ -951,7 +945,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess public ObjectMessage createObjectMessage() throws JMSException { checkNotClosed(); - return (ObjectMessage) new JMSObjectMessage(); + return (ObjectMessage) new JMSObjectMessage(getMessageDelegateFactory()); } public ObjectMessage createObjectMessage(Serializable object) throws JMSException @@ -962,23 +956,23 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess return msg; } - public BasicMessageProducer createProducer(Destination destination) throws JMSException + public P createProducer(Destination destination) throws JMSException { return createProducerImpl(destination, DEFAULT_MANDATORY, DEFAULT_IMMEDIATE); } - public BasicMessageProducer createProducer(Destination destination, boolean immediate) throws JMSException + public P createProducer(Destination destination, boolean immediate) throws JMSException { return createProducerImpl(destination, DEFAULT_MANDATORY, immediate); } - public BasicMessageProducer createProducer(Destination destination, boolean mandatory, boolean immediate) + public P createProducer(Destination destination, boolean mandatory, boolean immediate) throws JMSException { return createProducerImpl(destination, mandatory, immediate); } - public BasicMessageProducer createProducer(Destination destination, boolean mandatory, boolean immediate, + public P createProducer(Destination destination, boolean mandatory, boolean immediate, boolean waitUntilSent) throws JMSException { return createProducerImpl(destination, mandatory, immediate, waitUntilSent); @@ -988,7 +982,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess { checkNotClosed(); - return new TopicPublisherAdapter((BasicMessageProducer) createProducer(topic,false,false), topic); + return new TopicPublisherAdapter((P) createProducer(topic, false, false), topic); } public Queue createQueue(String queueName) throws JMSException @@ -1025,24 +1019,44 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * @param exclusive Flag to indicate that the queue is exclusive to this client. * * @throws AMQException If the queue cannot be declared for any reason. - * * @todo Be aware of possible changes to parameter order as versions change. */ public void createQueue(final AMQShortString name, final boolean autoDelete, final boolean durable, final boolean exclusive) throws AMQException { + createQueue(name, autoDelete, durable, exclusive, null); + } + + /** + * Declares the named queue. + * + * <p/>Note that this operation automatically retries in the event of fail-over. + * + * @param name The name of the queue to declare. + * @param autoDelete + * @param durable Flag to indicate that the queue is durable. + * @param exclusive Flag to indicate that the queue is exclusive to this client. + * @param arguments Arguments used to set special properties of the queue + * + * @throws AMQException If the queue cannot be declared for any reason. + * @todo Be aware of possible changes to parameter order as versions change. + */ + public void createQueue(final AMQShortString name, final boolean autoDelete, final boolean durable, + final boolean exclusive, final Map<String, Object> arguments) throws AMQException + { new FailoverRetrySupport<Object, AMQException>(new FailoverProtectedOperation<Object, AMQException>() { public Object execute() throws AMQException, FailoverException { - sendCreateQueue(name, autoDelete, durable, exclusive); + sendCreateQueue(name, autoDelete, durable, exclusive, arguments); return null; } }, _connection).execute(); } public abstract void sendCreateQueue(AMQShortString name, final boolean autoDelete, final boolean durable, - final boolean exclusive)throws AMQException, FailoverException; + final boolean exclusive, final Map<String, Object> arguments) throws AMQException, FailoverException; + /** * Creates a QueueReceiver * @@ -1056,7 +1070,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess { checkValidDestination(destination); AMQQueue dest = (AMQQueue) destination; - BasicMessageConsumer consumer = (BasicMessageConsumer) createConsumer(destination); + C consumer = (C) createConsumer(destination); return new QueueReceiverAdaptor(dest, consumer); } @@ -1075,7 +1089,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess { checkValidDestination(destination); AMQQueue dest = (AMQQueue) destination; - BasicMessageConsumer consumer = (BasicMessageConsumer) createConsumer(destination, messageSelector); + C consumer = (C) createConsumer(destination, messageSelector); return new QueueReceiverAdaptor(dest, consumer); } @@ -1093,7 +1107,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess { checkNotClosed(); AMQQueue dest = (AMQQueue) queue; - BasicMessageConsumer consumer = (BasicMessageConsumer) createConsumer(dest); + C consumer = (C) createConsumer(dest); return new QueueReceiverAdaptor(dest, consumer); } @@ -1112,7 +1126,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess { checkNotClosed(); AMQQueue dest = (AMQQueue) queue; - BasicMessageConsumer consumer = (BasicMessageConsumer) createConsumer(dest, messageSelector); + C consumer = (C) createConsumer(dest, messageSelector); return new QueueReceiverAdaptor(dest, consumer); } @@ -1127,11 +1141,18 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess public StreamMessage createStreamMessage() throws JMSException { - synchronized (_connection.getFailoverMutex()) + // This method needs to be improved. Throwables only arrive here from the mina : exceptionRecived + // calls through connection.closeAllSessions which is also called by the public connection.close() + // with a null cause + // When we are closing the Session due to a protocol session error we simply create a new AMQException + // with the correct error code and text this is cleary WRONG as the instanceof check below will fail. + // We need to determin here if the connection should be + + synchronized (getFailoverMutex()) { checkNotClosed(); - return new JMSStreamMessage(); + return new JMSStreamMessage(getMessageDelegateFactory()); } } @@ -1150,10 +1171,9 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess AMQTopic dest = checkValidTopic(topic); // AMQTopic dest = new AMQTopic(topic.getTopicName()); - return new TopicSubscriberAdaptor(dest, (BasicMessageConsumer) createExclusiveConsumer(dest)); + return new TopicSubscriberAdaptor(dest, (C) createExclusiveConsumer(dest)); } - /** * Creates a non-durable subscriber with a message selector * @@ -1171,7 +1191,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess AMQTopic dest = checkValidTopic(topic); // AMQTopic dest = new AMQTopic(topic.getTopicName()); - return new TopicSubscriberAdaptor(dest, (BasicMessageConsumer) createExclusiveConsumer(dest, messageSelector, noLocal)); + return new TopicSubscriberAdaptor(dest, (C) createExclusiveConsumer(dest, messageSelector, noLocal)); } public abstract TemporaryQueue createTemporaryQueue() throws JMSException; @@ -1185,14 +1205,19 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess public TextMessage createTextMessage() throws JMSException { - synchronized (_connection.getFailoverMutex()) + synchronized (getFailoverMutex()) { checkNotClosed(); - return new JMSTextMessage(); + return new JMSTextMessage(getMessageDelegateFactory()); } } + protected Object getFailoverMutex() + { + return _connection.getFailoverMutex(); + } + public TextMessage createTextMessage(String text) throws JMSException { @@ -1340,17 +1365,8 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess { _logger.debug("Message[" + message.toString() + "] received in session"); } - - if (message instanceof ReturnMessage) - { - // Return of the bounced message. - returnBouncedMessage((ReturnMessage)message); - } - else - { - _highestDeliveryTag.set(message.getDeliveryTag()); - _queue.add(message); - } + _highestDeliveryTag.set(message.getDeliveryTag()); + _queue.add(message); } public void declareAndBind(AMQDestination amqd) @@ -1360,7 +1376,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess AMQProtocolHandler protocolHandler = getProtocolHandler(); declareExchange(amqd, protocolHandler, false); AMQShortString queueName = declareQueue(amqd, protocolHandler, false); - bindQueue(queueName, amqd.getRoutingKey(), new FieldTable(), amqd.getExchangeName(),amqd); + bindQueue(queueName, amqd.getRoutingKey(), new FieldTable(), amqd.getExchangeName(), amqd); } /** @@ -1375,7 +1391,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * <li>Stop message delivery.</li> * <li>Mark all messages that might have been delivered but not acknowledged as "redelivered". * <li>Restart the delivery sequence including all unacknowledged messages that had been previously delivered. - * Redelivered messages do not have to be delivered in exactly their original delivery order.</li> + * Redelivered messages do not have to be delivered in exactly their original delivery order.</li> * </ul> * * <p/>If the recover operation is interrupted by a fail-over, between asking that the broker begin recovery and @@ -1429,7 +1445,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess } } - abstract void sendRecover() throws AMQException, FailoverException; + protected abstract void sendRecover() throws AMQException, FailoverException; public void rejectMessage(UnprocessedMessage message, boolean requeue) { @@ -1465,7 +1481,6 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * @throws JMSException If the JMS provider fails to rollback the transaction due to some internal error. This does * not mean that the rollback is known to have failed, merely that it is not known whether it * failed or not. - * * @todo Be aware of possible changes to parameter order as versions change. */ public void rollback() throws JMSException @@ -1507,8 +1522,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess public abstract void releaseForRollback(); - public abstract void sendRollback() throws AMQException, FailoverException ; - + public abstract void sendRollback() throws AMQException, FailoverException; public void run() { @@ -1576,7 +1590,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess deleteQueue(AMQTopic.getDurableTopicQueueName(name, _connection)); } - else + else // Queue Browser { if (isQueueBound(getDefaultTopicExchangeName(), AMQTopic.getDurableTopicQueueName(name, _connection))) @@ -1591,7 +1605,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess } } - protected MessageConsumer createConsumerImpl(final Destination destination, final int prefetchHigh, + protected C createConsumerImpl(final Destination destination, final int prefetchHigh, final int prefetchLow, final boolean noLocal, final boolean exclusive, String selector, final FieldTable rawSelector, final boolean noConsume, final boolean autoClose) throws JMSException { @@ -1615,10 +1629,10 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess messageSelector = selector; } - return new FailoverRetrySupport<MessageConsumer, JMSException>( - new FailoverProtectedOperation<MessageConsumer, JMSException>() + return new FailoverRetrySupport<C, JMSException>( + new FailoverProtectedOperation<C, JMSException>() { - public MessageConsumer execute() throws JMSException, FailoverException + public C execute() throws JMSException, FailoverException { checkNotClosed(); @@ -1630,13 +1644,19 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess final FieldTable ft = FieldTableFactory.newFieldTable(); // if (rawSelector != null) // ft.put("headers", rawSelector.getDataAsBytes()); - if (rawSelector != null) + // rawSelector is used by HeadersExchange and is not a JMS Selector + if (rawSelector != null) { ft.addAll(rawSelector); } + + if (messageSelector != null) + { + ft.put(new AMQShortString("x-filter-jms-selector"), messageSelector); + } - BasicMessageConsumer consumer = createMessageConsumer(amqd, prefetchHigh,prefetchLow, - noLocal,exclusive, messageSelector, ft, noConsume, autoClose); + C consumer = createMessageConsumer(amqd, prefetchHigh, prefetchLow, + noLocal, exclusive, messageSelector, ft, noConsume, autoClose); if (_messageListener != null) { @@ -1679,9 +1699,9 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess }, _connection).execute(); } - public abstract BasicMessageConsumer createMessageConsumer(final AMQDestination destination, final int prefetchHigh, - final int prefetchLow, final boolean noLocal, final boolean exclusive, String selector, final FieldTable rawSelector, - final boolean noConsume, final boolean autoClose) throws JMSException; + public abstract C createMessageConsumer(final AMQDestination destination, final int prefetchHigh, + final int prefetchLow, final boolean noLocal, final boolean exclusive, String selector, final FieldTable arguments, + final boolean noConsume, final boolean autoClose) throws JMSException; /** * Called by the MessageConsumer when closing, to deregister the consumer from the map from consumerTag to consumer @@ -1689,9 +1709,9 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * * @param consumer the consum */ - void deregisterConsumer(BasicMessageConsumer consumer) + void deregisterConsumer(C consumer) { - if (_consumers.remove(consumer.getConsumerTag().toIntValue()) != null) + if (_consumers.remove(consumer.getConsumerTag()) != null) { String subscriptionName = _reverseSubscriptionMap.remove(consumer); if (subscriptionName != null) @@ -1744,12 +1764,11 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * @return <tt>true</tt> if the queue is bound to the exchange and routing key, <tt>false</tt> if not. * * @throws JMSException If the query fails for any reason. - * * @todo Be aware of possible changes to parameter order as versions change. */ public abstract boolean isQueueBound(final AMQShortString exchangeName, final AMQShortString queueName, final AMQShortString routingKey) throws JMSException; - + public abstract boolean isQueueBound(final AMQDestination destination) throws JMSException; /** @@ -1771,7 +1790,10 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess */ void resubscribe() throws AMQException { - _failedOver = true; + if (_dirty) + { + _failedOverDirty = true; + } resubscribeProducers(); resubscribeConsumers(); } @@ -1790,10 +1812,9 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * Starts the session, which ensures that it is not suspended and that its event dispatcher is running. * * @throws AMQException If the session cannot be started for any reason. - * * @todo This should be controlled by _stopped as it pairs with the stop method fixme or check the - * FlowControlledBlockingQueue _queue to see if we have flow controlled. will result in sending Flow messages - * for each subsequent call to flow.. only need to do this if we have called stop. + * FlowControlledBlockingQueue _queue to see if we have flow controlled. will result in sending Flow messages + * for each subsequent call to flow.. only need to do this if we have called stop. */ void start() throws AMQException { @@ -1978,12 +1999,12 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess { // we need to clone the list of consumers since the close() method updates the _consumers collection // which would result in a concurrent modification exception - final ArrayList<BasicMessageConsumer> clonedConsumers = new ArrayList<BasicMessageConsumer>(_consumers.values()); + final ArrayList<C> clonedConsumers = new ArrayList<C>(_consumers.values()); - final Iterator<BasicMessageConsumer> it = clonedConsumers.iterator(); + final Iterator<C> it = clonedConsumers.iterator(); while (it.hasNext()) { - final BasicMessageConsumer con = it.next(); + final C con = it.next(); if (error != null) { con.notifyError(error); @@ -1994,7 +2015,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess } } // at this point the _consumers map will be empty - if (_dispatcher != null) + if (_dispatcher != null) { _dispatcher.close(); _dispatcher = null; @@ -2014,7 +2035,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess final Iterator it = clonedProducers.iterator(); while (it.hasNext()) { - final BasicMessageProducer prod = (BasicMessageProducer) it.next(); + final P prod = (P) it.next(); prod.close(); } // at this point the _producers map is empty @@ -2062,20 +2083,18 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * * @param queueName */ - private void consumeFromQueue(BasicMessageConsumer consumer, AMQShortString queueName, + private void consumeFromQueue(C consumer, AMQShortString queueName, AMQProtocolHandler protocolHandler, boolean nowait, String messageSelector) throws AMQException, FailoverException { int tagId = _nextTag++; - // need to generate a consumer tag on the client so we can exploit the nowait flag - AMQShortString tag = new AMQShortString(Integer.toString(tagId)); - consumer.setConsumerTag(tag); + consumer.setConsumerTag(tagId); // we must register the consumer in the map before we actually start listening _consumers.put(tagId, consumer); try { - sendConsume(consumer, queueName, protocolHandler, nowait, messageSelector, tag); + sendConsume(consumer, queueName, protocolHandler, nowait, messageSelector, tagId); } catch (AMQException e) { @@ -2085,27 +2104,27 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess } } - public abstract void sendConsume(BasicMessageConsumer consumer, AMQShortString queueName, - AMQProtocolHandler protocolHandler, boolean nowait, String messageSelector,AMQShortString tag) throws AMQException, FailoverException; + public abstract void sendConsume(C consumer, AMQShortString queueName, + AMQProtocolHandler protocolHandler, boolean nowait, String messageSelector, int tag) throws AMQException, FailoverException; - private BasicMessageProducer createProducerImpl(Destination destination, boolean mandatory, boolean immediate) + private P createProducerImpl(Destination destination, boolean mandatory, boolean immediate) throws JMSException { return createProducerImpl(destination, mandatory, immediate, false); } - private BasicMessageProducer createProducerImpl(final Destination destination, final boolean mandatory, + private P createProducerImpl(final Destination destination, final boolean mandatory, final boolean immediate, final boolean waitUntilSent) throws JMSException { - return new FailoverRetrySupport<BasicMessageProducer, JMSException>( - new FailoverProtectedOperation<BasicMessageProducer, JMSException>() + return new FailoverRetrySupport<P, JMSException>( + new FailoverProtectedOperation<P, JMSException>() { - public BasicMessageProducer execute() throws JMSException, FailoverException + public P execute() throws JMSException, FailoverException { checkNotClosed(); long producerId = getNextProducerId(); - BasicMessageProducer producer = createMessageProducer(destination, mandatory, - immediate, waitUntilSent, producerId); + P producer = createMessageProducer(destination, mandatory, + immediate, waitUntilSent, producerId); registerProducer(producerId, producer); return producer; @@ -2113,21 +2132,20 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess }, _connection).execute(); } - public abstract BasicMessageProducer createMessageProducer(final Destination destination, final boolean mandatory, - final boolean immediate, final boolean waitUntilSent, long producerId); + public abstract P createMessageProducer(final Destination destination, final boolean mandatory, + final boolean immediate, final boolean waitUntilSent, long producerId); private void declareExchange(AMQDestination amqd, AMQProtocolHandler protocolHandler, boolean nowait) throws AMQException { declareExchange(amqd.getExchangeName(), amqd.getExchangeClass(), protocolHandler, nowait); } - /** * Returns the number of messages currently queued for the given destination. * * <p/>Note that this operation automatically retries in the event of fail-over. * - * @param amqd The destination to be checked + * @param amqd The destination to be checked * * @return the number of queued messages. * @@ -2147,7 +2165,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess } - abstract Long requestQueueDepth(AMQDestination amqd) throws AMQException, FailoverException; + protected abstract Long requestQueueDepth(AMQDestination amqd) throws AMQException, FailoverException; /** * Declares the named exchange and type of exchange. @@ -2160,7 +2178,6 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * @param nowait * * @throws AMQException If the exchange cannot be declared for any reason. - * * @todo Be aware of possible changes to parameter order as versions change. */ private void declareExchange(final AMQShortString name, final AMQShortString type, @@ -2177,8 +2194,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess } public abstract void sendExchangeDeclare(final AMQShortString name, final AMQShortString type, final AMQProtocolHandler protocolHandler, - final boolean nowait) throws AMQException, FailoverException; - + final boolean nowait) throws AMQException, FailoverException; /** * Declares a queue for a JMS destination. @@ -2196,9 +2212,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * the client. * * @throws AMQException If the queue cannot be declared for any reason. - * * @todo Verify the destiation is valid or throw an exception. - * * @todo Be aware of possible changes to parameter order as versions change. */ protected AMQShortString declareQueue(final AMQDestination amqd, final AMQProtocolHandler protocolHandler, @@ -2224,7 +2238,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess }, _connection).execute(); } - public abstract void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler)throws AMQException, FailoverException; + public abstract void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler) throws AMQException, FailoverException; /** * Undeclares the specified queue. @@ -2234,7 +2248,6 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * @param queueName The name of the queue to delete. * * @throws JMSException If the queue could not be deleted for any reason. - * * @todo Be aware of possible changes to parameter order as versions change. */ protected void deleteQueue(final AMQShortString queueName) throws JMSException @@ -2256,7 +2269,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess } } - public abstract void sendQueueDelete(final AMQShortString queueName) throws AMQException, FailoverException; + public abstract void sendQueueDelete(final AMQShortString queueName) throws AMQException, FailoverException; private long getNextProducerId() { @@ -2292,12 +2305,12 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess } // we need to clone the list of consumers since the close() method updates the _consumers collection // which would result in a concurrent modification exception - final ArrayList<BasicMessageConsumer> clonedConsumers = new ArrayList<BasicMessageConsumer>(_consumers.values()); + final ArrayList<C> clonedConsumers = new ArrayList<C>(_consumers.values()); - final Iterator<BasicMessageConsumer> it = clonedConsumers.iterator(); + final Iterator<C> it = clonedConsumers.iterator(); while (it.hasNext()) { - final BasicMessageConsumer con = it.next(); + final C con = it.next(); con.markClosed(); } // at this point the _consumers map will be empty @@ -2332,7 +2345,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * * @throws AMQException */ - private void registerConsumer(BasicMessageConsumer consumer, boolean nowait) throws AMQException // , FailoverException + private void registerConsumer(C consumer, boolean nowait) throws AMQException // , FailoverException { AMQDestination amqd = consumer.getDestination(); @@ -2345,8 +2358,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess // store the consumer queue name consumer.setQueuename(queueName); - // bindQueue(amqd, queueName, protocolHandler, consumer.getRawSelectorFieldTable()); - bindQueue(queueName, amqd.getRoutingKey(), consumer.getRawSelectorFieldTable(), amqd.getExchangeName(),amqd); + bindQueue(queueName, amqd.getRoutingKey(), consumer.getArguments(), amqd.getExchangeName(), amqd); // If IMMEDIATE_PREFETCH is not required then suspsend the channel to delay prefetch if (!_immediatePrefetch) @@ -2397,15 +2409,16 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess private void rejectAllMessages(boolean requeue) { - rejectMessagesForConsumerTag(null, requeue); + rejectMessagesForConsumerTag(0, requeue, true); } /** * @param consumerTag The consumerTag to prune from queue or all if null * @param requeue Should the removed messages be requeued (or discarded. Possibly to DLQ) + * @param rejectAllConsumers */ - private void rejectMessagesForConsumerTag(AMQShortString consumerTag, boolean requeue) + private void rejectMessagesForConsumerTag(int consumerTag, boolean requeue, boolean rejectAllConsumers) { Iterator messages = _queue.iterator(); if (_logger.isInfoEnabled()) @@ -2426,12 +2439,12 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess { UnprocessedMessage message = (UnprocessedMessage) messages.next(); - if ((consumerTag == null) || message.getConsumerTag().equals(consumerTag.toString())) + if (rejectAllConsumers || (message.getConsumerTag() == consumerTag)) { if (_logger.isDebugEnabled()) { _logger.debug("Removing message(" + System.identityHashCode(message) + ") from _queue DT:" - + message.getDeliveryTag()); + + message.getDeliveryTag()); } messages.remove(); @@ -2448,12 +2461,11 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess private void resubscribeConsumers() throws AMQException { - ArrayList consumers = new ArrayList(_consumers.values()); + ArrayList<C> consumers = new ArrayList<C>(_consumers.values()); _consumers.clear(); - for (Iterator it = consumers.iterator(); it.hasNext();) - { - BasicMessageConsumer consumer = (BasicMessageConsumer) it.next(); + for (C consumer : consumers) + { consumer.failedOver(); registerConsumer(consumer, true); } @@ -2465,53 +2477,11 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess _logger.info(MessageFormat.format("Resubscribing producers = {0} producers.size={1}", producers, producers.size())); // FIXME: removeKey for (Iterator it = producers.iterator(); it.hasNext();) { - BasicMessageProducer producer = (BasicMessageProducer) it.next(); + P producer = (P) it.next(); producer.resubscribe(); } } - private void returnBouncedMessage(final ReturnMessage msg) - { - _connection.performConnectionTask(new Runnable() - { - public void run() - { - try - { - // Bounced message is processed here, away from the mina thread - AbstractJMSMessage bouncedMessage = - _messageFactoryRegistry.createMessage(0, false, msg.getExchange(), - msg.getRoutingKey(), msg.getContentHeader(), msg.getBodies()); - AMQConstant errorCode = AMQConstant.getConstant(msg.getReplyCode()); - AMQShortString reason = msg.getReplyText(); - _logger.debug("Message returned with error code " + errorCode + " (" + reason + ")"); - - // @TODO should this be moved to an exception handler of sorts. Somewhere errors are converted to correct execeptions. - if (errorCode == AMQConstant.NO_CONSUMERS) - { - _connection.exceptionReceived(new AMQNoConsumersException("Error: " + reason, bouncedMessage, null)); - } - else if (errorCode == AMQConstant.NO_ROUTE) - { - _connection.exceptionReceived(new AMQNoRouteException("Error: " + reason, bouncedMessage, null)); - } - else - { - _connection.exceptionReceived( - new AMQUndeliveredException(errorCode, "Error: " + reason, bouncedMessage, null)); - } - - } - catch (Exception e) - { - _logger.error( - "Caught exception trying to raise undelivered message exception (dump follows) - ignoring...", - e); - } - } - }); - } - /** * Suspends or unsuspends this session. * @@ -2519,7 +2489,6 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess * should be unsuspended. * * @throws AMQException If the session cannot be suspended for any reason. - * * @todo Be aware of possible changes to parameter order as versions change. */ protected void suspendChannel(boolean suspend) throws AMQException // , FailoverException @@ -2560,7 +2529,6 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess return getAMQConnection().getMaxPrefetch() > 0; } - /** Signifies that the session has pending sends to commit. */ public void markDirty() { @@ -2571,7 +2539,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess public void markClean() { _dirty = false; - _failedOver = false; + _failedOverDirty = false; } /** @@ -2581,7 +2549,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess */ public boolean hasFailedOver() { - return _failedOver; + return _failedOverDirty; } /** @@ -2604,12 +2572,11 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess _flowControl.setFlowControl(active); } - public void checkFlowControl() throws InterruptedException { - synchronized(_flowControl) + synchronized (_flowControl) { - while(!_flowControl.getFlowControl()) + while (!_flowControl.getFlowControl()) { _flowControl.wait(); } @@ -2617,6 +2584,9 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess } + /** Used for debugging in the dispatcher. */ + private static final Logger _dispatcherLogger = LoggerFactory.getLogger("org.apache.qpid.client.AMQSession.Dispatcher"); + /** Responsible for decoding a message fragment and passing it to the appropriate message consumer. */ class Dispatcher extends Thread @@ -2629,6 +2599,8 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess private final AtomicLong _rollbackMark = new AtomicLong(-1); private String dispatcherID = "" + System.identityHashCode(this); + + public Dispatcher() { super("Dispatcher-Channel-" + _channelId); @@ -2647,7 +2619,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess } - public void rejectPending(BasicMessageConsumer consumer) + public void rejectPending(C consumer) { synchronized (_lock) { @@ -2662,7 +2634,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess consumer.rollbackPendingMessages(); // Reject messages on pre-dispatch queue - rejectMessagesForConsumerTag(consumer.getConsumerTag(), true); + rejectMessagesForConsumerTag(consumer.getConsumerTag(), true, false); //Let the dispatcher deal with this when it gets to them. // closeConsumer @@ -2689,7 +2661,7 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess _dispatcherLogger.debug("Session Pre Dispatch Queue cleared"); - for (BasicMessageConsumer consumer : _consumers.values()) + for (C consumer : _consumers.values()) { if (!consumer.isNoConsume()) { @@ -2755,7 +2727,8 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess _lock.wait(); } - if (tagLE(deliveryTag, _rollbackMark.get())) + if (!(message instanceof CloseConsumerMessage) + && tagLE(deliveryTag, _rollbackMark.get())) { rejectMessage(message, true); } @@ -2816,8 +2789,8 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess //This if block is not needed anymore as bounce messages are handled separately //if (message.getDeliverBody() != null) //{ - final BasicMessageConsumer consumer = - _consumers.get(message.getConsumerTag().toIntValue()); + final C consumer = + _consumers.get(message.getConsumerTag()); if ((consumer == null) || consumer.isClosed()) { @@ -2826,14 +2799,26 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess if (consumer == null) { _dispatcherLogger.info("Dispatcher(" + dispatcherID + ")Received a message(" + System.identityHashCode(message) + ")" + "[" - + message.getDeliveryTag() + "] from queue " - + message.getConsumerTag() + " )without a handler - rejecting(requeue)..."); + + message.getDeliveryTag() + "] from queue " + + message.getConsumerTag() + " )without a handler - rejecting(requeue)..."); } else { - _dispatcherLogger.info("Received a message(" + System.identityHashCode(message) + ")" + "[" - + message.getDeliveryTag() + "] from queue " + " consumer(" - + message.getConsumerTag() + ") is closed rejecting(requeue)..."); + if (consumer.isNoConsume()) + { + _dispatcherLogger.info("Received a message(" + System.identityHashCode(message) + ")" + "[" + + message.getDeliveryTag() + "] from queue " + " consumer(" + + message.getConsumerTag() + ") is closed and a browser so dropping..."); + //DROP MESSAGE + return; + + } + else + { + _dispatcherLogger.info("Received a message(" + System.identityHashCode(message) + ")" + "[" + + message.getDeliveryTag() + "] from queue " + " consumer(" + + message.getConsumerTag() + ") is closed rejecting(requeue)..."); + } } } // Don't reject if we're already closing @@ -2850,9 +2835,11 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess } } - abstract boolean tagLE(long tag1, long tag2); + protected abstract boolean tagLE(long tag1, long tag2); + + protected abstract boolean updateRollbackMark(long current, long deliveryTag); - abstract boolean updateRollbackMark(long current, long deliveryTag); + public abstract AMQMessageDelegateFactory getMessageDelegateFactory(); /*public void requestAccess(AMQShortString realm, boolean exclusive, boolean passive, boolean active, boolean write, boolean read) throws AMQException @@ -2880,9 +2867,9 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess private class SuspenderRunner implements Runnable { - private boolean _suspend; + private AtomicBoolean _suspend; - public SuspenderRunner(boolean suspend) + public SuspenderRunner(AtomicBoolean suspend) { _suspend = suspend; } @@ -2891,7 +2878,10 @@ public abstract class AMQSession extends Closeable implements Session, QueueSess { try { - suspendChannel(_suspend); + synchronized (_suspensionLock) + { + suspendChannel(_suspend.get()); + } } catch (AMQException e) { diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java b/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java index 4c3d768020..aa0ff66545 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java @@ -27,17 +27,18 @@ import org.apache.qpid.client.failover.FailoverProtectedOperation; import org.apache.qpid.client.protocol.AMQProtocolHandler; import org.apache.qpid.client.message.MessageFactoryRegistry; import org.apache.qpid.client.message.FiledTableSupport; +import org.apache.qpid.client.message.AMQMessageDelegateFactory; import org.apache.qpid.util.Serial; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.nclient.util.MessagePartListenerAdapter; -import org.apache.qpidity.ErrorCode; -import org.apache.qpidity.QpidException; -import org.apache.qpidity.transport.MessageCreditUnit; -import org.apache.qpidity.transport.MessageFlowMode; -import org.apache.qpidity.transport.RangeSet; -import org.apache.qpidity.transport.Option; -import org.apache.qpidity.transport.ExchangeBoundResult; -import org.apache.qpidity.transport.Future; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.nclient.util.MessagePartListenerAdapter; +import org.apache.qpid.ErrorCode; +import org.apache.qpid.QpidException; +import org.apache.qpid.transport.MessageCreditUnit; +import org.apache.qpid.transport.MessageFlowMode; +import org.apache.qpid.transport.RangeSet; +import org.apache.qpid.transport.Option; +import org.apache.qpid.transport.ExchangeBoundResult; +import org.apache.qpid.transport.Future; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,7 +52,7 @@ import java.util.Map; /** * This is a 0.10 Session */ -public class AMQSession_0_10 extends AMQSession +public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, BasicMessageProducer_0_10> { /** @@ -71,8 +72,11 @@ public class AMQSession_0_10 extends AMQSession private Object _currentExceptionLock = new Object(); private QpidException _currentException; - // a ref on the qpidity connection - protected org.apache.qpidity.nclient.Connection _qpidConnection; + // a ref on the qpid connection + protected org.apache.qpid.nclient.Connection _qpidConnection; + + private RangeSet unacked = new RangeSet(); + private int unackedCount = 0; /** * USed to store the range of in tx messages @@ -93,7 +97,7 @@ public class AMQSession_0_10 extends AMQSession * @param defaultPrefetchLowMark The number of prefetched messages at which to resume the session. * @param qpidConnection The qpid connection */ - AMQSession_0_10(org.apache.qpidity.nclient.Connection qpidConnection, AMQConnection con, int channelId, + AMQSession_0_10(org.apache.qpid.nclient.Connection qpidConnection, AMQConnection con, int channelId, boolean transacted, int acknowledgeMode, MessageFactoryRegistry messageFactoryRegistry, int defaultPrefetchHighMark, int defaultPrefetchLowMark) { @@ -123,7 +127,7 @@ public class AMQSession_0_10 extends AMQSession * @param defaultPrefetchLow The number of prefetched messages at which to resume the session. * @param qpidConnection The connection */ - AMQSession_0_10(org.apache.qpidity.nclient.Connection qpidConnection, AMQConnection con, int channelId, + AMQSession_0_10(org.apache.qpid.nclient.Connection qpidConnection, AMQConnection con, int channelId, boolean transacted, int acknowledgeMode, int defaultPrefetchHigh, int defaultPrefetchLow) { @@ -131,6 +135,18 @@ public class AMQSession_0_10 extends AMQSession defaultPrefetchHigh, defaultPrefetchLow); } + private void addUnacked(int id) + { + unacked.add(id); + unackedCount++; + } + + private void clearUnacked() + { + unacked.clear(); + unackedCount = 0; + } + //------- overwritten methods of class AMQSession /** @@ -140,6 +156,7 @@ public class AMQSession_0_10 extends AMQSession * @param multiple <tt>true</tt> to acknowledge all messages up to and including the one specified by the * delivery tag, <tt>false</tt> to just acknowledge that message. */ + public void acknowledgeMessage(long deliveryTag, boolean multiple) { if (_logger.isDebugEnabled()) @@ -147,14 +164,13 @@ public class AMQSession_0_10 extends AMQSession _logger.debug("Sending ack for delivery tag " + deliveryTag + " on session " + _channelId); } // acknowledge this message - RangeSet ranges = new RangeSet(); if (multiple) { for (Long messageTag : _unacknowledgedMessageTags) { if( messageTag <= deliveryTag ) { - ranges.add((int) (long) messageTag); + addUnacked(messageTag.intValue()); _unacknowledgedMessageTags.remove(messageTag); } } @@ -163,10 +179,26 @@ public class AMQSession_0_10 extends AMQSession } else { - ranges.add((int) deliveryTag); + addUnacked((int) deliveryTag); _unacknowledgedMessageTags.remove(deliveryTag); } - getQpidSession().messageAcknowledge(ranges, _acknowledgeMode != org.apache.qpid.jms.Session.NO_ACKNOWLEDGE); + + long prefetch = getAMQConnection().getMaxPrefetch(); + + if (unackedCount >= prefetch/2) + { + flushAcknowledgments(); + } + } + + void flushAcknowledgments() + { + if (unackedCount > 0) + { + getQpidSession().messageAcknowledge + (unacked, _acknowledgeMode != org.apache.qpid.jms.Session.NO_ACKNOWLEDGE); + clearUnacked(); + } } /** @@ -210,6 +242,7 @@ public class AMQSession_0_10 extends AMQSession */ public void sendClose(long timeout) throws AMQException, FailoverException { + flushAcknowledgments(); getQpidSession().sync(); getQpidSession().close(); getCurrentException(); @@ -243,15 +276,16 @@ public class AMQSession_0_10 extends AMQSession * @param durable If set when creating a new queue, * the queue will be marked as durable. * @param exclusive Exclusive queues can only be used from one connection at a time. + * @param arguments Exclusive queues can only be used from one connection at a time. * @throws AMQException * @throws FailoverException */ public void sendCreateQueue(AMQShortString name, final boolean autoDelete, final boolean durable, - final boolean exclusive) throws AMQException, FailoverException + final boolean exclusive, Map<String, Object> arguments) throws AMQException, FailoverException { - getQpidSession().queueDeclare(name.toString(), null, null, durable ? Option.DURABLE : Option.NO_OPTION, - autoDelete ? Option.AUTO_DELETE : Option.NO_OPTION, - exclusive ? Option.EXCLUSIVE : Option.NO_OPTION); + getQpidSession().queueDeclare(name.toString(), null, arguments, durable ? Option.DURABLE : Option.NONE, + autoDelete ? Option.AUTO_DELETE : Option.NONE, + exclusive ? Option.EXCLUSIVE : Option.NONE); // We need to sync so that we get notify of an error. getQpidSession().sync(); getCurrentException(); @@ -311,7 +345,7 @@ public class AMQSession_0_10 extends AMQSession /** * Create an 0_10 message consumer */ - public BasicMessageConsumer createMessageConsumer(final AMQDestination destination, final int prefetchHigh, + public BasicMessageConsumer_0_10 createMessageConsumer(final AMQDestination destination, final int prefetchHigh, final int prefetchLow, final boolean noLocal, final boolean exclusive, String messageSelector, final FieldTable ft, final boolean noConsume, @@ -372,8 +406,8 @@ public class AMQSession_0_10 extends AMQSession * This method is invoked when a consumer is creted * Registers the consumer with the broker */ - public void sendConsume(BasicMessageConsumer consumer, AMQShortString queueName, AMQProtocolHandler protocolHandler, - boolean nowait, String messageSelector, AMQShortString tag) + public void sendConsume(BasicMessageConsumer_0_10 consumer, AMQShortString queueName, AMQProtocolHandler protocolHandler, + boolean nowait, String messageSelector, int tag) throws AMQException, FailoverException { boolean preAcquire; @@ -382,32 +416,34 @@ public class AMQSession_0_10 extends AMQSession preAcquire = ( ! consumer.isNoConsume() && (consumer.getMessageSelector() == null || consumer.getMessageSelector().equals("")) ) || !(consumer.getDestination() instanceof AMQQueue); - getQpidSession().messageSubscribe(queueName.toString(), tag.toString(), + getQpidSession().messageSubscribe(queueName.toString(), String.valueOf(tag), getAcknowledgeMode() == NO_ACKNOWLEDGE ? Session.TRANSFER_CONFIRM_MODE_NOT_REQUIRED:Session.TRANSFER_CONFIRM_MODE_REQUIRED, preAcquire ? Session.TRANSFER_ACQUIRE_MODE_PRE_ACQUIRE : Session.TRANSFER_ACQUIRE_MODE_NO_ACQUIRE, - new MessagePartListenerAdapter((BasicMessageConsumer_0_10) consumer), null, - consumer.isExclusive() ? Option.EXCLUSIVE : Option.NO_OPTION); + (BasicMessageConsumer_0_10) consumer, null, + consumer.isExclusive() ? Option.EXCLUSIVE : Option.NONE); } catch (JMSException e) { throw new AMQException(AMQConstant.INTERNAL_ERROR, "problem when registering consumer", e); } + String consumerTag = ((BasicMessageConsumer_0_10)consumer).getConsumerTagString(); + if (! prefetch()) { - getQpidSession().messageSetFlowMode(consumer.getConsumerTag().toString(), MessageFlowMode.CREDIT); + getQpidSession().messageSetFlowMode(consumerTag, MessageFlowMode.CREDIT); } else { - getQpidSession().messageSetFlowMode(consumer.getConsumerTag().toString(), MessageFlowMode.WINDOW); + getQpidSession().messageSetFlowMode(consumerTag, MessageFlowMode.WINDOW); } - getQpidSession().messageFlow(consumer.getConsumerTag().toString(), MessageCreditUnit.BYTE, 0xFFFFFFFF); + getQpidSession().messageFlow(consumerTag, MessageCreditUnit.BYTE, 0xFFFFFFFF); // We need to sync so that we get notify of an error. // only if not immediat prefetch if(prefetch() && (consumer.isStrated() || _immediatePrefetch)) { // set the flow - getQpidSession().messageFlow(consumer.getConsumerTag().toString(), + getQpidSession().messageFlow(consumerTag, MessageCreditUnit.MESSAGE, getAMQConnection().getMaxPrefetch()); } @@ -418,7 +454,7 @@ public class AMQSession_0_10 extends AMQSession /** * Create an 0_10 message producer */ - public BasicMessageProducer createMessageProducer(final Destination destination, final boolean mandatory, + public BasicMessageProducer_0_10 createMessageProducer(final Destination destination, final boolean mandatory, final boolean immediate, final boolean waitUntilSent, long producerId) { @@ -476,9 +512,9 @@ public class AMQSession_0_10 extends AMQSession arguments.put("no-local", true); } getQpidSession().queueDeclare(res.toString(), null, arguments, - amqd.isAutoDelete() ? Option.AUTO_DELETE : Option.NO_OPTION, - amqd.isDurable() ? Option.DURABLE : Option.NO_OPTION, - !amqd.isDurable() && amqd.isExclusive() ? Option.EXCLUSIVE : Option.NO_OPTION); + amqd.isAutoDelete() ? Option.AUTO_DELETE : Option.NONE, + amqd.isDurable() ? Option.DURABLE : Option.NONE, + !amqd.isDurable() && amqd.isExclusive() ? Option.EXCLUSIVE : Option.NONE); // passive --> false // We need to sync so that we get notify of an error. getQpidSession().sync(); @@ -508,13 +544,14 @@ public class AMQSession_0_10 extends AMQSession { for (BasicMessageConsumer consumer : _consumers.values()) { - getQpidSession().messageStop(consumer.getConsumerTag().toString()); + getQpidSession().messageStop(String.valueOf(consumer.getConsumerTag())); } } else { - for (BasicMessageConsumer consumer : _consumers.values()) + for (BasicMessageConsumer_0_10 consumer : _consumers.values()) { + String consumerTag = String.valueOf(consumer.getConsumerTag()); //only set if msg list is null try { @@ -522,18 +559,18 @@ public class AMQSession_0_10 extends AMQSession { if (consumer.getMessageListener() != null) { - getQpidSession().messageFlow(consumer.getConsumerTag().toString(), + getQpidSession().messageFlow(consumerTag, MessageCreditUnit.MESSAGE, 1); } } else { getQpidSession() - .messageFlow(consumer.getConsumerTag().toString(), MessageCreditUnit.MESSAGE, + .messageFlow(consumerTag, MessageCreditUnit.MESSAGE, getAMQConnection().getMaxPrefetch()); } getQpidSession() - .messageFlow(consumer.getConsumerTag().toString(), MessageCreditUnit.BYTE, 0xFFFFFFFF); + .messageFlow(consumerTag, MessageCreditUnit.BYTE, 0xFFFFFFFF); } catch (Exception e) { @@ -561,7 +598,7 @@ public class AMQSession_0_10 extends AMQSession * * @return The associated Qpid Session. */ - protected org.apache.qpidity.nclient.Session getQpidSession() + protected org.apache.qpid.nclient.Session getQpidSession() { return _qpidSession; } @@ -594,7 +631,7 @@ public class AMQSession_0_10 extends AMQSession try { // this is done so that we can produce to a temporary queue beofre we create a consumer - sendCreateQueue(result.getRoutingKey(), result.isAutoDelete(), result.isDurable(), result.isExclusive()); + sendCreateQueue(result.getRoutingKey(), result.isAutoDelete(), result.isDurable(), result.isExclusive(),null); sendQueueBind(result.getRoutingKey(), result.getRoutingKey(), new FieldTable(), result.getExchangeName(),result); result.setQueueName(result.getRoutingKey()); } @@ -612,7 +649,7 @@ public class AMQSession_0_10 extends AMQSession /** * Lstener for qpid protocol exceptions */ - private class QpidSessionExceptionListener implements org.apache.qpidity.nclient.ClosedListener + private class QpidSessionExceptionListener implements org.apache.qpid.nclient.ClosedListener { public void onClosed(ErrorCode errorCode, String reason, Throwable t) { @@ -681,7 +718,7 @@ public class AMQSession_0_10 extends AMQSession AMQTopic origTopic=checkValidTopic(topic); AMQTopic dest=AMQTopic.createDurable010Topic(origTopic, name, _connection); - TopicSubscriberAdaptor subscriber=_subscriptions.get(name); + TopicSubscriberAdaptor<BasicMessageConsumer_0_10> subscriber=_subscriptions.get(name); if (subscriber != null) { if (subscriber.getTopic().equals(topic)) @@ -732,7 +769,7 @@ public class AMQSession_0_10 extends AMQSession } } - subscriber=new TopicSubscriberAdaptor(dest, (BasicMessageConsumer) createExclusiveConsumer(dest)); + subscriber=new TopicSubscriberAdaptor(dest, createExclusiveConsumer(dest)); _subscriptions.put(name, subscriber); _reverseSubscriptionMap.put(subscriber.getMessageConsumer(), name); @@ -740,7 +777,7 @@ public class AMQSession_0_10 extends AMQSession return subscriber; } - Long requestQueueDepth(AMQDestination amqd) + protected Long requestQueueDepth(AMQDestination amqd) { return getQpidSession().queueQuery(amqd.getQueueName()).get().getMessageCount(); } @@ -757,10 +794,11 @@ public class AMQSession_0_10 extends AMQSession _txRangeSet.add((int) id); _txSize++; // this is a heuristic, we may want to have that configurable - if( _txSize > _connection.getMaxPrefetch() / 2 ) + if (_connection.getMaxPrefetch() == 1 || + _connection.getMaxPrefetch() != 0 && _txSize % (_connection.getMaxPrefetch() / 2) == 0) { - // send completed so consumer credits don't dry up - getQpidSession().messageAcknowledge(_txRangeSet, false); + // send completed so consumer credits don't dry up + getQpidSession().messageAcknowledge(_txRangeSet, false); } } @@ -787,14 +825,19 @@ public class AMQSession_0_10 extends AMQSession } } - final boolean tagLE(long tag1, long tag2) + protected final boolean tagLE(long tag1, long tag2) { return Serial.le((int) tag1, (int) tag2); } - final boolean updateRollbackMark(long currentMark, long deliveryTag) + protected final boolean updateRollbackMark(long currentMark, long deliveryTag) { return Serial.lt((int) currentMark, (int) deliveryTag); } + public AMQMessageDelegateFactory getMessageDelegateFactory() + { + return AMQMessageDelegateFactory.FACTORY_0_10; + } + } diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java b/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java index 00aa8e4d31..2442b157f1 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java @@ -25,10 +25,12 @@ import javax.jms.*; import javax.jms.IllegalStateException; import org.apache.qpid.AMQException; +import org.apache.qpid.AMQUndeliveredException; import org.apache.qpid.client.failover.FailoverException; import org.apache.qpid.client.failover.FailoverProtectedOperation; import org.apache.qpid.client.failover.FailoverRetrySupport; -import org.apache.qpid.client.message.MessageFactoryRegistry; +import org.apache.qpid.client.message.*; +import org.apache.qpid.client.message.AMQMessageDelegateFactory; import org.apache.qpid.client.protocol.AMQProtocolHandler; import org.apache.qpid.client.state.listener.SpecificMethodFrameListener; import org.apache.qpid.common.AMQPFilterTypes; @@ -40,7 +42,9 @@ import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public final class AMQSession_0_8 extends AMQSession +import java.util.Map; + +public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, BasicMessageProducer_0_8> { /** Used for debugging. */ @@ -125,10 +129,19 @@ public final class AMQSession_0_8 extends AMQSession handler.syncWrite(getProtocolHandler().getMethodRegistry().createTxCommitBody().generateFrame(_channelId), TxCommitOkBody.class); } - public void sendCreateQueue(AMQShortString name, final boolean autoDelete, final boolean durable, final boolean exclusive) throws AMQException, + public void sendCreateQueue(AMQShortString name, final boolean autoDelete, final boolean durable, final boolean exclusive, final Map<String, Object> arguments) throws AMQException, FailoverException { - QueueDeclareBody body = getMethodRegistry().createQueueDeclareBody(getTicket(),name,false,durable,exclusive,autoDelete,false,null); + FieldTable table = null; + if(arguments != null && !arguments.isEmpty()) + { + table = new FieldTable(); + for(Map.Entry<String, Object> entry : arguments.entrySet()) + { + table.setObject(entry.getKey(), entry.getValue()); + } + } + QueueDeclareBody body = getMethodRegistry().createQueueDeclareBody(getTicket(),name,false,durable,exclusive,autoDelete,false,table); AMQFrame queueDeclare = body.generateFrame(_channelId); getProtocolHandler().syncWrite(queueDeclare, QueueDeclareOkBody.class); } @@ -206,6 +219,7 @@ public final class AMQSession_0_8 extends AMQSession return isQueueBound(destination.getExchangeName(),destination.getAMQQueueName(),destination.getAMQQueueName()); } + public boolean isQueueBound(final AMQShortString exchangeName, final AMQShortString queueName, final AMQShortString routingKey) throws JMSException { @@ -233,10 +247,14 @@ public final class AMQSession_0_8 extends AMQSession { throw new JMSAMQException("Queue bound query failed: " + e.getMessage(), e); } - } - - public void sendConsume(BasicMessageConsumer consumer, AMQShortString queueName, AMQProtocolHandler protocolHandler, boolean nowait, - String messageSelector, AMQShortString tag) throws AMQException, FailoverException + } + + @Override public void sendConsume(BasicMessageConsumer_0_8 consumer, + AMQShortString queueName, + AMQProtocolHandler protocolHandler, + boolean nowait, + String messageSelector, + int tag) throws AMQException, FailoverException { FieldTable arguments = FieldTableFactory.newFieldTable(); if ((messageSelector != null) && !messageSelector.equals("")) @@ -256,7 +274,7 @@ public final class AMQSession_0_8 extends AMQSession BasicConsumeBody body = getMethodRegistry().createBasicConsumeBody(getTicket(), queueName, - tag, + new AMQShortString(String.valueOf(tag)), consumer.isNoLocal(), consumer.getAcknowledgeMode() == Session.NO_ACKNOWLEDGE, consumer.isExclusive(), @@ -314,18 +332,18 @@ public final class AMQSession_0_8 extends AMQSession } public BasicMessageConsumer_0_8 createMessageConsumer(final AMQDestination destination, final int prefetchHigh, - final int prefetchLow, final boolean noLocal, final boolean exclusive, String messageSelector, final FieldTable ft, + final int prefetchLow, final boolean noLocal, final boolean exclusive, String messageSelector, final FieldTable arguments, final boolean noConsume, final boolean autoClose) throws JMSException { final AMQProtocolHandler protocolHandler = getProtocolHandler(); return new BasicMessageConsumer_0_8(_channelId, _connection, destination, messageSelector, noLocal, - _messageFactoryRegistry,this, protocolHandler, ft, prefetchHigh, prefetchLow, + _messageFactoryRegistry,this, protocolHandler, arguments, prefetchHigh, prefetchLow, exclusive, _acknowledgeMode, noConsume, autoClose); } - public BasicMessageProducer createMessageProducer(final Destination destination, final boolean mandatory, + public BasicMessageProducer_0_8 createMessageProducer(final Destination destination, final boolean mandatory, final boolean immediate, final boolean waitUntilSent, long producerId) { @@ -333,6 +351,66 @@ public final class AMQSession_0_8 extends AMQSession this, getProtocolHandler(), producerId, immediate, mandatory, waitUntilSent); } + + @Override public void messageReceived(UnprocessedMessage message) + { + + if (message instanceof ReturnMessage) + { + // Return of the bounced message. + returnBouncedMessage((ReturnMessage) message); + } + else + { + super.messageReceived(message); + } + } + + private void returnBouncedMessage(final ReturnMessage msg) + { + _connection.performConnectionTask(new Runnable() + { + public void run() + { + try + { + // Bounced message is processed here, away from the mina thread + AbstractJMSMessage bouncedMessage = + _messageFactoryRegistry.createMessage(0, false, msg.getExchange(), + msg.getRoutingKey(), msg.getContentHeader(), msg.getBodies()); + AMQConstant errorCode = AMQConstant.getConstant(msg.getReplyCode()); + AMQShortString reason = msg.getReplyText(); + _logger.debug("Message returned with error code " + errorCode + " (" + reason + ")"); + + // @TODO should this be moved to an exception handler of sorts. Somewhere errors are converted to correct execeptions. + if (errorCode == AMQConstant.NO_CONSUMERS) + { + _connection.exceptionReceived(new AMQNoConsumersException("Error: " + reason, bouncedMessage, null)); + } + else if (errorCode == AMQConstant.NO_ROUTE) + { + _connection.exceptionReceived(new AMQNoRouteException("Error: " + reason, bouncedMessage, null)); + } + else + { + _connection.exceptionReceived( + new AMQUndeliveredException(errorCode, "Error: " + reason, bouncedMessage, null)); + } + + } + catch (Exception e) + { + _logger.error( + "Caught exception trying to raise undelivered message exception (dump follows) - ignoring...", + e); + } + } + }); + } + + + + public void sendRollback() throws AMQException, FailoverException { TxRollbackBody body = getMethodRegistry().createTxRollbackBody(); @@ -353,7 +431,7 @@ public final class AMQSession_0_8 extends AMQSession checkNotClosed(); AMQTopic origTopic = checkValidTopic(topic); AMQTopic dest = AMQTopic.createDurableTopic(origTopic, name, _connection); - TopicSubscriberAdaptor subscriber = _subscriptions.get(name); + TopicSubscriberAdaptor<BasicMessageConsumer_0_8> subscriber = _subscriptions.get(name); if (subscriber != null) { if (subscriber.getTopic().equals(topic)) @@ -412,6 +490,28 @@ public final class AMQSession_0_8 extends AMQSession return subscriber; } + + + + public void setPrefecthLimits(final int messagePrefetch, final long sizePrefetch) throws AMQException + { + new FailoverRetrySupport<Object, AMQException>( + new FailoverProtectedOperation<Object, AMQException>() + { + public Object execute() throws AMQException, FailoverException + { + + BasicQosBody basicQosBody = getProtocolHandler().getMethodRegistry().createBasicQosBody(sizePrefetch, messagePrefetch, false); + + // todo send low water mark when protocol allows. + // todo Be aware of possible changes to parameter order as versions change. + getProtocolHandler().syncWrite(basicQosBody.generateFrame(getChannelId()), BasicQosOkBody.class); + + return null; + } + }, _connection).execute(); + } + class QueueDeclareOkHandler extends SpecificMethodFrameListener { @@ -437,7 +537,7 @@ public final class AMQSession_0_8 extends AMQSession } - Long requestQueueDepth(AMQDestination amqd) throws AMQException, FailoverException + protected Long requestQueueDepth(AMQDestination amqd) throws AMQException, FailoverException { AMQFrame queueDeclare = getMethodRegistry().createQueueDeclareBody(getTicket(), @@ -449,18 +549,23 @@ public final class AMQSession_0_8 extends AMQSession false, null).generateFrame(_channelId); QueueDeclareOkHandler okHandler = new QueueDeclareOkHandler(); - getProtocolHandler().writeCommandFrameAndWaitForReply(queueDeclare, okHandler); + getProtocolHandler().writeCommandFrameAndWaitForReply(queueDeclare, okHandler); return okHandler._messageCount; } - final boolean tagLE(long tag1, long tag2) + protected final boolean tagLE(long tag1, long tag2) { return tag1 <= tag2; } - final boolean updateRollbackMark(long currentMark, long deliveryTag) + protected final boolean updateRollbackMark(long currentMark, long deliveryTag) { return false; } + public AMQMessageDelegateFactory getMessageDelegateFactory() + { + return AMQMessageDelegateFactory.FACTORY_0_8; + } + } diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java index 8288581538..01bb68c23e 100644 --- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java +++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java @@ -22,9 +22,7 @@ package org.apache.qpid.client; import org.apache.qpid.AMQException; import org.apache.qpid.client.failover.FailoverException; -import org.apache.qpid.client.message.AbstractJMSMessage; -import org.apache.qpid.client.message.MessageFactoryRegistry; -import org.apache.qpid.client.message.UnprocessedMessage; +import org.apache.qpid.client.message.*; import org.apache.qpid.client.protocol.AMQProtocolHandler; import org.apache.qpid.framing.*; import org.apache.qpid.jms.MessageConsumer; @@ -48,7 +46,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -public abstract class BasicMessageConsumer<H, B> extends Closeable implements MessageConsumer +public abstract class BasicMessageConsumer<U> extends Closeable implements MessageConsumer { private static final Logger _logger = LoggerFactory.getLogger(BasicMessageConsumer.class); @@ -71,7 +69,7 @@ public abstract class BasicMessageConsumer<H, B> extends Closeable implements Me private final AtomicReference<MessageListener> _messageListener = new AtomicReference<MessageListener>(); /** The consumer tag allows us to close the consumer by sending a jmsCancel method to the broker */ - protected AMQShortString _consumerTag; + protected int _consumerTag; /** We need to know the channel id when constructing frames */ protected final int _channelId; @@ -91,7 +89,7 @@ public abstract class BasicMessageConsumer<H, B> extends Closeable implements Me /** * We need to store the "raw" field table so that we can resubscribe in the event of failover being required */ - private final FieldTable _rawSelectorFieldTable; + private final FieldTable _arguments; /** * We store the high water prefetch field in order to be able to reuse it when resubscribing in the event of @@ -168,7 +166,7 @@ public abstract class BasicMessageConsumer<H, B> extends Closeable implements Me protected BasicMessageConsumer(int channelId, AMQConnection connection, AMQDestination destination, String messageSelector, boolean noLocal, MessageFactoryRegistry messageFactory, AMQSession session, AMQProtocolHandler protocolHandler, - FieldTable rawSelectorFieldTable, int prefetchHigh, int prefetchLow, + FieldTable arguments, int prefetchHigh, int prefetchLow, boolean exclusive, int acknowledgeMode, boolean noConsume, boolean autoClose) { _channelId = channelId; @@ -179,7 +177,7 @@ public abstract class BasicMessageConsumer<H, B> extends Closeable implements Me _messageFactory = messageFactory; _session = session; _protocolHandler = protocolHandler; - _rawSelectorFieldTable = rawSelectorFieldTable; + _arguments = arguments; _prefetchHigh = prefetchHigh; _prefetchLow = prefetchLow; _exclusive = exclusive; @@ -277,6 +275,14 @@ public abstract class BasicMessageConsumer<H, B> extends Closeable implements Me _messageListener.set(messageListener); _session.setHasMessageListeners(); _session.startDispatcherIfNecessary(); + + // If we already have messages on the queue, deliver them to the listener + Object o = _synchronousQueue.poll(); + while (o != null) + { + messageListener.onMessage((Message) o); + o = _synchronousQueue.poll(); + } } } } @@ -335,9 +341,9 @@ public abstract class BasicMessageConsumer<H, B> extends Closeable implements Me _receivingThread = null; } - public FieldTable getRawSelectorFieldTable() + public FieldTable getArguments() { - return _rawSelectorFieldTable; + return _arguments; } public int getPrefetch() @@ -508,6 +514,12 @@ public abstract class BasicMessageConsumer<H, B> extends Closeable implements Me throw e; } + else if (o instanceof CloseConsumerMessage) + { + _closed.set(true); + deregisterConsumer(); + return null; + } else { return (AbstractJMSMessage) o; @@ -562,6 +574,7 @@ public abstract class BasicMessageConsumer<H, B> extends Closeable implements Me } else { + // FIXME: wow this is ugly // //fixme this probably is not right // if (!isNoConsume()) { // done in BasicCancelOK Handler but not sending one so just deregister. @@ -606,7 +619,8 @@ public abstract class BasicMessageConsumer<H, B> extends Closeable implements Me } else { - _closedStack = Arrays.asList(Thread.currentThread().getStackTrace()).subList(3, 8); + StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); + _closedStack = Arrays.asList(stackTrace).subList(3, stackTrace.length - 1); } } } @@ -615,25 +629,56 @@ public abstract class BasicMessageConsumer<H, B> extends Closeable implements Me } /** + * @param closeMessage + * this message signals that we should close the browser + */ + public void notifyCloseMessage(CloseConsumerMessage closeMessage) + { + if (isMessageListenerSet()) + { + // Currently only possible to get this msg type with a browser. + // If we get the message here then we should probably just close + // this consumer. + // Though an AutoClose consumer with message listener is quite odd.. + // Just log out the fact so we know where we are + _logger.warn("Using an AutoCloseconsumer with message listener is not supported."); + } + else + { + try + { + _synchronousQueue.put(closeMessage); + } + catch (InterruptedException e) + { + _logger.info(" SynchronousQueue.put interupted. Usually result of connection closing," + + "but we shouldn't have close yet"); + } + } + } + + + /** * Called from the AMQSession when a message has arrived for this consumer. This methods handles both the case of a * message listener or a synchronous receive() caller. * * @param messageFrame the raw unprocessed mesage */ - void notifyMessage(UnprocessedMessage messageFrame) + void notifyMessage(U messageFrame) { - final boolean debug = _logger.isDebugEnabled(); - - if (debug) + if (messageFrame instanceof CloseConsumerMessage) { - _logger.debug("notifyMessage called with message number " + messageFrame.getDeliveryTag()); + notifyCloseMessage((CloseConsumerMessage) messageFrame); + return; } + + try { - AbstractJMSMessage jmsMessage = createJMSMessageFromUnprocessedMessage(messageFrame); + AbstractJMSMessage jmsMessage = createJMSMessageFromUnprocessedMessage(_session.getMessageDelegateFactory(), messageFrame); - if (debug) + if (_logger.isDebugEnabled()) { _logger.debug("Message is of type: " + jmsMessage.getClass().getName()); } @@ -668,7 +713,7 @@ public abstract class BasicMessageConsumer<H, B> extends Closeable implements Me } } - public abstract AbstractJMSMessage createJMSMessageFromUnprocessedMessage(UnprocessedMessage<H, B> messageFrame) + public abstract AbstractJMSMessage createJMSMessageFromUnprocessedMessage(AMQMessageDelegateFactory delegateFactory, U messageFrame) throws Exception; /** @param jmsMessage this message has already been processed so can't redo preDeliver */ @@ -678,18 +723,9 @@ public abstract class BasicMessageConsumer<H, B> extends Closeable implements Me { if (isMessageListenerSet()) { - // we do not need a lock around the test above, and the dispatch below as it is invalid - // for an application to alter an installed listener while the session is started - // synchronized (_closed) - { - // if (!_closed.get()) - { - - preApplicationProcessing(jmsMessage); - getMessageListener().onMessage(jmsMessage); - postDeliver(jmsMessage); - } - } + preApplicationProcessing(jmsMessage); + getMessageListener().onMessage(jmsMessage); + postDeliver(jmsMessage); } else { @@ -750,7 +786,7 @@ public abstract class BasicMessageConsumer<H, B> extends Closeable implements Me { _session.acknowledgeMessage(msg.getDeliveryTag(), false); } - + _session.markDirty(); break; case Session.DUPS_OK_ACKNOWLEDGE: @@ -892,12 +928,12 @@ public abstract class BasicMessageConsumer<H, B> extends Closeable implements Me _session.deregisterConsumer(this); } - public AMQShortString getConsumerTag() + public int getConsumerTag() { return _consumerTag; } - public void setConsumerTag(AMQShortString consumerTag) + public void setConsumerTag(int consumerTag) { _consumerTag = consumerTag; } diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java index 9230225bd5..2a37298a43 100644 --- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java +++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java @@ -22,31 +22,24 @@ import org.slf4j.LoggerFactory; import org.apache.qpid.client.message.*; import org.apache.qpid.client.protocol.AMQProtocolHandler; import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.AMQException; -import org.apache.qpid.jms.*; -import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.transport.*; -import org.apache.qpidity.transport.Session; -import org.apache.qpidity.QpidException; -import org.apache.qpidity.filter.MessageFilter; -import org.apache.qpidity.filter.JMSSelectorFilter; +import org.apache.qpid.transport.*; +import org.apache.qpid.QpidException; +import org.apache.qpid.filter.MessageFilter; +import org.apache.qpid.filter.JMSSelectorFilter; import javax.jms.InvalidSelectorException; import javax.jms.JMSException; import javax.jms.MessageListener; -import java.io.IOException; -import java.nio.ByteBuffer; import java.util.Iterator; import java.util.concurrent.atomic.AtomicBoolean; /** * This is a 0.10 message consumer. */ -public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<Struct[], ByteBuffer> - implements org.apache.qpidity.nclient.util.MessageListener +public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedMessage_0_10> + implements org.apache.qpid.nclient.MessagePartListener { /** @@ -78,17 +71,18 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<Struct[], By * Specify whether this consumer is performing a sync receive */ private final AtomicBoolean _syncReceive = new AtomicBoolean(false); + private String _consumerTagString; //--- constructor protected BasicMessageConsumer_0_10(int channelId, AMQConnection connection, AMQDestination destination, String messageSelector, boolean noLocal, MessageFactoryRegistry messageFactory, AMQSession session, AMQProtocolHandler protocolHandler, - FieldTable rawSelectorFieldTable, int prefetchHigh, int prefetchLow, + FieldTable arguments, int prefetchHigh, int prefetchLow, boolean exclusive, int acknowledgeMode, boolean noConsume, boolean autoClose) throws JMSException { super(channelId, connection, destination, messageSelector, noLocal, messageFactory, session, protocolHandler, - rawSelectorFieldTable, prefetchHigh, prefetchLow, exclusive, acknowledgeMode, noConsume, autoClose); + arguments, prefetchHigh, prefetchLow, exclusive, acknowledgeMode, noConsume, autoClose); _0_10session = (AMQSession_0_10) session; if (messageSelector != null && !messageSelector.equals("")) { @@ -108,7 +102,20 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<Struct[], By _isStarted = connection.started(); } - // ----- Interface org.apache.qpidity.client.util.MessageListener + + @Override public void setConsumerTag(int consumerTag) + { + super.setConsumerTag(consumerTag); + _consumerTagString = String.valueOf(consumerTag); + } + + public String getConsumerTagString() + { + return _consumerTagString; + } + + + // ----- Interface org.apache.qpid.client.util.MessageListener /** * @@ -144,7 +151,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<Struct[], By { if (isMessageListenerSet() && ! getSession().prefetch()) { - _0_10session.getQpidSession().messageFlow(getConsumerTag().toString(), + _0_10session.getQpidSession().messageFlow(getConsumerTagString(), MessageCreditUnit.MESSAGE, 1); } _logger.debug("messageOk, trying to notify"); @@ -157,52 +164,19 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<Struct[], By /** * This method is invoked by the transport layer when a message is delivered for this * consumer. The message is transformed and pass to the session. - * @param message an 0.10 message + * @param xfr an 0.10 message transfer */ - public void onMessage(Message message) + public void messageTransfer(MessageTransfer xfr) + + //public void onMessage(Message message) { int channelId = getSession().getChannelId(); - long deliveryId = message.getMessageTransferId(); - AMQShortString consumerTag = getConsumerTag(); - AMQShortString exchange; - AMQShortString routingKey; - boolean redelivered = false; - Struct[] headers = {message.getMessageProperties(), message.getDeliveryProperties()}; - if (headers[0] == null) { - headers[0] = new MessageProperties(); - } - if( message.getDeliveryProperties() != null ) - { - exchange = new AMQShortString(message.getDeliveryProperties().getExchange()); - routingKey = new AMQShortString(message.getDeliveryProperties().getRoutingKey()); - redelivered = message.getDeliveryProperties().getRedelivered(); - } - else - { - exchange = new AMQShortString(""); - routingKey = new AMQShortString(""); - headers[1] = new DeliveryProperties(); - } + int consumerTag = getConsumerTag(); + UnprocessedMessage_0_10 newMessage = - new UnprocessedMessage_0_10(channelId, deliveryId, consumerTag, exchange, routingKey, redelivered); - try - { - newMessage.receiveBody(message.readData()); - } - catch (IOException e) - { - getSession().getAMQConnection().exceptionReceived(e); - } - // if there is a replyto destination then we need to request the exchange info - ReplyTo replyTo = ((MessageProperties) headers[0]).getReplyTo(); - if (replyTo != null && replyTo.getExchange() != null && !replyTo.getExchange().equals("")) - { - // <exch_class>://<exch_name>/[<destination>]/[<queue>]?<option>='<value>'[,<option>='<value>']* - // the exchnage class will be set later from within the sesion thread - String replyToUrl = replyTo.getExchange() + "/" + replyTo.getRoutingKey() + "/" + replyTo.getRoutingKey(); - newMessage.setReplyToURL(replyToUrl); - } - newMessage.setContentHeader(headers); + new UnprocessedMessage_0_10(consumerTag, xfr); + + getSession().messageReceived(newMessage); // else ignore this message } @@ -215,47 +189,16 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<Struct[], By */ @Override void sendCancel() throws AMQException { - ((AMQSession_0_10) getSession()).getQpidSession().messageCancel(getConsumerTag().toString()); + ((AMQSession_0_10) getSession()).getQpidSession().messageCancel(getConsumerTagString()); ((AMQSession_0_10) getSession()).getQpidSession().sync(); // confirm cancel getSession().confirmConsumerCancelled(getConsumerTag()); ((AMQSession_0_10) getSession()).getCurrentException(); } - @Override void notifyMessage(UnprocessedMessage messageFrame) + @Override void notifyMessage(UnprocessedMessage_0_10 messageFrame) { - // if there is a replyto destination then we need to request the exchange info - String replyToURL = messageFrame.getReplyToURL(); - if (replyToURL != null && !replyToURL.equals("")) - { - AMQShortString shortExchangeName = new AMQShortString( replyToURL.substring(0, replyToURL.indexOf('/'))); - String replyToUrl = "://" + replyToURL; - if (shortExchangeName.equals(ExchangeDefaults.TOPIC_EXCHANGE_NAME)) - { - replyToUrl = ExchangeDefaults.TOPIC_EXCHANGE_CLASS + replyToUrl; - } - else if (shortExchangeName.equals(ExchangeDefaults.DIRECT_EXCHANGE_NAME)) - { - replyToUrl = ExchangeDefaults.DIRECT_EXCHANGE_CLASS + replyToUrl; - } - else if (shortExchangeName.equals(ExchangeDefaults.HEADERS_EXCHANGE_NAME)) - { - replyToUrl = ExchangeDefaults.HEADERS_EXCHANGE_CLASS + replyToUrl; - } - else if (shortExchangeName.equals(ExchangeDefaults.FANOUT_EXCHANGE_NAME)) - { - replyToUrl = ExchangeDefaults.FANOUT_EXCHANGE_CLASS + replyToUrl; - } - else - { - Future<ExchangeQueryResult> future = - ((AMQSession_0_10) getSession()).getQpidSession().exchangeQuery(shortExchangeName.toString()); - ExchangeQueryResult res = future.get(); - // <exch_class>://<exch_name>/[<destination>]/[<queue>]?<option>='<value>'[,<option>='<value>']* - replyToUrl = res.getType() + replyToUrl; - } - ((UnprocessedMessage_0_10) messageFrame).setReplyToURL(replyToUrl); - } + super.notifyMessage(messageFrame); } @@ -269,12 +212,10 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<Struct[], By } @Override public AbstractJMSMessage createJMSMessageFromUnprocessedMessage( - UnprocessedMessage<Struct[], ByteBuffer> messageFrame) throws Exception + AMQMessageDelegateFactory delegateFactory, UnprocessedMessage_0_10 msg) throws Exception { - return _messageFactory.createMessage(messageFrame.getDeliveryTag(), messageFrame.isRedelivered(), - messageFrame.getExchange(), messageFrame.getRoutingKey(), - messageFrame.getContentHeader(), messageFrame.getBodies(), - messageFrame.getReplyToURL()); + AMQMessageDelegate_0_10.updateExchangeTypeMapping(msg.getMessageTransfer().getHeader(), ((AMQSession_0_10)getSession()).getQpidSession()); + return _messageFactory.createMessage(msg.getMessageTransfer()); } // private methods @@ -330,7 +271,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<Struct[], By // and messages are not prefetched we then need to request another one if(! getSession().prefetch()) { - _0_10session.getQpidSession().messageFlow(getConsumerTag().toString(), + _0_10session.getQpidSession().messageFlow(getConsumerTagString(), MessageCreditUnit.MESSAGE, 1); } } @@ -418,7 +359,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<Struct[], By super.setMessageListener(messageListener); if (messageListener != null && ! getSession().prefetch()) { - _0_10session.getQpidSession().messageFlow(getConsumerTag().toString(), + _0_10session.getQpidSession().messageFlow(getConsumerTagString(), MessageCreditUnit.MESSAGE, 1); } if (messageListener != null && !_synchronousQueue.isEmpty()) @@ -443,7 +384,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<Struct[], By _isStarted = true; if (_syncReceive.get()) { - _0_10session.getQpidSession().messageFlow(getConsumerTag().toString(), + _0_10session.getQpidSession().messageFlow(getConsumerTagString(), MessageCreditUnit.MESSAGE, 1); } } @@ -466,7 +407,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<Struct[], By { if (isStrated() && ! getSession().prefetch() && _synchronousQueue.isEmpty()) { - _0_10session.getQpidSession().messageFlow(getConsumerTag().toString(), + _0_10session.getQpidSession().messageFlow(getConsumerTagString(), MessageCreditUnit.MESSAGE, 1); } if (! getSession().prefetch()) @@ -489,4 +430,5 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<Struct[], By _session.acknowledgeMessage(msg.getDeliveryTag(), false); } } + } diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java index 5414e25539..494a8fb43d 100644 --- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java +++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java @@ -20,40 +20,48 @@ */ package org.apache.qpid.client; -import java.util.concurrent.TimeUnit; +import javax.jms.InvalidSelectorException; +import javax.jms.JMSException; import org.apache.qpid.AMQException; +import org.apache.qpid.QpidException; import org.apache.qpid.client.failover.FailoverException; -import org.apache.qpid.client.message.AbstractJMSMessage; -import org.apache.qpid.client.message.MessageFactoryRegistry; -import org.apache.qpid.client.message.UnprocessedMessage; +import org.apache.qpid.client.message.*; import org.apache.qpid.client.protocol.AMQProtocolHandler; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.BasicCancelBody; -import org.apache.qpid.framing.BasicCancelOkBody; -import org.apache.qpid.framing.ContentBody; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.filter.JMSSelectorFilter; +import org.apache.qpid.framing.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<ContentHeaderBody,ContentBody> +public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<UnprocessedMessage_0_8> { protected final Logger _logger = LoggerFactory.getLogger(getClass()); protected BasicMessageConsumer_0_8(int channelId, AMQConnection connection, AMQDestination destination, String messageSelector, boolean noLocal, MessageFactoryRegistry messageFactory, AMQSession session, - AMQProtocolHandler protocolHandler, FieldTable rawSelectorFieldTable, int prefetchHigh, int prefetchLow, - boolean exclusive, int acknowledgeMode, boolean noConsume, boolean autoClose) + AMQProtocolHandler protocolHandler, FieldTable arguments, int prefetchHigh, int prefetchLow, + boolean exclusive, int acknowledgeMode, boolean noConsume, boolean autoClose) throws JMSException { super(channelId, connection, destination,messageSelector,noLocal,messageFactory,session, - protocolHandler, rawSelectorFieldTable, prefetchHigh, prefetchLow, exclusive, + protocolHandler, arguments, prefetchHigh, prefetchLow, exclusive, acknowledgeMode, noConsume, autoClose); + try + { + + if (messageSelector != null && messageSelector.length() > 0) + { + JMSSelectorFilter _filter = new JMSSelectorFilter(messageSelector); + } + } + catch (QpidException e) + { + throw new InvalidSelectorException("cannot create consumer because of selector issue"); + } } void sendCancel() throws AMQException, FailoverException { - BasicCancelBody body = getSession().getMethodRegistry().createBasicCancelBody(_consumerTag, false); + BasicCancelBody body = getSession().getMethodRegistry().createBasicCancelBody(new AMQShortString(String.valueOf(_consumerTag)), false); final AMQFrame cancelFrame = body.generateFrame(_channelId); @@ -65,7 +73,7 @@ public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<ContentHeader } } - public AbstractJMSMessage createJMSMessageFromUnprocessedMessage(UnprocessedMessage<ContentHeaderBody, ContentBody> messageFrame)throws Exception + public AbstractJMSMessage createJMSMessageFromUnprocessedMessage(AMQMessageDelegateFactory delegateFactory, UnprocessedMessage_0_8 messageFrame)throws Exception { return _messageFactory.createMessage(messageFrame.getDeliveryTag(), @@ -74,4 +82,4 @@ public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<ContentHeader } -}
\ No newline at end of file +} diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java index 9d01fbfaa2..beaa47ed1e 100644 --- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java +++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java @@ -31,23 +31,16 @@ import javax.jms.JMSException; import javax.jms.MapMessage; import javax.jms.Message; import javax.jms.ObjectMessage; -import javax.jms.Queue; import javax.jms.StreamMessage; import javax.jms.TextMessage; -import javax.jms.Topic; -import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; import org.apache.qpid.client.message.AbstractJMSMessage; import org.apache.qpid.client.message.MessageConverter; import org.apache.qpid.client.protocol.AMQProtocolHandler; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.BasicPublishBody; -import org.apache.qpid.framing.CompositeAMQDataBlock; import org.apache.qpid.framing.ContentBody; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.ExchangeDeclareBody; +import org.apache.qpid.util.UUIDGen; +import org.apache.qpid.util.UUIDs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -122,6 +115,8 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac private boolean _disableMessageId; + private UUIDGen _messageIdGenerator = UUIDs.newGenerator(); + private static final ContentBody[] NO_CONTENT_BODIES = new ContentBody[0]; protected BasicMessageProducer(AMQConnection connection, AMQDestination destination, boolean transacted, int channelId, @@ -365,27 +360,27 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac if (message instanceof BytesMessage) { - newMessage = new MessageConverter((BytesMessage) message).getConvertedMessage(); + newMessage = new MessageConverter(_session, (BytesMessage) message).getConvertedMessage(); } else if (message instanceof MapMessage) { - newMessage = new MessageConverter((MapMessage) message).getConvertedMessage(); + newMessage = new MessageConverter(_session, (MapMessage) message).getConvertedMessage(); } else if (message instanceof ObjectMessage) { - newMessage = new MessageConverter((ObjectMessage) message).getConvertedMessage(); + newMessage = new MessageConverter(_session, (ObjectMessage) message).getConvertedMessage(); } else if (message instanceof TextMessage) { - newMessage = new MessageConverter((TextMessage) message).getConvertedMessage(); + newMessage = new MessageConverter(_session, (TextMessage) message).getConvertedMessage(); } else if (message instanceof StreamMessage) { - newMessage = new MessageConverter((StreamMessage) message).getConvertedMessage(); + newMessage = new MessageConverter(_session, (StreamMessage) message).getConvertedMessage(); } else { - newMessage = new MessageConverter(message).getConvertedMessage(); + newMessage = new MessageConverter(_session, message).getConvertedMessage(); } if (newMessage != null) @@ -453,19 +448,18 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac } } + UUID messageId = null; if (_disableMessageId) { - message.setJMSMessageID(null); + message.setJMSMessageID((UUID)null); } else { - StringBuilder b = new StringBuilder(39); - b.append("ID:"); - b.append(UUID.randomUUID()); - message.setJMSMessageID(b.toString()); + messageId = _messageIdGenerator.generate(); + message.setJMSMessageID(messageId); } - sendMessage(destination, origMessage, message, deliveryMode, priority, timeToLive, mandatory, immediate, wait); + sendMessage(destination, origMessage, message, messageId, deliveryMode, priority, timeToLive, mandatory, immediate, wait); if (message != origMessage) { @@ -484,8 +478,8 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac } abstract void sendMessage(AMQDestination destination, Message origMessage, AbstractJMSMessage message, - int deliveryMode, int priority, long timeToLive, boolean mandatory, - boolean immediate, boolean wait)throws JMSException; + UUID messageId, int deliveryMode, int priority, long timeToLive, boolean mandatory, + boolean immediate, boolean wait) throws JMSException; private void checkTemporaryDestination(AMQDestination destination) throws JMSException { diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java index 5eb066ec36..02c5526e03 100644 --- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java +++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java @@ -22,6 +22,7 @@ import java.net.URISyntaxException; import java.util.HashMap; import java.util.Map; import java.util.UUID; +import java.nio.ByteBuffer; import javax.jms.JMSException; import javax.jms.Message; @@ -29,17 +30,15 @@ import javax.jms.DeliveryMode; import org.apache.qpid.client.message.AbstractJMSMessage; import org.apache.qpid.client.message.FiledTableSupport; +import org.apache.qpid.client.message.AMQMessageDelegate_0_10; import org.apache.qpid.client.protocol.AMQProtocolHandler; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.BasicContentHeaderProperties; import org.apache.qpid.url.AMQBindingURL; -import org.apache.qpidity.nclient.util.ByteBufferMessage; -import org.apache.qpidity.njms.ExceptionHelper; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageDeliveryMode; -import org.apache.qpidity.transport.MessageDeliveryPriority; -import org.apache.qpidity.transport.MessageProperties; -import org.apache.qpidity.transport.ReplyTo; +import org.apache.qpid.nclient.util.ByteBufferMessage; +import org.apache.qpid.njms.ExceptionHelper; +import org.apache.qpid.transport.*; +import static org.apache.qpid.transport.Option.*; /** * This is a 0_10 message producer. @@ -68,23 +67,25 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer * Sends a message to a given destination */ void sendMessage(AMQDestination destination, Message origMessage, AbstractJMSMessage message, - int deliveryMode, int priority, long timeToLive, boolean mandatory, boolean immediate, - boolean wait) throws JMSException + UUID messageId, int deliveryMode, int priority, long timeToLive, boolean mandatory, + boolean immediate, boolean wait) throws JMSException { message.prepareForSending(); - if (message.get010Message() == null) + + AMQMessageDelegate_0_10 delegate = (AMQMessageDelegate_0_10) message.getDelegate(); + + DeliveryProperties deliveryProp = delegate.getDeliveryProperties(); + MessageProperties messageProps = delegate.getMessageProperties(); + + if (messageId != null) { - message.set010Message(new ByteBufferMessage()); + messageProps.setMessageId(messageId); } - // force a rebuild of the 0-10 message if data has changed - if (message.getData() == null) + else if (messageProps.hasMessageId()) { - message.dataChanged(); + messageProps.clearMessageId(); } - DeliveryProperties deliveryProp = message.get010Message().getDeliveryProperties(); - MessageProperties messageProps = message.get010Message().getMessageProperties(); - // set the delivery properties if (!_disableTimestamps) { final long currentTime = System.currentTimeMillis(); @@ -124,10 +125,10 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer deliveryProp.setPriority(MessageDeliveryPriority.get((short) priority)); message.setJMSPriority(priority); } - String excahngeName = destination.getExchangeName().toString(); - if ( deliveryProp.getExchange() == null || ! deliveryProp.getExchange().equals(excahngeName)) + String exchangeName = destination.getExchangeName().toString(); + if ( deliveryProp.getExchange() == null || ! deliveryProp.getExchange().equals(exchangeName)) { - deliveryProp.setExchange(excahngeName); + deliveryProp.setExchange(exchangeName); } String routingKey = destination.getRoutingKey().toString(); if (deliveryProp.getRoutingKey() == null || ! deliveryProp.getRoutingKey().equals(routingKey)) @@ -135,105 +136,29 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer deliveryProp.setRoutingKey(routingKey); } - BasicContentHeaderProperties contentHeaderProperties = message.getContentHeaderProperties(); - if (contentHeaderProperties.reset()) - { - // set the application properties - messageProps.setContentType(contentHeaderProperties.getContentType().toString()); - messageProps.setContentLength(message.getContentLength()); - - // XXX: fixme - String mid = message.getJMSMessageID(); - if( mid != null ) - { - messageProps.setMessageId(UUID.fromString(mid.substring(3))); - } - - AMQShortString correlationID = contentHeaderProperties.getCorrelationId(); - if (correlationID != null) - { - messageProps.setCorrelationId(correlationID.getBytes()); - } - - String replyToURL = contentHeaderProperties.getReplyToAsString(); - if (replyToURL != null) - { - if(_logger.isDebugEnabled()) - { - StringBuffer b = new StringBuffer(); - b.append("\n=========================="); - b.append("\nReplyTo : " + replyToURL); - b.append("\n=========================="); - _logger.debug(b.toString()); - } - AMQBindingURL dest; - try - { - dest = new AMQBindingURL(replyToURL); - } - catch (URISyntaxException e) - { - throw ExceptionHelper.convertQpidExceptionToJMSException(e); - } - messageProps.setReplyTo(new ReplyTo(dest.getExchangeName().toString(), dest.getRoutingKey().toString())); - } - - Map<String,Object> map = null; - - if (contentHeaderProperties.getHeaders() != null) - { - //JMS_QPID_DESTTYPE is always set but useles so this is a temporary fix - contentHeaderProperties.getHeaders().remove(CustomJMSXProperty.JMS_QPID_DESTTYPE.getShortStringName()); - map = FiledTableSupport.convertToMap(contentHeaderProperties.getHeaders()); - } - - AMQShortString type = contentHeaderProperties.getType(); - if (type != null) - { - if (map == null) - { - map = new HashMap<String,Object>(); - } - map.put(AbstractJMSMessage.JMS_TYPE, type.toString()); - } - - if (map != null) - { - messageProps.setApplicationHeaders(map); - } - } + messageProps.setContentLength(message.getContentLength()); // send the message try { - org.apache.qpidity.nclient.Session ssn = ((AMQSession_0_10) getSession()).getQpidSession(); + org.apache.qpid.transport.Session ssn = (org.apache.qpid.transport.Session) + ((AMQSession_0_10) getSession()).getQpidSession(); // if true, we need to sync the delivery of this message boolean sync = (deliveryMode == DeliveryMode.PERSISTENT && getSession().getAMQConnection().getSyncPersistence()); + org.apache.mina.common.ByteBuffer data = message.getData(); + ByteBuffer buffer = data == null ? ByteBuffer.allocate(0) : data.buf().slice(); + + ssn.messageTransfer(destination.getExchangeName().toString(), MessageAcceptMode.NONE, + MessageAcquireMode.PRE_ACQUIRED, + new Header(deliveryProp, messageProps), + buffer, sync ? SYNC : NONE); if (sync) { - ssn.setAutoSync(true); - } - try - { - ssn.messageTransfer(destination.getExchangeName().toString(), - message.get010Message(), - ssn.TRANSFER_CONFIRM_MODE_NOT_REQUIRED, - ssn.TRANSFER_ACQUIRE_MODE_PRE_ACQUIRE); + ssn.sync(); } - finally - { - if (sync) - { - ssn.setAutoSync(false); - } - } - } - catch (IOException e) - { - throw ExceptionHelper.convertQpidExceptionToJMSException(e); } catch (RuntimeException rte) { diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java index ff991b1a03..c547fcb488 100644 --- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java +++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java @@ -20,11 +20,15 @@ */ package org.apache.qpid.client; +import java.util.UUID; + import javax.jms.JMSException; import javax.jms.Message; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.client.message.AbstractJMSMessage; +import org.apache.qpid.client.message.AMQMessageDelegate; +import org.apache.qpid.client.message.AMQMessageDelegate_0_8; import org.apache.qpid.client.protocol.AMQProtocolHandler; import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.BasicConsumeBody; @@ -65,9 +69,9 @@ public class BasicMessageProducer_0_8 extends BasicMessageProducer _protocolHandler.writeFrame(declare); } - void sendMessage(AMQDestination destination, Message origMessage,AbstractJMSMessage message, - int deliveryMode,int priority, long timeToLive, boolean mandatory, boolean immediate, - boolean wait) throws JMSException + void sendMessage(AMQDestination destination, Message origMessage, AbstractJMSMessage message, + UUID messageId, int deliveryMode,int priority, long timeToLive, boolean mandatory, + boolean immediate, boolean wait) throws JMSException { BasicPublishBody body = getSession().getMethodRegistry().createBasicPublishBody(_session.getTicket(), destination.getExchangeName(), @@ -79,7 +83,8 @@ public class BasicMessageProducer_0_8 extends BasicMessageProducer message.prepareForSending(); ByteBuffer payload = message.getData(); - BasicContentHeaderProperties contentHeaderProperties = message.getContentHeaderProperties(); + AMQMessageDelegate_0_8 delegate = (AMQMessageDelegate_0_8) message.getDelegate(); + BasicContentHeaderProperties contentHeaderProperties = delegate.getContentHeaderProperties(); if (!_disableTimestamps) { diff --git a/java/client/src/main/java/org/apache/qpid/client/TopicSubscriberAdaptor.java b/java/client/src/main/java/org/apache/qpid/client/TopicSubscriberAdaptor.java index 29fa03fd1d..9bdef22f96 100644 --- a/java/client/src/main/java/org/apache/qpid/client/TopicSubscriberAdaptor.java +++ b/java/client/src/main/java/org/apache/qpid/client/TopicSubscriberAdaptor.java @@ -32,20 +32,20 @@ import javax.jms.TopicSubscriber; * Wraps a MessageConsumer to fulfill the extended TopicSubscriber contract * */ -class TopicSubscriberAdaptor implements TopicSubscriber +class TopicSubscriberAdaptor<C extends BasicMessageConsumer> implements TopicSubscriber { private final Topic _topic; - private final BasicMessageConsumer _consumer; + private final C _consumer; private final boolean _noLocal; - TopicSubscriberAdaptor(Topic topic, BasicMessageConsumer consumer, boolean noLocal) + TopicSubscriberAdaptor(Topic topic, C consumer, boolean noLocal) { _topic = topic; _consumer = consumer; _noLocal = noLocal; } - TopicSubscriberAdaptor(Topic topic, BasicMessageConsumer consumer) + TopicSubscriberAdaptor(Topic topic, C consumer) { this(topic, consumer, consumer.isNoLocal()); } @@ -103,7 +103,7 @@ class TopicSubscriberAdaptor implements TopicSubscriber } private void checkPreConditions() throws javax.jms.IllegalStateException{ - BasicMessageConsumer msgConsumer = (BasicMessageConsumer)_consumer; + C msgConsumer = _consumer; if (msgConsumer.isClosed() ){ throw new javax.jms.IllegalStateException("Consumer is closed"); @@ -120,7 +120,7 @@ class TopicSubscriberAdaptor implements TopicSubscriber } } - BasicMessageConsumer getMessageConsumer() + C getMessageConsumer() { return _consumer; } diff --git a/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java b/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java index 7a107d748b..6763c72ecd 100644 --- a/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java +++ b/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java @@ -21,9 +21,9 @@ import javax.transaction.xa.XAException; import javax.transaction.xa.XAResource; import javax.transaction.xa.Xid; -import org.apache.qpidity.QpidException; -import org.apache.qpidity.dtx.XidImpl; -import org.apache.qpidity.transport.*; +import org.apache.qpid.QpidException; +import org.apache.qpid.dtx.XidImpl; +import org.apache.qpid.transport.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -76,7 +76,7 @@ public class XAResourceImpl implements XAResource _logger.debug("commit tx branch with xid: ", xid); } Future<XaResult> future = - _xaSession.getQpidSession().dtxCommit(convertXid(xid), b ? Option.ONE_PHASE : Option.NO_OPTION); + _xaSession.getQpidSession().dtxCommit(convertXid(xid), b ? Option.ONE_PHASE : Option.NONE); // now wait on the future for the result XaResult result = null; @@ -86,7 +86,7 @@ public class XAResourceImpl implements XAResource } catch (SessionException e) { - // we need to restore the qpidity session that has been closed + // we need to restore the qpid session that has been closed _xaSession.createSession(); // we should get a single exception convertExecutionErrorToXAErr(e.getExceptions().get(0).getErrorCode()); @@ -127,10 +127,11 @@ public class XAResourceImpl implements XAResource default: throw new XAException(XAException.XAER_INVAL); } + _xaSession.flushAcknowledgments(); Future<XaResult> future = _xaSession.getQpidSession() .dtxEnd(convertXid(xid), - flag == XAResource.TMFAIL ? Option.FAIL : Option.NO_OPTION, - flag == XAResource.TMSUSPEND ? Option.SUSPEND : Option.NO_OPTION); + flag == XAResource.TMFAIL ? Option.FAIL : Option.NONE, + flag == XAResource.TMSUSPEND ? Option.SUSPEND : Option.NONE); // now wait on the future for the result XaResult result = null; try @@ -139,7 +140,7 @@ public class XAResourceImpl implements XAResource } catch (SessionException e) { - // we need to restore the qpidity session that has been closed + // we need to restore the qpid session that has been closed _xaSession.createSession(); // we should get a single exception convertExecutionErrorToXAErr(e.getExceptions().get(0).getErrorCode()); @@ -168,7 +169,7 @@ public class XAResourceImpl implements XAResource } catch (SessionException e) { - // we need to restore the qpidity session that has been closed + // we need to restore the qpid session that has been closed _xaSession.createSession(); // we should get a single exception convertExecutionErrorToXAErr(e.getExceptions().get(0).getErrorCode()); @@ -198,7 +199,7 @@ public class XAResourceImpl implements XAResource } catch (SessionException e) { - // we need to restore the qpidity session that has been closed + // we need to restore the qpid session that has been closed _xaSession.createSession(); // we should get a single exception convertExecutionErrorToXAErr(e.getExceptions().get(0).getErrorCode()); @@ -245,7 +246,7 @@ public class XAResourceImpl implements XAResource } catch (SessionException e) { - // we need to restore the qpidity session that has been closed + // we need to restore the qpid session that has been closed _xaSession.createSession(); // we should get a single exception convertExecutionErrorToXAErr(e.getExceptions().get(0).getErrorCode()); @@ -288,7 +289,7 @@ public class XAResourceImpl implements XAResource } catch (SessionException e) { - // we need to restore the qpidity session that has been closed + // we need to restore the qpid session that has been closed _xaSession.createSession(); // we should get a single exception convertExecutionErrorToXAErr( e.getExceptions().get(0).getErrorCode()); @@ -297,7 +298,7 @@ public class XAResourceImpl implements XAResource int i = 0; for (Object obj : res.getInDoubt()) { - org.apache.qpidity.transport.Xid xid = (org.apache.qpidity.transport.Xid) obj; + org.apache.qpid.transport.Xid xid = (org.apache.qpid.transport.Xid) obj; result[i] = new XidImpl(xid.getBranchId(), (int) xid.getFormat(), xid.getGlobalId()); i++; } @@ -326,7 +327,7 @@ public class XAResourceImpl implements XAResource } catch (SessionException e) { - // we need to restore the qpidity session that has been closed + // we need to restore the qpid session that has been closed _xaSession.createSession(); // we should get a single exception convertExecutionErrorToXAErr( e.getExceptions().get(0).getErrorCode()); @@ -400,8 +401,8 @@ public class XAResourceImpl implements XAResource } Future<XaResult> future = _xaSession.getQpidSession() .dtxStart(convertXid(xid), - flag == XAResource.TMJOIN ? Option.JOIN : Option.NO_OPTION, - flag == XAResource.TMRESUME ? Option.RESUME : Option.NO_OPTION); + flag == XAResource.TMJOIN ? Option.JOIN : Option.NONE, + flag == XAResource.TMRESUME ? Option.RESUME : Option.NONE); // now wait on the future for the result XaResult result = null; try @@ -410,7 +411,7 @@ public class XAResourceImpl implements XAResource } catch (SessionException e) { - // we need to restore the qpidity session that has been closed + // we need to restore the qpid session that has been closed _xaSession.createSession(); // we should get a single exception convertExecutionErrorToXAErr(e.getExceptions().get(0).getErrorCode()); @@ -511,7 +512,7 @@ public class XAResourceImpl implements XAResource * @return the qpid formated xid * @throws XAException when xid is null or when it cannot be converted. */ - private org.apache.qpidity.transport.Xid convertXid(Xid xid) throws XAException + private org.apache.qpid.transport.Xid convertXid(Xid xid) throws XAException { if (xid == null) { diff --git a/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java b/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java index 1eda71cc63..51b4b7899f 100644 --- a/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java +++ b/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java @@ -17,7 +17,7 @@ */ package org.apache.qpid.client; -import org.apache.qpidity.nclient.DtxSession; +import org.apache.qpid.nclient.DtxSession; import org.apache.qpid.client.message.MessageFactoryRegistry; import javax.jms.*; @@ -48,7 +48,7 @@ public class XASessionImpl extends AMQSession_0_10 implements XASession, XATopic /** * Create a JMS XASession */ - public XASessionImpl(org.apache.qpidity.nclient.Connection qpidConnection, AMQConnection con, int channelId, + public XASessionImpl(org.apache.qpid.nclient.Connection qpidConnection, AMQConnection con, int channelId, int defaultPrefetchHigh, int defaultPrefetchLow) { super(qpidConnection, con, channelId, false, // this is not a transacted session @@ -61,7 +61,7 @@ public class XASessionImpl extends AMQSession_0_10 implements XASession, XATopic //-- public methods /** - * Create a qpidity session. + * Create a qpid session. */ public void createSession() { @@ -126,7 +126,7 @@ public class XASessionImpl extends AMQSession_0_10 implements XASession, XATopic * * @return The associated Qpid Session. */ - protected org.apache.qpidity.nclient.DtxSession getQpidSession() + protected org.apache.qpid.nclient.DtxSession getQpidSession() { return _qpidDtxSession; } diff --git a/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java b/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java index 76c899f565..927f660932 100644 --- a/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java @@ -139,11 +139,15 @@ public class FailoverHandler implements Runnable // have a state waiter waiting until the connection is closed for some reason. Or in future we may have // a slightly more complex state model therefore I felt it was worthwhile doing this. AMQStateManager existingStateManager = _amqProtocolHandler.getStateManager(); - _amqProtocolHandler.setStateManager(new AMQStateManager(_amqProtocolHandler.getProtocolSession())); + + _amqProtocolHandler.setStateManager(new AMQStateManager()); + + if (!_amqProtocolHandler.getConnection().firePreFailover(_host != null)) { _logger.info("Failover process veto-ed by client"); + //Restore Existing State Manager _amqProtocolHandler.setStateManager(existingStateManager); //todo: ritchiem these exceptions are useless... Would be better to attempt to propogate exception that @@ -181,13 +185,19 @@ public class FailoverHandler implements Runnable if (!failoverSucceeded) { + //Restore Existing State Manager _amqProtocolHandler.setStateManager(existingStateManager); + _amqProtocolHandler.getConnection().exceptionReceived( new AMQDisconnectedException("Server closed connection and no failover " + "was successful", null)); } else { + // Set the new Protocol Session in the StateManager. + existingStateManager.setProtocolSession(_amqProtocolHandler.getProtocolSession()); + + //Restore Existing State Manager _amqProtocolHandler.setStateManager(existingStateManager); try { diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/AccessRequestOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/AccessRequestOkMethodHandler.java index 5bd36aa88b..365fed6aa5 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/AccessRequestOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/AccessRequestOkMethodHandler.java @@ -5,14 +5,8 @@ import org.slf4j.LoggerFactory; import org.apache.qpid.framing.*; import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.AMQNoConsumersException; -import org.apache.qpid.client.AMQNoRouteException; import org.apache.qpid.AMQException; -import org.apache.qpid.AMQInvalidRoutingKeyException; -import org.apache.qpid.AMQChannelClosedException; -import org.apache.qpid.protocol.AMQConstant; public class AccessRequestOkMethodHandler implements StateAwareMethodListener<AccessRequestOkBody> { @@ -25,11 +19,10 @@ public class AccessRequestOkMethodHandler implements StateAwareMethodListener<Ac return _handler; } - public void methodReceived(AMQStateManager stateManager, AccessRequestOkBody method, int channelId) + public void methodReceived(AMQProtocolSession session, AccessRequestOkBody method, int channelId) throws AMQException { _logger.debug("AccessRequestOk method received"); - final AMQProtocolSession session = stateManager.getProtocolSession(); session.setTicket(method.getTicket(), channelId); } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/BasicCancelOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/BasicCancelOkMethodHandler.java index e3e08667d8..5cb9412d51 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/BasicCancelOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/BasicCancelOkMethodHandler.java @@ -22,11 +22,8 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.BasicCancelOkBody; -import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,13 +42,9 @@ public class BasicCancelOkMethodHandler implements StateAwareMethodListener<Basi private BasicCancelOkMethodHandler() { } - public void methodReceived(AMQStateManager stateManager, BasicCancelOkBody body, int channelId) + public void methodReceived(AMQProtocolSession session, BasicCancelOkBody body, int channelId) throws AMQException { - AMQProtocolSession session = stateManager.getProtocolSession(); - - - if (_logger.isInfoEnabled()) { _logger.info("New BasicCancelOk method received for consumer:" + body.getConsumerTag()); diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java index 4deaa314ec..6237234c4d 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java @@ -21,10 +21,8 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.client.message.UnprocessedMessage; import org.apache.qpid.client.message.UnprocessedMessage_0_8; import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.BasicDeliverBody; import org.slf4j.Logger; @@ -41,18 +39,16 @@ public class BasicDeliverMethodHandler implements StateAwareMethodListener<Basic return _instance; } - public void methodReceived(AMQStateManager stateManager, BasicDeliverBody body, int channelId) - throws AMQException + public void methodReceived(AMQProtocolSession session, BasicDeliverBody body, int channelId) + throws AMQException { - final AMQProtocolSession session = stateManager.getProtocolSession(); final UnprocessedMessage_0_8 msg = new UnprocessedMessage_0_8( - channelId, body.getDeliveryTag(), - body.getConsumerTag(), + body.getConsumerTag().toIntValue(), body.getExchange(), body.getRoutingKey(), body.getRedelivered()); - _logger.debug("New JmsDeliver method received"); - session.unprocessedMessageReceived(msg); + _logger.debug("New JmsDeliver method received:" + session); + session.unprocessedMessageReceived(channelId, msg); } } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/BasicReturnMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/BasicReturnMethodHandler.java index 682c3ac2c1..3bbc9209c5 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/BasicReturnMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/BasicReturnMethodHandler.java @@ -22,13 +22,9 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; import org.apache.qpid.client.message.ReturnMessage; -import org.apache.qpid.client.message.UnprocessedMessage; -import org.apache.qpid.client.message.UnprocessedMessage_0_8; import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.BasicReturnBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,19 +41,18 @@ public class BasicReturnMethodHandler implements StateAwareMethodListener<BasicR } - public void methodReceived(AMQStateManager stateManager, BasicReturnBody body, int channelId) + public void methodReceived(AMQProtocolSession session, BasicReturnBody body, int channelId) throws AMQException { _logger.debug("New JmsBounce method received"); - final AMQProtocolSession session = stateManager.getProtocolSession(); - final ReturnMessage msg = new ReturnMessage(channelId, + final ReturnMessage msg = new ReturnMessage( body.getExchange(), body.getRoutingKey(), body.getReplyText(), body.getReplyCode() ); - session.unprocessedMessageReceived(msg); + session.unprocessedMessageReceived(channelId, msg); } } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java index ee4cf14d58..2b6745ebe4 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java @@ -26,14 +26,12 @@ import org.apache.qpid.AMQInvalidRoutingKeyException; import org.apache.qpid.client.AMQNoConsumersException; import org.apache.qpid.client.AMQNoRouteException; import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ChannelCloseBody; import org.apache.qpid.framing.ChannelCloseOkBody; import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,12 +47,10 @@ public class ChannelCloseMethodHandler implements StateAwareMethodListener<Chann return _handler; } - public void methodReceived(AMQStateManager stateManager, ChannelCloseBody method, int channelId) + public void methodReceived(AMQProtocolSession session, ChannelCloseBody method, int channelId) throws AMQException { _logger.debug("ChannelClose method received"); - final AMQProtocolSession session = stateManager.getProtocolSession(); - AMQConstant errorCode = AMQConstant.getConstant(method.getReplyCode()); AMQShortString reason = method.getReplyText(); diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java index 8d3277d4de..9a9a0b4e63 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java @@ -23,9 +23,7 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; import org.apache.qpid.framing.ChannelCloseOkBody; import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,12 +39,11 @@ public class ChannelCloseOkMethodHandler implements StateAwareMethodListener<Cha return _instance; } - public void methodReceived(AMQStateManager stateManager, ChannelCloseOkBody method, int channelId) + public void methodReceived(AMQProtocolSession session, ChannelCloseOkBody method, int channelId) throws AMQException { _logger.info("Received channel-close-ok for channel-id " + channelId); - final AMQProtocolSession session = stateManager.getProtocolSession(); // todo this should do the local closure } } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowMethodHandler.java index b47fe751d6..2153b9cc8c 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowMethodHandler.java @@ -2,7 +2,6 @@ package org.apache.qpid.client.handler; import org.apache.qpid.framing.ChannelFlowBody; import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.AMQException; import org.slf4j.Logger; @@ -42,11 +41,9 @@ public class ChannelFlowMethodHandler implements StateAwareMethodListener<Channe private ChannelFlowMethodHandler() { } - public void methodReceived(AMQStateManager stateManager, ChannelFlowBody body, int channelId) + public void methodReceived(AMQProtocolSession session, ChannelFlowBody body, int channelId) throws AMQException { - - final AMQProtocolSession session = stateManager.getProtocolSession(); session.setFlowControl(channelId, body.getActive()); } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java index 96de8af54b..6f66a972d5 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java @@ -22,10 +22,8 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.ChannelFlowOkBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,7 +41,7 @@ public class ChannelFlowOkMethodHandler implements StateAwareMethodListener<Chan private ChannelFlowOkMethodHandler() { } - public void methodReceived(AMQStateManager stateManager, ChannelFlowOkBody body, int channelId) + public void methodReceived(AMQProtocolSession session, ChannelFlowOkBody body, int channelId) throws AMQException { diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl.java b/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl.java index afb7517a12..9c791730ca 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl.java @@ -27,31 +27,32 @@ import org.apache.qpid.framing.*; import org.apache.qpid.AMQException; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.AMQMethodNotImplementedException; - +import org.apache.qpid.client.protocol.AMQProtocolSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ClientMethodDispatcherImpl implements MethodDispatcher { - - private static final BasicCancelOkMethodHandler _basicCancelOkMethodHandler = BasicCancelOkMethodHandler.getInstance(); - private static final BasicDeliverMethodHandler _basicDeliverMethodHandler = BasicDeliverMethodHandler.getInstance(); - private static final BasicReturnMethodHandler _basicReturnMethodHandler = BasicReturnMethodHandler.getInstance(); - private static final ChannelCloseMethodHandler _channelCloseMethodHandler = ChannelCloseMethodHandler.getInstance(); - private static final ChannelFlowOkMethodHandler _channelFlowOkMethodHandler = ChannelFlowOkMethodHandler.getInstance(); - private static final ConnectionCloseMethodHandler _connectionCloseMethodHandler = ConnectionCloseMethodHandler.getInstance(); - private static final ConnectionOpenOkMethodHandler _connectionOpenOkMethodHandler = ConnectionOpenOkMethodHandler.getInstance(); + private static final BasicCancelOkMethodHandler _basicCancelOkMethodHandler = BasicCancelOkMethodHandler.getInstance(); + private static final BasicDeliverMethodHandler _basicDeliverMethodHandler = BasicDeliverMethodHandler.getInstance(); + private static final BasicReturnMethodHandler _basicReturnMethodHandler = BasicReturnMethodHandler.getInstance(); + private static final ChannelCloseMethodHandler _channelCloseMethodHandler = ChannelCloseMethodHandler.getInstance(); + private static final ChannelFlowOkMethodHandler _channelFlowOkMethodHandler = ChannelFlowOkMethodHandler.getInstance(); + private static final ConnectionCloseMethodHandler _connectionCloseMethodHandler = ConnectionCloseMethodHandler.getInstance(); + private static final ConnectionOpenOkMethodHandler _connectionOpenOkMethodHandler = ConnectionOpenOkMethodHandler.getInstance(); private static final ConnectionRedirectMethodHandler _connectionRedirectMethodHandler = ConnectionRedirectMethodHandler.getInstance(); - private static final ConnectionSecureMethodHandler _connectionSecureMethodHandler = ConnectionSecureMethodHandler.getInstance(); - private static final ConnectionStartMethodHandler _connectionStartMethodHandler = ConnectionStartMethodHandler.getInstance(); - private static final ConnectionTuneMethodHandler _connectionTuneMethodHandler = ConnectionTuneMethodHandler.getInstance(); - private static final ExchangeBoundOkMethodHandler _exchangeBoundOkMethodHandler = ExchangeBoundOkMethodHandler.getInstance(); - private static final QueueDeleteOkMethodHandler _queueDeleteOkMethodHandler = QueueDeleteOkMethodHandler.getInstance(); - + private static final ConnectionSecureMethodHandler _connectionSecureMethodHandler = ConnectionSecureMethodHandler.getInstance(); + private static final ConnectionStartMethodHandler _connectionStartMethodHandler = ConnectionStartMethodHandler.getInstance(); + private static final ConnectionTuneMethodHandler _connectionTuneMethodHandler = ConnectionTuneMethodHandler.getInstance(); + private static final ExchangeBoundOkMethodHandler _exchangeBoundOkMethodHandler = ExchangeBoundOkMethodHandler.getInstance(); + private static final QueueDeleteOkMethodHandler _queueDeleteOkMethodHandler = QueueDeleteOkMethodHandler.getInstance(); + private static final Logger _logger = LoggerFactory.getLogger(ClientMethodDispatcherImpl.class); private static interface DispatcherFactory { - public ClientMethodDispatcherImpl createMethodDispatcher(AMQStateManager stateManager); + public ClientMethodDispatcherImpl createMethodDispatcher(AMQProtocolSession session); } private static final Map<ProtocolVersion, DispatcherFactory> _dispatcherFactories = @@ -62,44 +63,44 @@ public class ClientMethodDispatcherImpl implements MethodDispatcher _dispatcherFactories.put(ProtocolVersion.v8_0, new DispatcherFactory() { - public ClientMethodDispatcherImpl createMethodDispatcher(AMQStateManager stateManager) + public ClientMethodDispatcherImpl createMethodDispatcher(AMQProtocolSession session) { - return new ClientMethodDispatcherImpl_8_0(stateManager); + return new ClientMethodDispatcherImpl_8_0(session); } }); _dispatcherFactories.put(ProtocolVersion.v0_9, new DispatcherFactory() { - public ClientMethodDispatcherImpl createMethodDispatcher(AMQStateManager stateManager) + public ClientMethodDispatcherImpl createMethodDispatcher(AMQProtocolSession session) { - return new ClientMethodDispatcherImpl_0_9(stateManager); + return new ClientMethodDispatcherImpl_0_9(session); } }); } - - public static ClientMethodDispatcherImpl newMethodDispatcher(ProtocolVersion version, AMQStateManager stateManager) + public static ClientMethodDispatcherImpl newMethodDispatcher(ProtocolVersion version, AMQProtocolSession session) { + if (_logger.isInfoEnabled()) + { + _logger.info("New Method Dispatcher:" + session); + } + DispatcherFactory factory = _dispatcherFactories.get(version); - return factory.createMethodDispatcher(stateManager); + return factory.createMethodDispatcher(session); } - + AMQProtocolSession _session; - - private AMQStateManager _stateManager; - - public ClientMethodDispatcherImpl(AMQStateManager stateManager) + public ClientMethodDispatcherImpl(AMQProtocolSession session) { - _stateManager = stateManager; + _session = session; } - public AMQStateManager getStateManager() { - return _stateManager; + return _session.getStateManager(); } public boolean dispatchAccessRequestOk(AccessRequestOkBody body, int channelId) throws AMQException @@ -109,7 +110,7 @@ public class ClientMethodDispatcherImpl implements MethodDispatcher public boolean dispatchBasicCancelOk(BasicCancelOkBody body, int channelId) throws AMQException { - _basicCancelOkMethodHandler.methodReceived(_stateManager,body,channelId); + _basicCancelOkMethodHandler.methodReceived(_session, body, channelId); return true; } @@ -120,7 +121,7 @@ public class ClientMethodDispatcherImpl implements MethodDispatcher public boolean dispatchBasicDeliver(BasicDeliverBody body, int channelId) throws AMQException { - _basicDeliverMethodHandler.methodReceived(_stateManager,body,channelId); + _basicDeliverMethodHandler.methodReceived(_session, body, channelId); return true; } @@ -141,13 +142,13 @@ public class ClientMethodDispatcherImpl implements MethodDispatcher public boolean dispatchBasicReturn(BasicReturnBody body, int channelId) throws AMQException { - _basicReturnMethodHandler.methodReceived(_stateManager,body,channelId); + _basicReturnMethodHandler.methodReceived(_session, body, channelId); return true; } public boolean dispatchChannelClose(ChannelCloseBody body, int channelId) throws AMQException { - _channelCloseMethodHandler.methodReceived(_stateManager,body,channelId); + _channelCloseMethodHandler.methodReceived(_session, body, channelId); return true; } @@ -163,7 +164,7 @@ public class ClientMethodDispatcherImpl implements MethodDispatcher public boolean dispatchChannelFlowOk(ChannelFlowOkBody body, int channelId) throws AMQException { - _channelFlowOkMethodHandler.methodReceived(_stateManager,body,channelId); + _channelFlowOkMethodHandler.methodReceived(_session, body, channelId); return true; } @@ -174,7 +175,7 @@ public class ClientMethodDispatcherImpl implements MethodDispatcher public boolean dispatchConnectionClose(ConnectionCloseBody body, int channelId) throws AMQException { - _connectionCloseMethodHandler.methodReceived(_stateManager,body,channelId); + _connectionCloseMethodHandler.methodReceived(_session, body, channelId); return true; } @@ -185,37 +186,37 @@ public class ClientMethodDispatcherImpl implements MethodDispatcher public boolean dispatchConnectionOpenOk(ConnectionOpenOkBody body, int channelId) throws AMQException { - _connectionOpenOkMethodHandler.methodReceived(_stateManager,body,channelId); + _connectionOpenOkMethodHandler.methodReceived(_session, body, channelId); return true; } public boolean dispatchConnectionRedirect(ConnectionRedirectBody body, int channelId) throws AMQException { - _connectionRedirectMethodHandler.methodReceived(_stateManager,body,channelId); + _connectionRedirectMethodHandler.methodReceived(_session, body, channelId); return true; } public boolean dispatchConnectionSecure(ConnectionSecureBody body, int channelId) throws AMQException { - _connectionSecureMethodHandler.methodReceived(_stateManager,body,channelId); + _connectionSecureMethodHandler.methodReceived(_session, body, channelId); return true; } public boolean dispatchConnectionStart(ConnectionStartBody body, int channelId) throws AMQException { - _connectionStartMethodHandler.methodReceived(_stateManager,body,channelId); + _connectionStartMethodHandler.methodReceived(_session, body, channelId); return true; } public boolean dispatchConnectionTune(ConnectionTuneBody body, int channelId) throws AMQException { - _connectionTuneMethodHandler.methodReceived(_stateManager,body,channelId); + _connectionTuneMethodHandler.methodReceived(_session, body, channelId); return true; } public boolean dispatchQueueDeleteOk(QueueDeleteOkBody body, int channelId) throws AMQException { - _queueDeleteOkMethodHandler.methodReceived(_stateManager,body,channelId); + _queueDeleteOkMethodHandler.methodReceived(_session, body, channelId); return true; } @@ -431,7 +432,7 @@ public class ClientMethodDispatcherImpl implements MethodDispatcher public boolean dispatchExchangeBoundOk(ExchangeBoundOkBody body, int channelId) throws AMQException { - _exchangeBoundOkMethodHandler.methodReceived(_stateManager,body,channelId); + _exchangeBoundOkMethodHandler.methodReceived(_session, body, channelId); return true; } @@ -522,7 +523,7 @@ public class ClientMethodDispatcherImpl implements MethodDispatcher public boolean dispatchTxSelectOk(TxSelectOkBody body, int channelId) throws AMQException { - return false; + return false; } } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl_0_9.java b/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl_0_9.java index e235368357..d3e9fba8ed 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl_0_9.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl_0_9.java @@ -26,16 +26,15 @@ import org.apache.qpid.framing.amqp_0_9.MethodDispatcher_0_9; import org.apache.qpid.AMQException; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.AMQMethodNotImplementedException; - +import org.apache.qpid.client.protocol.AMQProtocolSession; public class ClientMethodDispatcherImpl_0_9 extends ClientMethodDispatcherImpl implements MethodDispatcher_0_9 { - public ClientMethodDispatcherImpl_0_9(AMQStateManager stateManager) + public ClientMethodDispatcherImpl_0_9(AMQProtocolSession session) { - super(stateManager); + super(session); } - public boolean dispatchBasicRecoverSyncOk(BasicRecoverSyncOkBody body, int channelId) throws AMQException { return false; @@ -148,8 +147,7 @@ public class ClientMethodDispatcherImpl_0_9 extends ClientMethodDispatcherImpl i public boolean dispatchQueueUnbindOk(QueueUnbindOkBody body, int channelId) throws AMQException { - return false; + return false; } - } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl_8_0.java b/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl_8_0.java index b0f003cd2d..19f758817d 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl_8_0.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl_8_0.java @@ -24,13 +24,13 @@ import org.apache.qpid.framing.*; import org.apache.qpid.framing.amqp_8_0.MethodDispatcher_8_0; import org.apache.qpid.AMQException; -import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.protocol.AMQProtocolSession; public class ClientMethodDispatcherImpl_8_0 extends ClientMethodDispatcherImpl implements MethodDispatcher_8_0 { - public ClientMethodDispatcherImpl_8_0(AMQStateManager stateManager) + public ClientMethodDispatcherImpl_8_0(AMQProtocolSession session) { - super(stateManager); + super(session); } public boolean dispatchBasicRecoverOk(BasicRecoverOkBody body, int channelId) throws AMQException diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java index 950a3288fc..bc82d6bc62 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java @@ -25,13 +25,11 @@ import org.apache.qpid.AMQException; import org.apache.qpid.client.AMQAuthenticationException; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQState; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ConnectionCloseBody; import org.apache.qpid.framing.ConnectionCloseOkBody; import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,14 +46,13 @@ public class ConnectionCloseMethodHandler implements StateAwareMethodListener<Co } private ConnectionCloseMethodHandler() - { } + { + } - public void methodReceived(AMQStateManager stateManager, ConnectionCloseBody method, int channelId) - throws AMQException + public void methodReceived(AMQProtocolSession session, ConnectionCloseBody method, int channelId) + throws AMQException { _logger.info("ConnectionClose frame received"); - final AMQProtocolSession session = stateManager.getProtocolSession(); - // does it matter // stateManager.changeState(AMQState.CONNECTION_CLOSING); @@ -63,6 +60,8 @@ public class ConnectionCloseMethodHandler implements StateAwareMethodListener<Co AMQConstant errorCode = AMQConstant.getConstant(method.getReplyCode()); AMQShortString reason = method.getReplyText(); + AMQException error = null; + try { @@ -75,35 +74,33 @@ public class ConnectionCloseMethodHandler implements StateAwareMethodListener<Co { if (errorCode == AMQConstant.NOT_ALLOWED || (errorCode == AMQConstant.ACCESS_REFUSED)) { - _logger.info("Error :" + errorCode +":"+ Thread.currentThread().getName()); - - // todo ritchiem : Why do this here when it is going to be done in the finally block? - session.closeProtocolSession(); + _logger.info("Error :" + errorCode + ":" + Thread.currentThread().getName()); - // todo this is a bit of a fudge (could be conssidered such as each new connection needs a new state manager or at least a fresh state. - stateManager.changeState(AMQState.CONNECTION_NOT_STARTED); - - throw new AMQAuthenticationException(errorCode, reason == null ? null : reason.toString(), null); + error = new AMQAuthenticationException(errorCode, reason == null ? null : reason.toString(), null); } else { _logger.info("Connection close received with error code " + errorCode); - throw new AMQConnectionClosedException(errorCode, "Error: " + reason, null); + error = new AMQConnectionClosedException(errorCode, "Error: " + reason, null); } } } finally { - // this actually closes the connection in the case where it is not an error. + if (error != null) + { + session.notifyError(error); + } + + // Close the protocol Session, including any open TCP connections session.closeProtocolSession(); - // ritchiem: Doing this though will cause any waiting connection start to be released without being able to - // see what the cause was. - stateManager.changeState(AMQState.CONNECTION_CLOSED); + // Closing the session should not introduce a race condition as this thread will continue to propgate any + // exception in to the exceptionCaught method of the SessionHandler. + // Any sessionClosed event should occur after this. } } - } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java index fd7acac84f..e639a33450 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java @@ -24,9 +24,7 @@ import org.apache.qpid.AMQException; import org.apache.qpid.framing.ConnectionOpenOkBody; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQState; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.protocol.AMQMethodEvent; public class ConnectionOpenOkMethodHandler implements StateAwareMethodListener<ConnectionOpenOkBody> { @@ -41,10 +39,10 @@ public class ConnectionOpenOkMethodHandler implements StateAwareMethodListener<C { } - public void methodReceived(AMQStateManager stateManager, ConnectionOpenOkBody body, int channelId) + public void methodReceived(AMQProtocolSession session, ConnectionOpenOkBody body, int channelId) throws AMQException { - stateManager.changeState(AMQState.CONNECTION_OPEN); + session.getStateManager().changeState(AMQState.CONNECTION_OPEN); } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java index cac68c9467..472c471fd6 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java @@ -22,10 +22,8 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.ConnectionRedirectBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,11 +44,10 @@ public class ConnectionRedirectMethodHandler implements StateAwareMethodListener private ConnectionRedirectMethodHandler() { } - public void methodReceived(AMQStateManager stateManager, ConnectionRedirectBody method, int channelId) + public void methodReceived(AMQProtocolSession session, ConnectionRedirectBody method, int channelId) throws AMQException { _logger.info("ConnectionRedirect frame received"); - final AMQProtocolSession session = stateManager.getProtocolSession(); String host = method.getHost().toString(); // the host is in the form hostname:port with the port being optional diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java index 900aa2abac..9a9bee757b 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java @@ -25,12 +25,9 @@ import javax.security.sasl.SaslException; import org.apache.qpid.AMQException; import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.ConnectionSecureBody; import org.apache.qpid.framing.ConnectionSecureOkBody; -import org.apache.qpid.protocol.AMQMethodEvent; public class ConnectionSecureMethodHandler implements StateAwareMethodListener<ConnectionSecureBody> { @@ -41,10 +38,9 @@ public class ConnectionSecureMethodHandler implements StateAwareMethodListener<C return _instance; } - public void methodReceived(AMQStateManager stateManager, ConnectionSecureBody body, int channelId) + public void methodReceived(AMQProtocolSession session, ConnectionSecureBody body, int channelId) throws AMQException { - final AMQProtocolSession session = stateManager.getProtocolSession(); SaslClient client = session.getSaslClient(); if (client == null) { diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java index d3746f137e..8857f1115a 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java @@ -25,7 +25,6 @@ import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.security.AMQCallbackHandler; import org.apache.qpid.client.security.CallbackHandlerRegistry; import org.apache.qpid.client.state.AMQState; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.common.ClientProperties; import org.apache.qpid.common.QpidProperties; @@ -35,7 +34,6 @@ import org.apache.qpid.framing.ConnectionStartOkBody; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.FieldTableFactory; import org.apache.qpid.framing.ProtocolVersion; -import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,15 +60,12 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener<Co private ConnectionStartMethodHandler() { } - public void methodReceived(AMQStateManager stateManager, ConnectionStartBody body, int channelId) + public void methodReceived(AMQProtocolSession session, ConnectionStartBody body, int channelId) throws AMQException { _log.debug("public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, " + "AMQMethodEvent evt): called"); - final AMQProtocolSession session = stateManager.getProtocolSession(); - - ProtocolVersion pv = new ProtocolVersion((byte) body.getVersionMajor(), (byte) body.getVersionMinor()); // For the purposes of interop, we can make the client accept the broker's version string. @@ -145,7 +140,7 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener<Co throw new AMQException(null, "No locales sent from server, passed: " + locales, null); } - stateManager.changeState(AMQState.CONNECTION_NOT_TUNED); + session.getStateManager().changeState(AMQState.CONNECTION_NOT_TUNED); FieldTable clientProperties = FieldTableFactory.newFieldTable(); clientProperties.setString(new AMQShortString(ClientProperties.instance.toString()), diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java index fc0e40b745..e4e58c317d 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java @@ -24,10 +24,8 @@ import org.apache.qpid.AMQException; import org.apache.qpid.client.ConnectionTuneParameters; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQState; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.*; -import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,11 +44,10 @@ public class ConnectionTuneMethodHandler implements StateAwareMethodListener<Con protected ConnectionTuneMethodHandler() { } - public void methodReceived(AMQStateManager stateManager, ConnectionTuneBody frame, int channelId) + public void methodReceived(AMQProtocolSession session, ConnectionTuneBody frame, int channelId) throws AMQException { _logger.debug("ConnectionTune frame received"); - final AMQProtocolSession session = stateManager.getProtocolSession(); final MethodRegistry methodRegistry = session.getMethodRegistry(); @@ -65,7 +62,7 @@ public class ConnectionTuneMethodHandler implements StateAwareMethodListener<Con params.setHeartbeat(Integer.getInteger("amqj.heartbeat.delay", frame.getHeartbeat())); session.setConnectionTuneParameters(params); - stateManager.changeState(AMQState.CONNECTION_NOT_OPENED); + session.getStateManager().changeState(AMQState.CONNECTION_NOT_OPENED); ConnectionTuneOkBody tuneOkBody = methodRegistry.createConnectionTuneOkBody(params.getChannelMax(), params.getFrameMax(), diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java index 8de40beb10..690d782b40 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java @@ -22,10 +22,8 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.ExchangeBoundOkBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,7 +44,7 @@ public class ExchangeBoundOkMethodHandler implements StateAwareMethodListener<Ex private ExchangeBoundOkMethodHandler() { } - public void methodReceived(AMQStateManager stateManager, ExchangeBoundOkBody body, int channelId) + public void methodReceived(AMQProtocolSession session, ExchangeBoundOkBody body, int channelId) throws AMQException { if (_logger.isDebugEnabled()) diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java index 41225c0569..01d82c9b55 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java @@ -22,10 +22,8 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.QueueDeleteOkBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,7 +44,7 @@ public class QueueDeleteOkMethodHandler implements StateAwareMethodListener<Queu private QueueDeleteOkMethodHandler() { } - public void methodReceived(AMQStateManager stateManager, QueueDeleteOkBody body, int channelId) + public void methodReceived(AMQProtocolSession session, QueueDeleteOkBody body, int channelId) throws AMQException { if (_logger.isDebugEnabled()) diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AMQMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/AMQMessage.java deleted file mode 100644 index 8741a1cbb6..0000000000 --- a/java/client/src/main/java/org/apache/qpid/client/message/AMQMessage.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * - * 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.qpid.client.message; - -import javax.jms.JMSException; - -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.framing.ContentHeaderProperties; -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.FieldTable; - -import java.math.BigDecimal; - -public class AMQMessage -{ - protected ContentHeaderProperties _contentHeaderProperties; - - /** If the acknowledge mode is CLIENT_ACKNOWLEDGE the session is required */ - protected AMQSession _session; - - protected final long _deliveryTag; - - public AMQMessage(ContentHeaderProperties properties, long deliveryTag) - { - _contentHeaderProperties = properties; - _deliveryTag = deliveryTag; - } - - public AMQMessage(ContentHeaderProperties properties) - { - this(properties, -1); - } - - /** - * The session is set when CLIENT_ACKNOWLEDGE mode is used so that the CHANNEL ACK can be sent when the user calls - * acknowledge() - * - * @param s the AMQ session that delivered this message - */ - public void setAMQSession(AMQSession s) - { - _session = s; - } - - public AMQSession getAMQSession() - { - return _session; - } - - /** - * Get the AMQ message number assigned to this message - * - * @return the message number - */ - public long getDeliveryTag() - { - return _deliveryTag; - } - - /** Invoked prior to sending the message. Allows the message to be modified if necessary before sending. */ - public void prepareForSending() throws JMSException - { - } - - public FieldTable getPropertyHeaders() - { - return ((BasicContentHeaderProperties) _contentHeaderProperties).getHeaders(); - } - - public void setDecimalProperty(AMQShortString propertyName, BigDecimal bd) throws JMSException - { - getPropertyHeaders().setDecimal(propertyName, bd); - } - - public void setIntProperty(AMQShortString propertyName, int i) throws JMSException - { - getPropertyHeaders().setInteger(propertyName, new Integer(i)); - } - - public void setLongStringProperty(AMQShortString propertyName, String value) - { - getPropertyHeaders().setString(propertyName, value); - } - - public void setTimestampProperty(AMQShortString propertyName, long value) - { - getPropertyHeaders().setTimestamp(propertyName, value); - } - - public void setVoidProperty(AMQShortString propertyName) - { - getPropertyHeaders().setVoid(propertyName); - } - - //** Getters - - public BigDecimal getDecimalProperty(AMQShortString propertyName) throws JMSException - { - return getPropertyHeaders().getDecimal(propertyName); - } - - public int getIntegerProperty(AMQShortString propertyName) throws JMSException - { - return getPropertyHeaders().getInteger(propertyName); - } - - public String getLongStringProperty(AMQShortString propertyName) - { - return getPropertyHeaders().getString(propertyName); - } - - public Long getTimestampProperty(AMQShortString propertyName) - { - return getPropertyHeaders().getTimestamp(propertyName); - } -} diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate.java b/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate.java new file mode 100644 index 0000000000..7f43e4b4b2 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate.java @@ -0,0 +1,138 @@ +/* + * + * 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.qpid.client.message; + +import org.apache.qpid.client.AMQSession; +import org.apache.qpid.framing.BasicContentHeaderProperties; + +import javax.jms.Destination; +import javax.jms.JMSException; +import java.util.Enumeration; +import java.util.UUID; + +public interface AMQMessageDelegate +{ + void acknowledgeThis() throws JMSException; + + String getJMSMessageID() throws JMSException; + + void setJMSMessageID(String string) throws JMSException; + + long getJMSTimestamp() throws JMSException; + + void setJMSTimestamp(long l) throws JMSException; + + byte[] getJMSCorrelationIDAsBytes() throws JMSException; + + void setJMSCorrelationIDAsBytes(byte[] bytes) throws JMSException; + + void setJMSCorrelationID(String string) throws JMSException; + + String getJMSCorrelationID() throws JMSException; + + Destination getJMSReplyTo() throws JMSException; + + void setJMSReplyTo(Destination destination) throws JMSException; + + Destination getJMSDestination() throws JMSException; + + int getJMSDeliveryMode() throws JMSException; + + void setJMSDeliveryMode(int i) throws JMSException; + + String getJMSType() throws JMSException; + + void setJMSType(String string) throws JMSException; + + long getJMSExpiration() throws JMSException; + + void setJMSExpiration(long l) throws JMSException; + + int getJMSPriority() throws JMSException; + + void setJMSPriority(int i) throws JMSException; + + void clearProperties() throws JMSException; + + boolean propertyExists(String string) throws JMSException; + + boolean getBooleanProperty(String string) throws JMSException; + + byte getByteProperty(String string) throws JMSException; + + short getShortProperty(String string) throws JMSException; + + int getIntProperty(String string) throws JMSException; + + long getLongProperty(String string) throws JMSException; + + float getFloatProperty(String string) throws JMSException; + + double getDoubleProperty(String string) throws JMSException; + + String getStringProperty(String string) throws JMSException; + + Object getObjectProperty(String string) throws JMSException; + + Enumeration getPropertyNames() throws JMSException; + + void setBooleanProperty(String string, boolean b) throws JMSException; + + void setByteProperty(String string, byte b) throws JMSException; + + void setShortProperty(String string, short i) throws JMSException; + + void setIntProperty(String string, int i) throws JMSException; + + void setLongProperty(String string, long l) throws JMSException; + + void setFloatProperty(String string, float v) throws JMSException; + + void setDoubleProperty(String string, double v) throws JMSException; + + void setStringProperty(String string, String string1) throws JMSException; + + void setObjectProperty(String string, Object object) throws JMSException; + + void acknowledge() throws JMSException; + + public void setJMSDestination(Destination destination); + + public void setContentType(String contentType); + public String getContentType(); + + public void setEncoding(String encoding); + public String getEncoding(); + + + String getReplyToString(); + + void removeProperty(final String propertyName) throws JMSException; + + void setAMQSession(final AMQSession s); + + AMQSession getAMQSession(); + + long getDeliveryTag(); + + void setJMSMessageID(final UUID messageId) throws JMSException; +} diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegateFactory.java b/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegateFactory.java new file mode 100644 index 0000000000..8c3f2fd08f --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegateFactory.java @@ -0,0 +1,54 @@ +/* + * + * 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.qpid.client.message; + +import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.AMQException; + +public interface AMQMessageDelegateFactory<D extends AMQMessageDelegate> +{ + public static AMQMessageDelegateFactory DEFAULT_FACTORY = null; + + public static AMQMessageDelegateFactory<AMQMessageDelegate_0_8> FACTORY_0_8 = + new AMQMessageDelegateFactory<AMQMessageDelegate_0_8>() + { + public AMQMessageDelegate_0_8 createDelegate() + { + return new AMQMessageDelegate_0_8(); + } + }; + + public static AMQMessageDelegateFactory<AMQMessageDelegate_0_10> FACTORY_0_10 = + new AMQMessageDelegateFactory<AMQMessageDelegate_0_10>() + { + public AMQMessageDelegate_0_10 createDelegate() + { + return new AMQMessageDelegate_0_10(); + } + }; + + + public D createDelegate(); + +} diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java b/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java new file mode 100644 index 0000000000..8b4488f1f9 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java @@ -0,0 +1,973 @@ +/* + * + * 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.qpid.client.message; + +import org.apache.commons.collections.map.ReferenceMap; +import org.apache.qpid.client.*; +import org.apache.qpid.framing.ContentHeaderProperties; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.AMQException; +import org.apache.qpid.AMQPInvalidClassException; +import org.apache.qpid.nclient.*; +import org.apache.qpid.jms.Message; +import org.apache.qpid.url.BindingURL; +import org.apache.qpid.url.AMQBindingURL; +import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.transport.*; + +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.MessageNotWriteableException; +import javax.jms.MessageFormatException; +import javax.jms.DeliveryMode; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import org.apache.qpid.exchange.ExchangeDefaults; + +public class AMQMessageDelegate_0_10 implements AMQMessageDelegate +{ + private static final Map<ReplyTo, Destination> _destinationCache = Collections.synchronizedMap(new ReferenceMap()); + + public static final String JMS_TYPE = "x-jms-type"; + + + private boolean _readableProperties = false; + + private Destination _destination; + + + private MessageProperties _messageProps; + private DeliveryProperties _deliveryProps; + /** If the acknowledge mode is CLIENT_ACKNOWLEDGE the session is required */ + private AMQSession _session; + private final long _deliveryTag; + + private static Map<AMQShortString,Integer> _exchangeTypeMap = new ConcurrentHashMap<AMQShortString, Integer>(); + private static Map<String,Integer> _exchangeTypeStringMap = new ConcurrentHashMap<String, Integer>(); + private static Map<String, Integer> _exchangeTypeToDestinationType = new ConcurrentHashMap<String, Integer>();; + + static + { + _exchangeTypeMap.put(ExchangeDefaults.DIRECT_EXCHANGE_NAME, AMQDestination.QUEUE_TYPE); + _exchangeTypeMap.put(AMQShortString.EMPTY_STRING, AMQDestination.QUEUE_TYPE); + _exchangeTypeMap.put(ExchangeDefaults.TOPIC_EXCHANGE_NAME, AMQDestination.TOPIC_TYPE); + _exchangeTypeMap.put(ExchangeDefaults.FANOUT_EXCHANGE_NAME, AMQDestination.TOPIC_TYPE); + + _exchangeTypeStringMap.put(ExchangeDefaults.DIRECT_EXCHANGE_NAME.toString(), AMQDestination.QUEUE_TYPE); + _exchangeTypeStringMap.put("", AMQDestination.QUEUE_TYPE); + _exchangeTypeStringMap.put(ExchangeDefaults.TOPIC_EXCHANGE_NAME.toString(), AMQDestination.TOPIC_TYPE); + _exchangeTypeStringMap.put(ExchangeDefaults.FANOUT_EXCHANGE_NAME.toString(), AMQDestination.TOPIC_TYPE); + + + _exchangeTypeToDestinationType.put(ExchangeDefaults.DIRECT_EXCHANGE_CLASS.toString(), AMQDestination.QUEUE_TYPE); + _exchangeTypeToDestinationType.put(ExchangeDefaults.TOPIC_EXCHANGE_NAME.toString(), AMQDestination.TOPIC_TYPE); + _exchangeTypeToDestinationType.put(ExchangeDefaults.FANOUT_EXCHANGE_NAME.toString(), AMQDestination.TOPIC_TYPE); + } + + protected AMQMessageDelegate_0_10() + { + this(new MessageProperties(), new DeliveryProperties(), -1); + _readableProperties = false; + } + + protected AMQMessageDelegate_0_10(long deliveryTag, MessageProperties messageProps, DeliveryProperties deliveryProps, AMQShortString exchange, + AMQShortString routingKey) throws AMQException + { + this(messageProps, deliveryProps, deliveryTag); + + + AMQDestination dest; + + dest = generateDestination(exchange, routingKey); + setJMSDestination(dest); + } + + private AMQDestination generateDestination(AMQShortString exchange, AMQShortString routingKey) + { + AMQDestination dest; + switch(getExchangeType(exchange)) + { + case AMQDestination.QUEUE_TYPE: + dest = new AMQQueue(exchange, routingKey, routingKey); + break; + case AMQDestination.TOPIC_TYPE: + dest = new AMQTopic(exchange, routingKey, null); + break; + default: + dest = new AMQUndefinedDestination(exchange, routingKey, null); + + } + + return dest; + } + + private int getExchangeType(AMQShortString exchange) + { + Integer type = _exchangeTypeMap.get(exchange == null ? AMQShortString.EMPTY_STRING : exchange); + + if(type == null) + { + return AMQDestination.UNKNOWN_TYPE; + } + + + return type; + } + + + public static void updateExchangeTypeMapping(Header header, org.apache.qpid.nclient.Session session) + { + DeliveryProperties deliveryProps = header.get(DeliveryProperties.class); + if(deliveryProps != null) + { + String exchange = deliveryProps.getExchange(); + + if(exchange != null && !_exchangeTypeStringMap.containsKey(exchange)) + { + + AMQShortString exchangeShortString = new AMQShortString(exchange); + Future<ExchangeQueryResult> future = + session.exchangeQuery(exchange.toString()); + ExchangeQueryResult res = future.get(); + + Integer type = _exchangeTypeToDestinationType.get(res.getType()); + if(type == null) + { + type = AMQDestination.UNKNOWN_TYPE; + } + _exchangeTypeStringMap.put(exchange, type); + _exchangeTypeMap.put(exchangeShortString, type); + + } + } + } + + protected AMQMessageDelegate_0_10(MessageProperties messageProps, DeliveryProperties deliveryProps, long deliveryTag) + { + _messageProps = messageProps; + _deliveryProps = deliveryProps; + _deliveryTag = deliveryTag; + _readableProperties = (_messageProps != null); + + } + + + public String getJMSMessageID() throws JMSException + { + UUID id = _messageProps.getMessageId(); + return id == null ? null : "ID:" + id; + } + + public void setJMSMessageID(String messageId) throws JMSException + { + if(messageId == null) + { + _messageProps.clearMessageId(); + } + else + { + if(messageId.startsWith("ID:")) + { + try + { + _messageProps.setMessageId(UUID.fromString(messageId.substring(3))); + } + catch(IllegalArgumentException ex) + { + throw new JMSException("MessageId '"+messageId+"' is not of the correct format, it must be ID: followed by a UUID"); + } + } + else + { + throw new JMSException("MessageId '"+messageId+"' is not of the correct format, it must be ID: followed by a UUID"); + } + } + } + + public void setJMSMessageID(UUID messageId) throws JMSException + { + if(messageId == null) + { + _messageProps.clearMessageId(); + } + else + { + _messageProps.setMessageId(messageId); + } + } + + + public long getJMSTimestamp() throws JMSException + { + return _deliveryProps.getTimestamp(); + } + + public void setJMSTimestamp(long timestamp) throws JMSException + { + _deliveryProps.setTimestamp(timestamp); + } + + public byte[] getJMSCorrelationIDAsBytes() throws JMSException + { + return _messageProps.getCorrelationId(); + } + + public void setJMSCorrelationIDAsBytes(byte[] bytes) throws JMSException + { + _messageProps.setCorrelationId(bytes); + } + + public void setJMSCorrelationID(String correlationId) throws JMSException + { + + setJMSCorrelationIDAsBytes(correlationId == null ? null : correlationId.getBytes()); + } + + public String getJMSCorrelationID() throws JMSException + { + + byte[] correlationIDAsBytes = getJMSCorrelationIDAsBytes(); + return correlationIDAsBytes == null ? null : new String(correlationIDAsBytes); + } + + public Destination getJMSReplyTo() + { + ReplyTo replyTo = _messageProps.getReplyTo(); + + if (replyTo == null) + { + return null; + } + else + { + Destination dest = _destinationCache.get(replyTo); + if (dest == null) + { + String exchange = replyTo.getExchange(); + String routingKey = replyTo.getRoutingKey(); + + dest = generateDestination(exchange == null ? null : new AMQShortString(exchange), + routingKey == null ? null : new AMQShortString(routingKey)); + + + + + + _destinationCache.put(replyTo, dest); + } + + return dest; + } + } + + public void setJMSReplyTo(Destination destination) throws JMSException + { + if (destination == null) + { + throw new IllegalArgumentException("Null destination not allowed"); + } + + if (!(destination instanceof AMQDestination)) + { + throw new IllegalArgumentException( + "ReplyTo destination may only be an AMQDestination - passed argument was type " + destination.getClass()); + } + + final AMQDestination amqd = (AMQDestination) destination; + + final ReplyTo replyTo = new ReplyTo(amqd.getExchangeName().toString(), amqd.getRoutingKey().toString()); + _destinationCache.put(replyTo, destination); + _messageProps.setReplyTo(replyTo); + + } + + public Destination getJMSDestination() throws JMSException + { + return _destination; + } + + public void setJMSDestination(Destination destination) + { + _destination = destination; + } + + public void setContentType(String contentType) + { + _messageProps.setContentType(contentType); + } + + public String getContentType() + { + return _messageProps.getContentType(); + } + + public void setEncoding(String encoding) + { + if(encoding == null || encoding.length() == 0) + { + _messageProps.clearContentEncoding(); + } + else + { + _messageProps.setContentEncoding(encoding); + } + } + + public String getEncoding() + { + return _messageProps.getContentEncoding(); + } + + public String getReplyToString() + { + Destination replyTo = getJMSReplyTo(); + if(replyTo != null) + { + return ((AMQDestination)replyTo).toURL(); + } + else + { + return null; + } + + } + + public int getJMSDeliveryMode() throws JMSException + { + + MessageDeliveryMode deliveryMode = _deliveryProps.getDeliveryMode(); + if(deliveryMode != null) + { + switch(deliveryMode) + { + case PERSISTENT : + return DeliveryMode.PERSISTENT; + case NON_PERSISTENT: + return DeliveryMode.NON_PERSISTENT; + default: + throw new JMSException("Unknown Message Delivery Mode: " + _deliveryProps.getDeliveryMode()); + } + } + else + { + return Message.DEFAULT_DELIVERY_MODE; + } + + } + + public void setJMSDeliveryMode(int deliveryMode) throws JMSException + { + switch(deliveryMode) + { + case DeliveryMode.PERSISTENT: + _deliveryProps.setDeliveryMode(MessageDeliveryMode.PERSISTENT); + break; + case DeliveryMode.NON_PERSISTENT: + _deliveryProps.setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT); + break; + default: + throw new JMSException("Unknown JMS Delivery Mode: " + deliveryMode); + } + + } + + + public String getJMSType() throws JMSException + { + if(getApplicationHeaders().containsKey(JMS_TYPE)) + { + return getStringProperty(JMS_TYPE); + } + else + { + return null; + } + } + + private Map<String, Object> getApplicationHeaders() + { + Map<String, Object> map = _messageProps.getApplicationHeaders(); + return map == null ? Collections.EMPTY_MAP : map; + } + + public void setJMSType(String type) throws JMSException + { + Map<String, Object> headers = _messageProps.getApplicationHeaders(); + if(type == null) + { + if(headers != null) + { + headers.remove(JMS_TYPE); + } + } + else + { + if(headers == null) + { + headers = new HashMap<String,Object>(); + _messageProps.setApplicationHeaders(headers); + + } + headers.put(JMS_TYPE, type); + } + } + + public long getJMSExpiration() throws JMSException + { + return _deliveryProps.getExpiration(); + } + + public void setJMSExpiration(long l) throws JMSException + { + _deliveryProps.setExpiration(l); + } + + + + public boolean propertyExists(String propertyName) throws JMSException + { + return getApplicationHeaders().containsKey(propertyName); + } + + public boolean getBooleanProperty(String propertyName) throws JMSException + { + checkPropertyName(propertyName); + + Object o = getApplicationHeaders().get(propertyName); + + if(o instanceof Boolean) + { + return ((Boolean)o).booleanValue(); + } + else if(o instanceof String) + { + return Boolean.valueOf((String) o).booleanValue(); + } + else if(getApplicationHeaders().containsKey(propertyName)) + { + throw new MessageFormatException("getBooleanProperty(\""+propertyName+"\") failed as value is not boolean: " + o); + } + else + { + return Boolean.valueOf(null); + } + } + + public byte getByteProperty(String propertyName) throws JMSException + { + checkPropertyName(propertyName); + + Map<String, Object> propertyMap = getApplicationHeaders(); + + Object o = propertyMap.get(propertyName); + + if(o instanceof Byte) + { + return ((Byte)o).byteValue(); + } + else if(o instanceof String) + { + return Byte.valueOf((String) o).byteValue(); + } + else if(getApplicationHeaders().containsKey(propertyName)) + { + throw new MessageFormatException("getByteProperty(\""+propertyName+"\") failed as value is not a byte: " + o); + } + else + { + return Byte.valueOf(null); + } + } + + public short getShortProperty(String propertyName) throws JMSException + { + checkPropertyName(propertyName); + + Map<String, Object> propertyMap = getApplicationHeaders(); + + Object o = propertyMap.get(propertyName); + + if(o instanceof Short) + { + return ((Short)o).shortValue(); + } + else + { + try + { + return Short.valueOf(getByteProperty(propertyName)); + } + catch(MessageFormatException e) + { + throw new MessageFormatException("getShortProperty(\""+propertyName+"\") failed as value is not a short: " + o); + } + } + + + } + + public int getIntProperty(String propertyName) throws JMSException + { + checkPropertyName(propertyName); + + Map<String, Object> propertyMap = getApplicationHeaders(); + + Object o = propertyMap.get(propertyName); + + if(o instanceof Integer) + { + return ((Integer)o).intValue(); + } + else + { + try + { + return Integer.valueOf(getShortProperty(propertyName)); + } + catch(MessageFormatException e) + { + throw new MessageFormatException("getIntProperty(\""+propertyName+"\") failed as value is not an int: " + o); + } + + } + } + + public long getLongProperty(String propertyName) throws JMSException + { + checkPropertyName(propertyName); + + Map<String, Object> propertyMap = getApplicationHeaders(); + + Object o = propertyMap.get(propertyName); + + if(o instanceof Long) + { + return ((Long)o).longValue(); + } + else + { + try + { + return Long.valueOf(getIntProperty(propertyName)); + } + catch(MessageFormatException e) + { + throw new MessageFormatException("getLongProperty(\""+propertyName+"\") failed as value is not a long: " + o); + } + + } + } + + public float getFloatProperty(String propertyName) throws JMSException + { + checkPropertyName(propertyName); + Map<String, Object> propertyMap = getApplicationHeaders(); + + Object o = propertyMap.get(propertyName); + + if(o instanceof Float) + { + return ((Float)o).floatValue(); + } + else if(o instanceof String) + { + return Float.valueOf((String) o).floatValue(); + } + else if(getApplicationHeaders().containsKey(propertyName)) + { + throw new MessageFormatException("getFloatProperty(\""+propertyName+"\") failed as value is not a float: " + o); + } + else + { + return Float.valueOf(null); + } + + } + + public double getDoubleProperty(String propertyName) throws JMSException + { + checkPropertyName(propertyName); + + Map<String, Object> propertyMap = getApplicationHeaders(); + + Object o = propertyMap.get(propertyName); + + if(o instanceof Double) + { + return ((Double)o).doubleValue(); + } + else + { + try + { + return Double.valueOf(getFloatProperty(propertyName)); + } + catch(MessageFormatException e) + { + throw new MessageFormatException("getDoubleProperty(\""+propertyName+"\") failed as value is not a double: " + o); + } + + } + } + + public String getStringProperty(String propertyName) throws JMSException + { + if (propertyName.equals(CustomJMSXProperty.JMSXUserID.toString())) + { + return new String(_messageProps.getUserId()); + } + else + { + checkPropertyName(propertyName); + Map<String, Object> propertyMap = getApplicationHeaders(); + + Object o = propertyMap.get(propertyName); + + if(o instanceof String) + { + return (String) o; + } + else if(o == null) + { + return null; + } + else if(o.getClass().isArray()) + { + throw new MessageFormatException("getString(\""+propertyName+"\") failed as value of type " + o.getClass()+ " is an array."); + } + else + { + return String.valueOf(o); + } + + } + } + + public Object getObjectProperty(String propertyName) throws JMSException + { + checkPropertyName(propertyName); + Map<String, Object> propertyMap = getApplicationHeaders(); + + return propertyMap.get(propertyName); + + } + + public Enumeration getPropertyNames() throws JMSException + { + return java.util.Collections.enumeration(getApplicationHeaders().keySet()); + } + + public void setBooleanProperty(String propertyName, boolean b) throws JMSException + { + checkPropertyName(propertyName); + checkWritableProperties(); + setApplicationHeader(propertyName, b); + } + + public void setByteProperty(String propertyName, byte b) throws JMSException + { + checkPropertyName(propertyName); + checkWritableProperties(); + setApplicationHeader(propertyName, b); + } + + public void setShortProperty(String propertyName, short i) throws JMSException + { + checkPropertyName(propertyName); + checkWritableProperties(); + setApplicationHeader(propertyName, i); + } + + public void setIntProperty(String propertyName, int i) throws JMSException + { + checkPropertyName(propertyName); + checkWritableProperties(); + setApplicationHeader(propertyName, i); + } + + public void setLongProperty(String propertyName, long l) throws JMSException + { + checkPropertyName(propertyName); + checkWritableProperties(); + setApplicationHeader(propertyName, l); + } + + public void setFloatProperty(String propertyName, float f) throws JMSException + { + checkPropertyName(propertyName); + checkWritableProperties(); + setApplicationHeader(propertyName, f); + } + + public void setDoubleProperty(String propertyName, double v) throws JMSException + { + checkPropertyName(propertyName); + checkWritableProperties(); + setApplicationHeader(propertyName, v); + } + + public void setStringProperty(String propertyName, String value) throws JMSException + { + checkPropertyName(propertyName); + checkWritableProperties(); + setApplicationHeader(propertyName, value); + } + + private static final Set<Class> ALLOWED = new HashSet(); + static + { + ALLOWED.add(Boolean.class); + ALLOWED.add(Byte.class); + ALLOWED.add(Short.class); + ALLOWED.add(Integer.class); + ALLOWED.add(Long.class); + ALLOWED.add(Float.class); + ALLOWED.add(Double.class); + ALLOWED.add(Character.class); + ALLOWED.add(String.class); + ALLOWED.add(byte[].class); + } + + public void setObjectProperty(String propertyName, Object object) throws JMSException + { + checkPropertyName(propertyName); + checkWritableProperties(); + if (object != null && !ALLOWED.contains(object.getClass())) + { + throw new MessageFormatException + (String.format + ("Cannot set a %s, allowed property types are: %s", + object.getClass(), ALLOWED)); + } + setApplicationHeader(propertyName, object); + } + + private void setApplicationHeader(String propertyName, Object object) + { + Map<String, Object> headers = _messageProps.getApplicationHeaders(); + if(headers == null) + { + headers = new HashMap<String,Object>(); + _messageProps.setApplicationHeaders(headers); + } + headers.put(propertyName, object); + } + + public void removeProperty(String propertyName) throws JMSException + { + Map<String, Object> headers = _messageProps.getApplicationHeaders(); + if(headers != null) + { + headers.remove(propertyName); + } + } + + + + protected void checkWritableProperties() throws MessageNotWriteableException + { + if (_readableProperties) + { + throw new MessageNotWriteableException("You need to call clearProperties() to make the message writable"); + } + } + + + public int getJMSPriority() throws JMSException + { + MessageDeliveryPriority messageDeliveryPriority = _deliveryProps.getPriority(); + return messageDeliveryPriority == null ? Message.DEFAULT_PRIORITY : messageDeliveryPriority.getValue(); + } + + public void setJMSPriority(int i) throws JMSException + { + _deliveryProps.setPriority(MessageDeliveryPriority.get((short)i)); + } + + public void clearProperties() throws JMSException + { + if(!getApplicationHeaders().isEmpty()) + { + getApplicationHeaders().clear(); + } + + _readableProperties = false; + } + + + public void acknowledgeThis() throws JMSException + { + // the JMS 1.1 spec says in section 3.6 that calls to acknowledge are ignored when client acknowledge + // is not specified. In our case, we only set the session field where client acknowledge mode is specified. + if (_session != null) + { + if (_session.getAMQConnection().isClosed()) + { + throw new javax.jms.IllegalStateException("Connection is already closed"); + } + + // we set multiple to true here since acknowledgement implies acknowledge of all previous messages + // received on the session + _session.acknowledgeMessage(_deliveryTag, true); + } + } + + public void acknowledge() throws JMSException + { + if (_session != null) + { + _session.acknowledge(); + } + } + + + /** + * The session is set when CLIENT_ACKNOWLEDGE mode is used so that the CHANNEL ACK can be sent when the user calls + * acknowledge() + * + * @param s the AMQ session that delivered this message + */ + public void setAMQSession(AMQSession s) + { + _session = s; + } + + public AMQSession getAMQSession() + { + return _session; + } + + /** + * Get the AMQ message number assigned to this message + * + * @return the message number + */ + public long getDeliveryTag() + { + return _deliveryTag; + } + + + + + + + protected void checkPropertyName(CharSequence propertyName) + { + if (propertyName == null) + { + throw new IllegalArgumentException("Property name must not be null"); + } + else if (propertyName.length() == 0) + { + throw new IllegalArgumentException("Property name must not be the empty string"); + } + + checkIdentiferFormat(propertyName); + } + + protected void checkIdentiferFormat(CharSequence propertyName) + { +// JMS requirements 3.5.1 Property Names +// Identifiers: +// - An identifier is an unlimited-length character sequence that must begin +// with a Java identifier start character; all following characters must be Java +// identifier part characters. An identifier start character is any character for +// which the method Character.isJavaIdentifierStart returns true. This includes +// '_' and '$'. An identifier part character is any character for which the +// method Character.isJavaIdentifierPart returns true. +// - Identifiers cannot be the names NULL, TRUE, or FALSE. +// Identifiers cannot be NOT, AND, OR, BETWEEN, LIKE, IN, IS, or +// ESCAPE. +// Identifiers are either header field references or property references. The +// type of a property value in a message selector corresponds to the type +// used to set the property. If a property that does not exist in a message is +// referenced, its value is NULL. The semantics of evaluating NULL values +// in a selector are described in Section 3.8.1.2, Null Values. +// The conversions that apply to the get methods for properties do not +// apply when a property is used in a message selector expression. For +// example, suppose you set a property as a string value, as in the +// following: +// myMessage.setStringProperty("NumberOfOrders", "2"); +// The following expression in a message selector would evaluate to false, +// because a string cannot be used in an arithmetic expression: +// "NumberOfOrders > 1" +// Identifiers are case sensitive. +// Message header field references are restricted to JMSDeliveryMode, +// JMSPriority, JMSMessageID, JMSTimestamp, JMSCorrelationID, and +// JMSType. JMSMessageID, JMSCorrelationID, and JMSType values may be +// null and if so are treated as a NULL value. + + if (Boolean.getBoolean("strict-jms")) + { + // JMS start character + if (!(Character.isJavaIdentifierStart(propertyName.charAt(0)))) + { + throw new IllegalArgumentException("Identifier '" + propertyName + "' does not start with a valid JMS identifier start character"); + } + + // JMS part character + int length = propertyName.length(); + for (int c = 1; c < length; c++) + { + if (!(Character.isJavaIdentifierPart(propertyName.charAt(c)))) + { + throw new IllegalArgumentException("Identifier '" + propertyName + "' contains an invalid JMS identifier character"); + } + } + + // JMS invalid names + if ((propertyName.equals("NULL") + || propertyName.equals("TRUE") + || propertyName.equals("FALSE") + || propertyName.equals("NOT") + || propertyName.equals("AND") + || propertyName.equals("OR") + || propertyName.equals("BETWEEN") + || propertyName.equals("LIKE") + || propertyName.equals("IN") + || propertyName.equals("IS") + || propertyName.equals("ESCAPE"))) + { + throw new IllegalArgumentException("Identifier '" + propertyName + "' is not allowed in JMS"); + } + } + + } + + + public MessageProperties getMessageProperties() + { + return _messageProps; + } + + + public DeliveryProperties getDeliveryProperties() + { + return _deliveryProps; + } + +} diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_8.java b/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_8.java new file mode 100644 index 0000000000..4c20a44849 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_8.java @@ -0,0 +1,567 @@ +/* + * + * 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.qpid.client.message; + +import org.apache.commons.collections.map.ReferenceMap; +import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.client.AMQSession; +import org.apache.qpid.client.CustomJMSXProperty; +import org.apache.qpid.client.AMQDestination; +import org.apache.qpid.client.AMQQueue; +import org.apache.qpid.client.AMQTopic; +import org.apache.qpid.client.AMQUndefinedDestination; +import org.apache.qpid.client.JMSAMQException; +import org.apache.qpid.framing.ContentHeaderProperties; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.AMQException; +import org.apache.qpid.url.BindingURL; +import org.apache.qpid.url.AMQBindingURL; + +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.MessageNotWriteableException; +import java.util.Map; +import java.util.Collections; +import java.util.Enumeration; +import java.util.UUID; +import java.net.URISyntaxException; + +public class AMQMessageDelegate_0_8 implements AMQMessageDelegate +{ + private static final Map _destinationCache = Collections.synchronizedMap(new ReferenceMap()); + + public static final String JMS_TYPE = "x-jms-type"; + + + private boolean _readableProperties = false; + + private Destination _destination; + private JMSHeaderAdapter _headerAdapter; + private static final boolean STRICT_AMQP_COMPLIANCE = + Boolean.parseBoolean(System.getProperties().getProperty(AMQSession.STRICT_AMQP, AMQSession.STRICT_AMQP_DEFAULT)); + + private ContentHeaderProperties _contentHeaderProperties; + /** If the acknowledge mode is CLIENT_ACKNOWLEDGE the session is required */ + private AMQSession _session; + private final long _deliveryTag; + + protected AMQMessageDelegate_0_8() + { + this(new BasicContentHeaderProperties(), -1); + _readableProperties = false; + _headerAdapter = new JMSHeaderAdapter(((BasicContentHeaderProperties) _contentHeaderProperties).getHeaders()); + + } + + protected AMQMessageDelegate_0_8(long deliveryTag, BasicContentHeaderProperties contentHeader, AMQShortString exchange, + AMQShortString routingKey) + { + this(contentHeader, deliveryTag); + + Integer type = contentHeader.getHeaders().getInteger(CustomJMSXProperty.JMS_QPID_DESTTYPE.getShortStringName()); + + if(type == null) + { + type = AMQDestination.UNKNOWN_TYPE; + } + + AMQDestination dest; + + switch(type.intValue()) + { + case AMQDestination.QUEUE_TYPE: + dest = new AMQQueue(exchange, routingKey, routingKey); + break; + case AMQDestination.TOPIC_TYPE: + dest = new AMQTopic(exchange, routingKey, null); + break; + default: + dest = new AMQUndefinedDestination(exchange, routingKey, null); + } + + + + // Destination dest = AMQDestination.createDestination(url); + setJMSDestination(dest); + + + + } + + protected AMQMessageDelegate_0_8(BasicContentHeaderProperties properties, long deliveryTag) + { + _contentHeaderProperties = properties; + _deliveryTag = deliveryTag; + _readableProperties = (_contentHeaderProperties != null); + _headerAdapter = new JMSHeaderAdapter(((BasicContentHeaderProperties) _contentHeaderProperties).getHeaders()); + } + + + public String getJMSMessageID() throws JMSException + { + return getContentHeaderProperties().getMessageIdAsString(); + } + + public void setJMSMessageID(String messageId) throws JMSException + { + getContentHeaderProperties().setMessageId(messageId); + } + + public void setJMSMessageID(UUID messageId) throws JMSException + { + getContentHeaderProperties().setMessageId("ID:" + messageId); + } + + + public long getJMSTimestamp() throws JMSException + { + return getContentHeaderProperties().getTimestamp(); + } + + public void setJMSTimestamp(long timestamp) throws JMSException + { + getContentHeaderProperties().setTimestamp(timestamp); + } + + public byte[] getJMSCorrelationIDAsBytes() throws JMSException + { + return getContentHeaderProperties().getCorrelationIdAsString().getBytes(); + } + + public void setJMSCorrelationIDAsBytes(byte[] bytes) throws JMSException + { + getContentHeaderProperties().setCorrelationId(new String(bytes)); + } + + public void setJMSCorrelationID(String correlationId) throws JMSException + { + getContentHeaderProperties().setCorrelationId(correlationId); + } + + public String getJMSCorrelationID() throws JMSException + { + return getContentHeaderProperties().getCorrelationIdAsString(); + } + + public Destination getJMSReplyTo() throws JMSException + { + String replyToEncoding = getContentHeaderProperties().getReplyToAsString(); + if (replyToEncoding == null) + { + return null; + } + else + { + Destination dest = (Destination) _destinationCache.get(replyToEncoding); + if (dest == null) + { + try + { + BindingURL binding = new AMQBindingURL(replyToEncoding); + dest = AMQDestination.createDestination(binding); + } + catch (URISyntaxException e) + { + throw new JMSAMQException("Illegal value in JMS_ReplyTo property: " + replyToEncoding, e); + } + + _destinationCache.put(replyToEncoding, dest); + } + + return dest; + } + } + + public void setJMSReplyTo(Destination destination) throws JMSException + { + if (destination == null) + { + throw new IllegalArgumentException("Null destination not allowed"); + } + + if (!(destination instanceof AMQDestination)) + { + throw new IllegalArgumentException( + "ReplyTo destination may only be an AMQDestination - passed argument was type " + destination.getClass()); + } + + final AMQDestination amqd = (AMQDestination) destination; + + final AMQShortString encodedDestination = amqd.getEncodedName(); + _destinationCache.put(encodedDestination, destination); + getContentHeaderProperties().setReplyTo(encodedDestination); + } + + public Destination getJMSDestination() throws JMSException + { + return _destination; + } + + public void setJMSDestination(Destination destination) + { + _destination = destination; + } + + public void setContentType(String contentType) + { + getContentHeaderProperties().setContentType(contentType); + } + + public String getContentType() + { + return getContentHeaderProperties().getContentTypeAsString(); + } + + public void setEncoding(String encoding) + { + getContentHeaderProperties().setEncoding(encoding); + } + + public String getEncoding() + { + return getContentHeaderProperties().getEncodingAsString(); + } + + public String getReplyToString() + { + return getContentHeaderProperties().getReplyToAsString(); + } + + public int getJMSDeliveryMode() throws JMSException + { + return getContentHeaderProperties().getDeliveryMode(); + } + + public void setJMSDeliveryMode(int i) throws JMSException + { + getContentHeaderProperties().setDeliveryMode((byte) i); + } + + public BasicContentHeaderProperties getContentHeaderProperties() + { + return (BasicContentHeaderProperties) _contentHeaderProperties; + } + + + public String getJMSType() throws JMSException + { + return getContentHeaderProperties().getTypeAsString(); + } + + public void setJMSType(String string) throws JMSException + { + getContentHeaderProperties().setType(string); + } + + public long getJMSExpiration() throws JMSException + { + return getContentHeaderProperties().getExpiration(); + } + + public void setJMSExpiration(long l) throws JMSException + { + getContentHeaderProperties().setExpiration(l); + } + + + + public boolean propertyExists(String propertyName) throws JMSException + { + return getJmsHeaders().propertyExists(propertyName); + } + + public boolean getBooleanProperty(String propertyName) throws JMSException + { + if (STRICT_AMQP_COMPLIANCE) + { + throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); + } + + return getJmsHeaders().getBoolean(propertyName); + } + + public byte getByteProperty(String propertyName) throws JMSException + { + if (STRICT_AMQP_COMPLIANCE) + { + throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); + } + + return getJmsHeaders().getByte(propertyName); + } + + public short getShortProperty(String propertyName) throws JMSException + { + if (STRICT_AMQP_COMPLIANCE) + { + throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); + } + + return getJmsHeaders().getShort(propertyName); + } + + public int getIntProperty(String propertyName) throws JMSException + { + if (STRICT_AMQP_COMPLIANCE) + { + throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); + } + + return getJmsHeaders().getInteger(propertyName); + } + + public long getLongProperty(String propertyName) throws JMSException + { + if (STRICT_AMQP_COMPLIANCE) + { + throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); + } + + return getJmsHeaders().getLong(propertyName); + } + + public float getFloatProperty(String propertyName) throws JMSException + { + if (STRICT_AMQP_COMPLIANCE) + { + throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); + } + + return getJmsHeaders().getFloat(propertyName); + } + + public double getDoubleProperty(String propertyName) throws JMSException + { + if (STRICT_AMQP_COMPLIANCE) + { + throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); + } + + return getJmsHeaders().getDouble(propertyName); + } + + public String getStringProperty(String propertyName) throws JMSException + { + //NOTE: if the JMSX Property is a non AMQP property then we must check _strictAMQP and throw as below. + if (propertyName.equals(CustomJMSXProperty.JMSXUserID.toString())) + { + return ((BasicContentHeaderProperties) _contentHeaderProperties).getUserIdAsString(); + } + else + { + if (STRICT_AMQP_COMPLIANCE) + { + throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); + } + + return getJmsHeaders().getString(propertyName); + } + } + + public Object getObjectProperty(String propertyName) throws JMSException + { + return getJmsHeaders().getObject(propertyName); + } + + public Enumeration getPropertyNames() throws JMSException + { + return getJmsHeaders().getPropertyNames(); + } + + public void setBooleanProperty(String propertyName, boolean b) throws JMSException + { + if (STRICT_AMQP_COMPLIANCE) + { + throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); + } + + checkWritableProperties(); + getJmsHeaders().setBoolean(propertyName, b); + } + + public void setByteProperty(String propertyName, byte b) throws JMSException + { + if (STRICT_AMQP_COMPLIANCE) + { + throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); + } + + checkWritableProperties(); + getJmsHeaders().setByte(propertyName, new Byte(b)); + } + + public void setShortProperty(String propertyName, short i) throws JMSException + { + if (STRICT_AMQP_COMPLIANCE) + { + throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); + } + + checkWritableProperties(); + getJmsHeaders().setShort(propertyName, new Short(i)); + } + + public void setIntProperty(String propertyName, int i) throws JMSException + { + checkWritableProperties(); + getJmsHeaders().setInteger(propertyName, new Integer(i)); + } + + public void setLongProperty(String propertyName, long l) throws JMSException + { + if (STRICT_AMQP_COMPLIANCE) + { + throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); + } + + checkWritableProperties(); + getJmsHeaders().setLong(propertyName, new Long(l)); + } + + public void setFloatProperty(String propertyName, float f) throws JMSException + { + if (STRICT_AMQP_COMPLIANCE) + { + throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); + } + + checkWritableProperties(); + getJmsHeaders().setFloat(propertyName, new Float(f)); + } + + public void setDoubleProperty(String propertyName, double v) throws JMSException + { + if (STRICT_AMQP_COMPLIANCE) + { + throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); + } + + checkWritableProperties(); + getJmsHeaders().setDouble(propertyName, new Double(v)); + } + + public void setStringProperty(String propertyName, String value) throws JMSException + { + checkWritableProperties(); + getJmsHeaders().setString(propertyName, value); + } + + public void setObjectProperty(String propertyName, Object object) throws JMSException + { + checkWritableProperties(); + getJmsHeaders().setObject(propertyName, object); + } + + public void removeProperty(String propertyName) throws JMSException + { + getJmsHeaders().remove(propertyName); + } + + + private JMSHeaderAdapter getJmsHeaders() + { + return _headerAdapter; + } + + protected void checkWritableProperties() throws MessageNotWriteableException + { + if (_readableProperties) + { + throw new MessageNotWriteableException("You need to call clearProperties() to make the message writable"); + } + _contentHeaderProperties.updated(); + } + + + public int getJMSPriority() throws JMSException + { + return getContentHeaderProperties().getPriority(); + } + + public void setJMSPriority(int i) throws JMSException + { + getContentHeaderProperties().setPriority((byte) i); + } + + public void clearProperties() throws JMSException + { + getJmsHeaders().clear(); + + _readableProperties = false; + } + + + public void acknowledgeThis() throws JMSException + { + // the JMS 1.1 spec says in section 3.6 that calls to acknowledge are ignored when client acknowledge + // is not specified. In our case, we only set the session field where client acknowledge mode is specified. + if (_session != null) + { + if (_session.getAMQConnection().isClosed()) + { + throw new javax.jms.IllegalStateException("Connection is already closed"); + } + + // we set multiple to true here since acknowledgement implies acknowledge of all previous messages + // received on the session + _session.acknowledgeMessage(_deliveryTag, true); + } + } + + public void acknowledge() throws JMSException + { + if (_session != null) + { + _session.acknowledge(); + } + } + + + /** + * The session is set when CLIENT_ACKNOWLEDGE mode is used so that the CHANNEL ACK can be sent when the user calls + * acknowledge() + * + * @param s the AMQ session that delivered this message + */ + public void setAMQSession(AMQSession s) + { + _session = s; + } + + public AMQSession getAMQSession() + { + return _session; + } + + /** + * Get the AMQ message number assigned to this message + * + * @return the message number + */ + public long getDeliveryTag() + { + return _deliveryTag; + } + + +} diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java index 94be090cf2..c0d51fa726 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java @@ -31,7 +31,6 @@ import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.ContentHeaderBody; /** * @author Apache Software Foundation @@ -44,21 +43,21 @@ public abstract class AbstractBytesMessage extends AbstractJMSMessage */ private static final int DEFAULT_BUFFER_INITIAL_SIZE = 1024; - AbstractBytesMessage() + AbstractBytesMessage(AMQMessageDelegateFactory delegateFactory) { - this(null); + this(delegateFactory, null); } /** * Construct a bytes message with existing data. * + * @param delegateFactory * @param data the data that comprises this message. If data is null, you get a 1024 byte buffer that is - * set to auto expand */ - AbstractBytesMessage(ByteBuffer data) + AbstractBytesMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data) { - super(data); // this instanties a content header - getContentHeaderProperties().setContentType(getMimeTypeAsShortString()); + super(delegateFactory, data); // this instanties a content header + setContentType(getMimeType()); if (_data == null) { @@ -72,13 +71,12 @@ public abstract class AbstractBytesMessage extends AbstractJMSMessage _data.setAutoExpand(true); } - AbstractBytesMessage(long messageNbr, BasicContentHeaderProperties contentHeader, AMQShortString exchange, - AMQShortString routingKey, ByteBuffer data) throws AMQException - { - // TODO: this casting is ugly. Need to review whole ContentHeaderBody idea - super(messageNbr, contentHeader, exchange, routingKey, data); - getContentHeaderProperties().setContentType(getMimeTypeAsShortString()); - } + AbstractBytesMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException + { + super(delegate, data); + setContentType(getMimeType()); + } + public void clearBodyImpl() throws JMSException { diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesTypedMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesTypedMessage.java index 9bdde01bf3..f0fc394b0b 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesTypedMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesTypedMessage.java @@ -33,7 +33,6 @@ import javax.jms.MessageNotWriteableException; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.BasicContentHeaderProperties; /** @@ -70,27 +69,28 @@ public abstract class AbstractBytesTypedMessage extends AbstractBytesMessage */ private int _byteArrayRemaining = -1; - AbstractBytesTypedMessage() + AbstractBytesTypedMessage(AMQMessageDelegateFactory delegateFactory) { - this(null); + + this(delegateFactory, null); } /** * Construct a stream message with existing data. * + * @param delegateFactory * @param data the data that comprises this message. If data is null, you get a 1024 byte buffer that is - * set to auto expand */ - AbstractBytesTypedMessage(ByteBuffer data) + AbstractBytesTypedMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data) { - super(data); // this instanties a content header - } + super(delegateFactory, data); // this instanties a content header + } - AbstractBytesTypedMessage(long messageNbr, BasicContentHeaderProperties contentHeader, AMQShortString exchange, - AMQShortString routingKey, ByteBuffer data) throws AMQException + AbstractBytesTypedMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException { - super(messageNbr, contentHeader, exchange, routingKey, data); + + super(delegate, data); } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java index ab284116af..0700ce5d23 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java @@ -21,10 +21,7 @@ package org.apache.qpid.client.message; import java.io.IOException; -import java.net.URISyntaxException; -import java.util.Collections; import java.util.Enumeration; -import java.util.Map; import java.util.UUID; import javax.jms.Destination; @@ -32,122 +29,48 @@ import javax.jms.JMSException; import javax.jms.MessageNotReadableException; import javax.jms.MessageNotWriteableException; -import org.apache.commons.collections.map.ReferenceMap; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; -import org.apache.qpid.client.AMQDestination; -import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.client.AMQUndefinedDestination; -import org.apache.qpid.client.BasicMessageConsumer; -import org.apache.qpid.client.CustomJMSXProperty; -import org.apache.qpid.client.JMSAMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.url.AMQBindingURL; -import org.apache.qpid.url.BindingURL; -public abstract class AbstractJMSMessage extends AMQMessage implements org.apache.qpid.jms.Message +public abstract class AbstractJMSMessage implements org.apache.qpid.jms.Message { - private static final Map _destinationCache = Collections.synchronizedMap(new ReferenceMap()); - public static final String JMS_TYPE = "x-jms-type"; - protected boolean _redelivered; protected ByteBuffer _data; - private boolean _readableProperties = false; protected boolean _readableMessage = false; protected boolean _changedData = true; - private Destination _destination; - private JMSHeaderAdapter _headerAdapter; - private static final boolean STRICT_AMQP_COMPLIANCE = - Boolean.parseBoolean(System.getProperties().getProperty(AMQSession.STRICT_AMQP, AMQSession.STRICT_AMQP_DEFAULT)); - /** - * This is 0_10 specific - */ - private org.apache.qpidity.api.Message _010message = null; + /** If the acknowledge mode is CLIENT_ACKNOWLEDGE the session is required */ - public void set010Message(org.apache.qpidity.api.Message m ) - { - _010message = m; - } - - public void dataChanged() - { - if (_010message != null) - { - _010message.clearData(); - try - { - if (_data != null) - { - _010message.appendData(_data.buf().slice()); - } - else - { - _010message.appendData(java.nio.ByteBuffer.allocate(0)); - } - } - catch (IOException e) - { - throw new RuntimeException(e); - } - } - } - /** - * End 010 specific - */ - public org.apache.qpidity.api.Message get010Message() - { - return _010message; - } + private AMQMessageDelegate _delegate; + private boolean _redelivered; - protected AbstractJMSMessage(ByteBuffer data) + protected AbstractJMSMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data) { - super(new BasicContentHeaderProperties()); + _delegate = delegateFactory.createDelegate(); _data = data; if (_data != null) { _data.acquire(); } - _readableProperties = false; + _readableMessage = (data != null); _changedData = (data == null); - _headerAdapter = new JMSHeaderAdapter(((BasicContentHeaderProperties) _contentHeaderProperties).getHeaders()); } - protected AbstractJMSMessage(long deliveryTag, BasicContentHeaderProperties contentHeader, AMQShortString exchange, - AMQShortString routingKey, ByteBuffer data) throws AMQException + protected AbstractJMSMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException { - this(contentHeader, deliveryTag); - - Integer type = contentHeader.getHeaders().getInteger(CustomJMSXProperty.JMS_QPID_DESTTYPE.getShortStringName()); - AMQDestination dest; - - if (AMQDestination.QUEUE_TYPE.equals(type)) - { - dest = new AMQQueue(exchange, routingKey, routingKey); - } - else if (AMQDestination.TOPIC_TYPE.equals(type)) - { - dest = new AMQTopic(exchange, routingKey, null); - } - else - { - dest = new AMQUndefinedDestination(exchange, routingKey, null); - } - // Destination dest = AMQDestination.createDestination(url); - setJMSDestination(dest); + _delegate = delegate; _data = data; if (_data != null) @@ -159,126 +82,82 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach } - protected AbstractJMSMessage(BasicContentHeaderProperties contentHeader, long deliveryTag) + public String getJMSMessageID() throws JMSException { - super(contentHeader, deliveryTag); - _readableProperties = (_contentHeaderProperties != null); - _headerAdapter = new JMSHeaderAdapter(((BasicContentHeaderProperties) _contentHeaderProperties).getHeaders()); + return _delegate.getJMSMessageID(); } - public String getJMSMessageID() throws JMSException + public void setJMSMessageID(String messageId) throws JMSException { - return getContentHeaderProperties().getMessageIdAsString(); + _delegate.setJMSMessageID(messageId); } - public void setJMSMessageID(String messageId) throws JMSException + public void setJMSMessageID(UUID messageId) throws JMSException { - getContentHeaderProperties().setMessageId(messageId); + _delegate.setJMSMessageID(messageId); } + public long getJMSTimestamp() throws JMSException { - return getContentHeaderProperties().getTimestamp(); + return _delegate.getJMSTimestamp(); } public void setJMSTimestamp(long timestamp) throws JMSException { - getContentHeaderProperties().setTimestamp(timestamp); + _delegate.setJMSTimestamp(timestamp); } public byte[] getJMSCorrelationIDAsBytes() throws JMSException { - return getContentHeaderProperties().getCorrelationIdAsString().getBytes(); + return _delegate.getJMSCorrelationIDAsBytes(); } public void setJMSCorrelationIDAsBytes(byte[] bytes) throws JMSException { - getContentHeaderProperties().setCorrelationId(new String(bytes)); + _delegate.setJMSCorrelationIDAsBytes(bytes); } public void setJMSCorrelationID(String correlationId) throws JMSException { - getContentHeaderProperties().setCorrelationId(correlationId); + _delegate.setJMSCorrelationID(correlationId); } public String getJMSCorrelationID() throws JMSException { - return getContentHeaderProperties().getCorrelationIdAsString(); + return _delegate.getJMSCorrelationID(); } public Destination getJMSReplyTo() throws JMSException { - String replyToEncoding = getContentHeaderProperties().getReplyToAsString(); - if (replyToEncoding == null) - { - return null; - } - else - { - Destination dest = (Destination) _destinationCache.get(replyToEncoding); - if (dest == null) - { - try - { - BindingURL binding = new AMQBindingURL(replyToEncoding); - dest = AMQDestination.createDestination(binding); - } - catch (URISyntaxException e) - { - throw new JMSAMQException("Illegal value in JMS_ReplyTo property: " + replyToEncoding, e); - } - - _destinationCache.put(replyToEncoding, dest); - } - - return dest; - } + return _delegate.getJMSReplyTo(); } public void setJMSReplyTo(Destination destination) throws JMSException { - if (destination == null) - { - throw new IllegalArgumentException("Null destination not allowed"); - } - - if (!(destination instanceof AMQDestination)) - { - throw new IllegalArgumentException( - "ReplyTo destination may only be an AMQDestination - passed argument was type " + destination.getClass()); - } - - final AMQDestination amqd = (AMQDestination) destination; - - final AMQShortString encodedDestination = amqd.getEncodedName(); - _destinationCache.put(encodedDestination, destination); - getContentHeaderProperties().setReplyTo(encodedDestination); + _delegate.setJMSReplyTo(destination); } public Destination getJMSDestination() throws JMSException { - return _destination; + return _delegate.getJMSDestination(); } public void setJMSDestination(Destination destination) { - _destination = destination; + _delegate.setJMSDestination(destination); } public int getJMSDeliveryMode() throws JMSException { - return getContentHeaderProperties().getDeliveryMode(); + return _delegate.getJMSDeliveryMode(); } public void setJMSDeliveryMode(int i) throws JMSException { - getContentHeaderProperties().setDeliveryMode((byte) i); + _delegate.setJMSDeliveryMode(i); } - public BasicContentHeaderProperties getContentHeaderProperties() - { - return (BasicContentHeaderProperties) _contentHeaderProperties; - } public boolean getJMSRedelivered() throws JMSException { @@ -290,318 +169,180 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach _redelivered = b; } + public String getJMSType() throws JMSException { - return getContentHeaderProperties().getTypeAsString(); + return _delegate.getJMSType(); } public void setJMSType(String string) throws JMSException { - getContentHeaderProperties().setType(string); + _delegate.setJMSType(string); } public long getJMSExpiration() throws JMSException { - return getContentHeaderProperties().getExpiration(); + return _delegate.getJMSExpiration(); } public void setJMSExpiration(long l) throws JMSException { - getContentHeaderProperties().setExpiration(l); + _delegate.setJMSExpiration(l); } public int getJMSPriority() throws JMSException { - return getContentHeaderProperties().getPriority(); + return _delegate.getJMSPriority(); } public void setJMSPriority(int i) throws JMSException { - getContentHeaderProperties().setPriority((byte) i); - } - - public void clearProperties() throws JMSException - { - getJmsHeaders().clear(); - - _readableProperties = false; - } - - public void clearBody() throws JMSException - { - clearBodyImpl(); - _readableMessage = false; + _delegate.setJMSPriority(i); } - public boolean propertyExists(AMQShortString propertyName) throws JMSException - { - return getJmsHeaders().propertyExists(propertyName); - } public boolean propertyExists(String propertyName) throws JMSException { - return getJmsHeaders().propertyExists(propertyName); + return _delegate.propertyExists(propertyName); } - public boolean getBooleanProperty(AMQShortString propertyName) throws JMSException + public boolean getBooleanProperty(final String s) + throws JMSException { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - return getJmsHeaders().getBoolean(propertyName); + return _delegate.getBooleanProperty(s); } - public boolean getBooleanProperty(String propertyName) throws JMSException + public byte getByteProperty(final String s) + throws JMSException { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - return getJmsHeaders().getBoolean(propertyName); + return _delegate.getByteProperty(s); } - public byte getByteProperty(String propertyName) throws JMSException + public short getShortProperty(final String s) + throws JMSException { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - return getJmsHeaders().getByte(propertyName); + return _delegate.getShortProperty(s); } - public byte[] getBytesProperty(AMQShortString propertyName) throws JMSException + public int getIntProperty(final String s) + throws JMSException { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - return getJmsHeaders().getBytes(propertyName); + return _delegate.getIntProperty(s); } - public short getShortProperty(String propertyName) throws JMSException + public long getLongProperty(final String s) + throws JMSException { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - return getJmsHeaders().getShort(propertyName); + return _delegate.getLongProperty(s); } - public int getIntProperty(String propertyName) throws JMSException + public float getFloatProperty(final String s) + throws JMSException { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - return getJmsHeaders().getInteger(propertyName); + return _delegate.getFloatProperty(s); } - public long getLongProperty(String propertyName) throws JMSException + public double getDoubleProperty(final String s) + throws JMSException { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - return getJmsHeaders().getLong(propertyName); - } - - public float getFloatProperty(String propertyName) throws JMSException - { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - return getJmsHeaders().getFloat(propertyName); + return _delegate.getDoubleProperty(s); } - public double getDoubleProperty(String propertyName) throws JMSException + public String getStringProperty(final String s) + throws JMSException { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - return getJmsHeaders().getDouble(propertyName); + return _delegate.getStringProperty(s); } - public String getStringProperty(String propertyName) throws JMSException + public Object getObjectProperty(final String s) + throws JMSException { - //NOTE: if the JMSX Property is a non AMQP property then we must check _strictAMQP and throw as below. - if (propertyName.equals(CustomJMSXProperty.JMSXUserID.toString())) - { - return ((BasicContentHeaderProperties) _contentHeaderProperties).getUserIdAsString(); - } - else - { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - return getJmsHeaders().getString(propertyName); - } + return _delegate.getObjectProperty(s); } - public Object getObjectProperty(String propertyName) throws JMSException + public Enumeration getPropertyNames() + throws JMSException { - return getJmsHeaders().getObject(propertyName); + return _delegate.getPropertyNames(); } - public Enumeration getPropertyNames() throws JMSException + public void setBooleanProperty(final String s, final boolean b) + throws JMSException { - return getJmsHeaders().getPropertyNames(); + _delegate.setBooleanProperty(s, b); } - public void setBooleanProperty(AMQShortString propertyName, boolean b) throws JMSException + public void setByteProperty(final String s, final byte b) + throws JMSException { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - checkWritableProperties(); - getJmsHeaders().setBoolean(propertyName, b); + _delegate.setByteProperty(s, b); } - public void setBooleanProperty(String propertyName, boolean b) throws JMSException + public void setShortProperty(final String s, final short i) + throws JMSException { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - checkWritableProperties(); - getJmsHeaders().setBoolean(propertyName, b); + _delegate.setShortProperty(s, i); } - public void setByteProperty(String propertyName, byte b) throws JMSException + public void setIntProperty(final String s, final int i) + throws JMSException { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - checkWritableProperties(); - getJmsHeaders().setByte(propertyName, new Byte(b)); + _delegate.setIntProperty(s, i); } - public void setBytesProperty(AMQShortString propertyName, byte[] bytes) throws JMSException + public void setLongProperty(final String s, final long l) + throws JMSException { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - checkWritableProperties(); - getJmsHeaders().setBytes(propertyName, bytes); + _delegate.setLongProperty(s, l); } - public void setShortProperty(String propertyName, short i) throws JMSException + public void setFloatProperty(final String s, final float v) + throws JMSException { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - checkWritableProperties(); - getJmsHeaders().setShort(propertyName, new Short(i)); + _delegate.setFloatProperty(s, v); } - public void setIntProperty(String propertyName, int i) throws JMSException + public void setDoubleProperty(final String s, final double v) + throws JMSException { - checkWritableProperties(); - JMSHeaderAdapter.checkPropertyName(propertyName); - super.setIntProperty(new AMQShortString(propertyName), new Integer(i)); + _delegate.setDoubleProperty(s, v); } - public void setLongProperty(String propertyName, long l) throws JMSException + public void setStringProperty(final String s, final String s1) + throws JMSException { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - checkWritableProperties(); - getJmsHeaders().setLong(propertyName, new Long(l)); + _delegate.setStringProperty(s, s1); } - public void setFloatProperty(String propertyName, float f) throws JMSException + public void setObjectProperty(final String s, final Object o) + throws JMSException { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - - checkWritableProperties(); - getJmsHeaders().setFloat(propertyName, new Float(f)); + _delegate.setObjectProperty(s, o); } - public void setDoubleProperty(String propertyName, double v) throws JMSException - { - if (STRICT_AMQP_COMPLIANCE) - { - throw new UnsupportedOperationException("JMS Proprerties not supported in AMQP"); - } - checkWritableProperties(); - getJmsHeaders().setDouble(propertyName, new Double(v)); - } - public void setStringProperty(String propertyName, String value) throws JMSException + public void clearProperties() throws JMSException { - checkWritableProperties(); - JMSHeaderAdapter.checkPropertyName(propertyName); - super.setLongStringProperty(new AMQShortString(propertyName), value); + _delegate.clearProperties(); } - public void setObjectProperty(String propertyName, Object object) throws JMSException + public void clearBody() throws JMSException { - checkWritableProperties(); - getJmsHeaders().setObject(propertyName, object); - } + clearBodyImpl(); + _readableMessage = false; - protected void removeProperty(AMQShortString propertyName) throws JMSException - { - getJmsHeaders().remove(propertyName); } - protected void removeProperty(String propertyName) throws JMSException - { - getJmsHeaders().remove(propertyName); - } public void acknowledgeThis() throws JMSException { - // the JMS 1.1 spec says in section 3.6 that calls to acknowledge are ignored when client acknowledge - // is not specified. In our case, we only set the session field where client acknowledge mode is specified. - if (_session != null) - { - if (_session.getAMQConnection().isClosed()) - { - throw new javax.jms.IllegalStateException("Connection is already closed"); - } - - // we set multiple to true here since acknowledgement implies acknowledge of all previous messages - // received on the session - _session.acknowledgeMessage(_deliveryTag, true); - } + _delegate.acknowledgeThis(); } public void acknowledge() throws JMSException { - if (_session != null) - { - _session.acknowledge(); - } + _delegate.acknowledge(); } /** @@ -617,12 +358,9 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach */ public abstract String toBodyString() throws JMSException; - public String getMimeType() - { - return getMimeTypeAsShortString().toString(); - } + protected abstract String getMimeType(); + - public abstract AMQShortString getMimeTypeAsShortString(); public String toString() { @@ -640,16 +378,23 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach buf.append("\nJMS Destination: ").append(getJMSDestination()); buf.append("\nJMS Type: ").append(getJMSType()); buf.append("\nJMS MessageID: ").append(getJMSMessageID()); - buf.append("\nAMQ message number: ").append(_deliveryTag); + buf.append("\nAMQ message number: ").append(getDeliveryTag()); buf.append("\nProperties:"); - if (getJmsHeaders().isEmpty()) + final Enumeration propertyNames = getPropertyNames(); + if (!propertyNames.hasMoreElements()) { buf.append("<NONE>"); } else { - buf.append('\n').append(getJmsHeaders().getHeaders()); + buf.append('\n'); + while(propertyNames.hasMoreElements()) + { + String propertyName = (String) propertyNames.nextElement(); + buf.append(propertyName).append(":\t").append(getObjectProperty(propertyName)); + } + } return buf.toString(); @@ -660,14 +405,10 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach } } - public void setUnderlyingMessagePropertiesMap(FieldTable messageProperties) - { - getContentHeaderProperties().setHeaders(messageProperties); - } - public JMSHeaderAdapter getJmsHeaders() + public AMQMessageDelegate getDelegate() { - return _headerAdapter; + return _delegate; } public ByteBuffer getData() @@ -698,25 +439,6 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach } } - protected void checkWritableProperties() throws MessageNotWriteableException - { - if (_readableProperties) - { - throw new MessageNotWriteableException("You need to call clearProperties() to make the message writable"); - } - _contentHeaderProperties.updated(); - } - - public boolean isReadable() - { - return _readableMessage; - } - - public boolean isWritable() - { - return !_readableMessage; - } - public void reset() { if (!_changedData) @@ -726,7 +448,6 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach else { _data.flip(); - dataChanged(); _changedData = false; } } @@ -748,4 +469,66 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach _changedData = false; } + /** + * The session is set when CLIENT_ACKNOWLEDGE mode is used so that the CHANNEL ACK can be sent when the user calls + * acknowledge() + * + * @param s the AMQ session that delivered this message + */ + public void setAMQSession(AMQSession s) + { + _delegate.setAMQSession(s); + } + + public AMQSession getAMQSession() + { + return _delegate.getAMQSession(); + } + + /** + * Get the AMQ message number assigned to this message + * + * @return the message number + */ + public long getDeliveryTag() + { + return _delegate.getDeliveryTag(); + } + + /** Invoked prior to sending the message. Allows the message to be modified if necessary before sending. */ + public void prepareForSending() throws JMSException + { + } + + + public void setContentType(String contentType) + { + _delegate.setContentType(contentType); + } + + public String getContentType() + { + return _delegate.getContentType(); + } + + public void setEncoding(String encoding) + { + _delegate.setEncoding(encoding); + } + + public String getEncoding() + { + return _delegate.getEncoding(); + } + + public String getReplyToString() + { + return _delegate.getReplyToString(); + } + + protected void removeProperty(final String propertyName) throws JMSException + { + _delegate.removeProperty(propertyName); + } + } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java b/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java index 0dbad3726c..54a845ceef 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java @@ -27,9 +27,9 @@ import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ContentBody; import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpidity.transport.Struct; -import org.apache.qpidity.transport.MessageProperties; -import org.apache.qpidity.transport.DeliveryProperties; +import org.apache.qpid.transport.Struct; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.DeliveryProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,17 +38,11 @@ import javax.jms.JMSException; import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.UUID; public abstract class AbstractJMSMessageFactory implements MessageFactory { private static final Logger _logger = LoggerFactory.getLogger(AbstractJMSMessageFactory.class); - protected abstract AbstractJMSMessage createMessage(long messageNbr, ByteBuffer data, AMQShortString exchange, - AMQShortString routingKey, - BasicContentHeaderProperties contentHeader) throws AMQException; - protected AbstractJMSMessage create08MessageWithBody(long messageNbr, ContentHeaderBody contentHeader, AMQShortString exchange, AMQShortString routingKey, List bodies) throws AMQException @@ -105,23 +99,28 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory .remaining()); } - return createMessage(messageNbr, data, exchange, routingKey, - (BasicContentHeaderProperties) contentHeader.properties); + AMQMessageDelegate delegate = new AMQMessageDelegate_0_8(messageNbr, + (BasicContentHeaderProperties) contentHeader.properties, + exchange, routingKey); + + return createMessage(delegate, data); } + protected abstract AbstractJMSMessage createMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException; + + protected AbstractJMSMessage create010MessageWithBody(long messageNbr, Struct[] contentHeader, - AMQShortString exchange, AMQShortString routingKey, - List bodies, String replyToURL) throws AMQException + java.nio.ByteBuffer body) throws AMQException { ByteBuffer data; final boolean debug = _logger.isDebugEnabled(); - // we optimise the non-fragmented case to avoid copying - if ((bodies != null)) + + if (body != null) { - data = ByteBuffer.wrap((java.nio.ByteBuffer) bodies.get(0)); + data = ByteBuffer.wrap(body); } - else // bodies == null + else // body == null { data = ByteBuffer.allocate(0); } @@ -131,40 +130,13 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory _logger.debug("Creating message from buffer with position=" + data.position() + " and remaining=" + data .remaining()); } - BasicContentHeaderProperties props = new BasicContentHeaderProperties(); // set the properties of this message MessageProperties mprop = (MessageProperties) contentHeader[0]; DeliveryProperties devprop = (DeliveryProperties) contentHeader[1]; - props.setContentType(mprop.getContentType()); - props.setCorrelationId(asString(mprop.getCorrelationId())); - String encoding = mprop.getContentEncoding(); - if (encoding != null && !encoding.equals("")) - { - props.setEncoding(encoding); - } - if (devprop.hasDeliveryMode()) - { - props.setDeliveryMode((byte) devprop.getDeliveryMode().getValue()); - } - props.setExpiration(devprop.getExpiration()); - UUID mid = mprop.getMessageId(); - props.setMessageId(mid == null ? null : "ID:" + mid.toString()); - if (devprop.hasPriority()) - { - props.setPriority((byte) devprop.getPriority().getValue()); - } - props.setReplyTo(replyToURL); - props.setTimestamp(devprop.getTimestamp()); - String type = null; - Map<String,Object> map = mprop.getApplicationHeaders(); - if (map != null) - { - type = (String) map.get(AbstractJMSMessage.JMS_TYPE); - } - props.setType(type); - props.setUserId(asString(mprop.getUserId())); - props.setHeaders(FiledTableSupport.convertToFieldTable(mprop.getApplicationHeaders())); - AbstractJMSMessage message = createMessage(messageNbr, data, exchange, routingKey, props); + + AMQMessageDelegate delegate = new AMQMessageDelegate_0_10(mprop, devprop, messageNbr); + + AbstractJMSMessage message = createMessage(delegate, data); return message; } @@ -192,12 +164,11 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory } public AbstractJMSMessage createMessage(long messageNbr, boolean redelivered, Struct[] contentHeader, - AMQShortString exchange, AMQShortString routingKey, List bodies, - String replyToURL) + java.nio.ByteBuffer body) throws JMSException, AMQException { final AbstractJMSMessage msg = - create010MessageWithBody(messageNbr, contentHeader, exchange, routingKey, bodies, replyToURL); + create010MessageWithBody(messageNbr, contentHeader, body); msg.setJMSRedelivered(redelivered); msg.receivedFromServer(); return msg; diff --git a/java/client/src/main/java/org/apache/qpid/client/message/CloseConsumerMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/CloseConsumerMessage.java new file mode 100644 index 0000000000..4af04912e5 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/message/CloseConsumerMessage.java @@ -0,0 +1,43 @@ +/* + * + * 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.qpid.client.message; + +import org.apache.qpid.client.BasicMessageConsumer; + +public final class CloseConsumerMessage extends UnprocessedMessage +{ + + public CloseConsumerMessage(BasicMessageConsumer consumer) + { + super(consumer.getConsumerTag()); + } + + + public long getDeliveryTag() + { + return 0; + } + + public boolean isRedelivered() + { + return false; + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java index 4f5641bcff..cd9d7ccf8b 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java @@ -33,46 +33,47 @@ import javax.jms.MessageFormatException; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.BasicContentHeaderProperties; public class JMSBytesMessage extends AbstractBytesMessage implements BytesMessage { public static final String MIME_TYPE = "application/octet-stream"; - private static final AMQShortString MIME_TYPE_SHORT_STRING = new AMQShortString(MIME_TYPE); - public JMSBytesMessage() + + public JMSBytesMessage(AMQMessageDelegateFactory delegateFactory) { - this(null); + this(delegateFactory,null); + } /** * Construct a bytes message with existing data. * + * @param delegateFactory * @param data the data that comprises this message. If data is null, you get a 1024 byte buffer that is - * set to auto expand */ - JMSBytesMessage(ByteBuffer data) + JMSBytesMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data) { - super(data); // this instanties a content header + + super(delegateFactory, data); // this instanties a content header } - JMSBytesMessage(long messageNbr, BasicContentHeaderProperties contentHeader, AMQShortString exchange, - AMQShortString routingKey, ByteBuffer data) throws AMQException + JMSBytesMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException { - super(messageNbr, contentHeader, exchange, routingKey, data); + super(delegate, data); } + public void reset() { super.reset(); _readableMessage = true; } - public AMQShortString getMimeTypeAsShortString() + protected String getMimeType() { - return MIME_TYPE_SHORT_STRING; + return MIME_TYPE; } public long getBodyLength() throws JMSException diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessageFactory.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessageFactory.java index 0202dc29df..cb04ebee1b 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessageFactory.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessageFactory.java @@ -25,21 +25,18 @@ import javax.jms.JMSException; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.BasicContentHeaderProperties; public class JMSBytesMessageFactory extends AbstractJMSMessageFactory { - protected AbstractJMSMessage createMessage(long deliveryTag, ByteBuffer data, - AMQShortString exchange, AMQShortString routingKey, - BasicContentHeaderProperties contentHeader) throws AMQException + protected AbstractJMSMessage createMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException { - return new JMSBytesMessage(deliveryTag, contentHeader, exchange, routingKey, data); + return new JMSBytesMessage(delegate, data); } - public AbstractJMSMessage createMessage() throws JMSException + public AbstractJMSMessage createMessage(AMQMessageDelegateFactory delegateFactory) throws JMSException { - return new JMSBytesMessage(); + return new JMSBytesMessage(delegateFactory); } // 0_10 specific diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSHeaderAdapter.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSHeaderAdapter.java index fec0117a03..6215652c80 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSHeaderAdapter.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSHeaderAdapter.java @@ -467,7 +467,7 @@ public final class JMSHeaderAdapter return getPropertyNames(); } - protected static void checkPropertyName(CharSequence propertyName) + protected void checkPropertyName(CharSequence propertyName) { if (propertyName == null) { @@ -481,7 +481,7 @@ public final class JMSHeaderAdapter checkIdentiferFormat(propertyName); } - protected static void checkIdentiferFormat(CharSequence propertyName) + protected void checkIdentiferFormat(CharSequence propertyName) { // JMS requirements 3.5.1 Property Names // Identifiers: @@ -492,14 +492,14 @@ public final class JMSHeaderAdapter // '_' and '$'. An identifier part character is any character for which the // method Character.isJavaIdentifierPart returns true. // - Identifiers cannot be the names NULL, TRUE, or FALSE. -// � Identifiers cannot be NOT, AND, OR, BETWEEN, LIKE, IN, IS, or +// Identifiers cannot be NOT, AND, OR, BETWEEN, LIKE, IN, IS, or // ESCAPE. -// � Identifiers are either header field references or property references. The +// Identifiers are either header field references or property references. The // type of a property value in a message selector corresponds to the type // used to set the property. If a property that does not exist in a message is // referenced, its value is NULL. The semantics of evaluating NULL values -// in a selector are described in Section 3.8.1.2, �Null Values.� -// � The conversions that apply to the get methods for properties do not +// in a selector are described in Section 3.8.1.2, Null Values. +// The conversions that apply to the get methods for properties do not // apply when a property is used in a message selector expression. For // example, suppose you set a property as a string value, as in the // following: @@ -507,8 +507,8 @@ public final class JMSHeaderAdapter // The following expression in a message selector would evaluate to false, // because a string cannot be used in an arithmetic expression: // "NumberOfOrders > 1" -// � Identifiers are case sensitive. -// � Message header field references are restricted to JMSDeliveryMode, +// Identifiers are case sensitive. +// Message header field references are restricted to JMSDeliveryMode, // JMSPriority, JMSMessageID, JMSTimestamp, JMSCorrelationID, and // JMSType. JMSMessageID, JMSCorrelationID, and JMSType values may be // null and if so are treated as a NULL value. diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessage.java index fed1f1c609..b6e013ac8f 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessage.java @@ -24,7 +24,6 @@ import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.BasicContentHeaderProperties; import org.slf4j.Logger; @@ -44,18 +43,19 @@ public class JMSMapMessage extends AbstractBytesTypedMessage implements javax.jm private static final Logger _logger = LoggerFactory.getLogger(JMSMapMessage.class); public static final String MIME_TYPE = "jms/map-message"; - private static final AMQShortString MIME_TYPE_SHORT_STRING = new AMQShortString(MIME_TYPE); + private Map<String, Object> _map = new HashMap<String, Object>(); - public JMSMapMessage() throws JMSException + public JMSMapMessage(AMQMessageDelegateFactory delegateFactory) throws JMSException { - this(null); + this(delegateFactory, null); } - JMSMapMessage(ByteBuffer data) throws JMSException + JMSMapMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data) throws JMSException { - super(data); // this instantiates a content header + + super(delegateFactory, data); // this instantiates a content header if(data != null) { populateMapFromData(); @@ -63,10 +63,10 @@ public class JMSMapMessage extends AbstractBytesTypedMessage implements javax.jm } - JMSMapMessage(long messageNbr, BasicContentHeaderProperties contentHeader, AMQShortString exchange, AMQShortString routingKey, - ByteBuffer data) throws AMQException + JMSMapMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException { - super(messageNbr, contentHeader, exchange, routingKey, data); + + super(delegate, data); try { populateMapFromData(); @@ -79,14 +79,15 @@ public class JMSMapMessage extends AbstractBytesTypedMessage implements javax.jm } + public String toBodyString() throws JMSException { return _map == null ? "" : _map.toString(); } - public AMQShortString getMimeTypeAsShortString() + protected String getMimeType() { - return MIME_TYPE_SHORT_STRING; + return MIME_TYPE; } public ByteBuffer getData() diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessageFactory.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessageFactory.java index 7cb8b637e6..eccb90560b 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessageFactory.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessageFactory.java @@ -25,21 +25,18 @@ import javax.jms.JMSException; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.BasicContentHeaderProperties; public class JMSMapMessageFactory extends AbstractJMSMessageFactory { - public AbstractJMSMessage createMessage() throws JMSException + public AbstractJMSMessage createMessage(AMQMessageDelegateFactory delegateFactory) throws JMSException { - return new JMSMapMessage(); + return new JMSMapMessage(delegateFactory); } - protected AbstractJMSMessage createMessage(long deliveryTag, ByteBuffer data, - AMQShortString exchange, AMQShortString routingKey, - BasicContentHeaderProperties contentHeader) throws AMQException + protected AbstractJMSMessage createMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException { - return new JMSMapMessage(deliveryTag, contentHeader, exchange, routingKey, data); + return new JMSMapMessage(delegate, data); } } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java index 385eee47c9..39b9597af1 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java @@ -37,63 +37,65 @@ import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.ContentHeaderBody; public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessage { public static final String MIME_TYPE = "application/java-object-stream"; - private static final AMQShortString MIME_TYPE_SHORT_STRING = new AMQShortString(MIME_TYPE); + private static final int DEFAULT_BUFFER_SIZE = 1024; /** * Creates empty, writable message for use by producers + * @param delegateFactory */ - public JMSObjectMessage() + public JMSObjectMessage(AMQMessageDelegateFactory delegateFactory) { - this(null); + this(delegateFactory, null); } - private JMSObjectMessage(ByteBuffer data) + private JMSObjectMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data) { - super(data); + super(delegateFactory, data); if (data == null) { _data = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE); _data.setAutoExpand(true); } - getContentHeaderProperties().setContentType(MIME_TYPE_SHORT_STRING); + setContentType(getMimeType()); } /** * Creates read only message for delivery to consumers */ - JMSObjectMessage(long messageNbr, BasicContentHeaderProperties contentHeader, AMQShortString exchange, AMQShortString routingKey, - ByteBuffer data) throws AMQException - { - super(messageNbr, contentHeader, exchange, routingKey, data); - } + + JMSObjectMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException + { + super(delegate, data); + } + public void clearBodyImpl() throws JMSException { if (_data != null) { _data.release(); + _data = null; } - _data = null; + } public String toBodyString() throws JMSException { - return toString(_data); + return String.valueOf(getObject()); } - public AMQShortString getMimeTypeAsShortString() + public String getMimeType() { - return MIME_TYPE_SHORT_STRING; + return MIME_TYPE; } public void setObject(Serializable serializable) throws JMSException @@ -172,26 +174,4 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag catch (IOException ignore) { } } - - private static String toString(ByteBuffer data) - { - if (data == null) - { - return null; - } - - int pos = data.position(); - try - { - return data.getString(Charset.forName("UTF8").newDecoder()); - } - catch (CharacterCodingException e) - { - return null; - } - finally - { - data.position(pos); - } - } } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessageFactory.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessageFactory.java index e7369dcb26..03851dfa01 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessageFactory.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessageFactory.java @@ -25,20 +25,17 @@ import javax.jms.JMSException; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.BasicContentHeaderProperties; public class JMSObjectMessageFactory extends AbstractJMSMessageFactory { - protected AbstractJMSMessage createMessage(long deliveryTag, ByteBuffer data, - AMQShortString exchange, AMQShortString routingKey, - BasicContentHeaderProperties contentHeader) throws AMQException + protected AbstractJMSMessage createMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException { - return new JMSObjectMessage(deliveryTag, contentHeader, exchange, routingKey, data); + return new JMSObjectMessage(delegate, data); } - public AbstractJMSMessage createMessage() throws JMSException + public AbstractJMSMessage createMessage(AMQMessageDelegateFactory delegateFactory) throws JMSException { - return new JMSObjectMessage(); + return new JMSObjectMessage(delegateFactory); } } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessage.java index 62f3150ed1..ad2620852b 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessage.java @@ -26,7 +26,6 @@ import javax.jms.StreamMessage; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.BasicContentHeaderProperties; /** @@ -35,7 +34,7 @@ import org.apache.qpid.framing.BasicContentHeaderProperties; public class JMSStreamMessage extends AbstractBytesTypedMessage implements StreamMessage { public static final String MIME_TYPE="jms/stream-message"; - private static final AMQShortString MIME_TYPE_SHORT_STRING = new AMQShortString(MIME_TYPE); + /** @@ -44,38 +43,40 @@ public class JMSStreamMessage extends AbstractBytesTypedMessage implements Strea */ private int _byteArrayRemaining = -1; - public JMSStreamMessage() + public JMSStreamMessage(AMQMessageDelegateFactory delegateFactory) { - this(null); + this(delegateFactory,null); + } /** * Construct a stream message with existing data. * + * @param delegateFactory * @param data the data that comprises this message. If data is null, you get a 1024 byte buffer that is - * set to auto expand */ - JMSStreamMessage(ByteBuffer data) + JMSStreamMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data) { - super(data); // this instanties a content header - } + super(delegateFactory, data); // this instanties a content header + } - JMSStreamMessage(long messageNbr, BasicContentHeaderProperties contentHeader, AMQShortString exchange, - AMQShortString routingKey, ByteBuffer data) throws AMQException + JMSStreamMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException { - super(messageNbr, contentHeader, exchange, routingKey, data); + + super(delegate, data); } + public void reset() { super.reset(); _readableMessage = true; } - public AMQShortString getMimeTypeAsShortString() + protected String getMimeType() { - return MIME_TYPE_SHORT_STRING; + return MIME_TYPE; } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessageFactory.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessageFactory.java index 4bb648e090..5e25db9ae0 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessageFactory.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessageFactory.java @@ -25,19 +25,16 @@ import javax.jms.JMSException; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.BasicContentHeaderProperties; public class JMSStreamMessageFactory extends AbstractJMSMessageFactory { - protected AbstractJMSMessage createMessage(long deliveryTag, ByteBuffer data, - AMQShortString exchange, AMQShortString routingKey, - BasicContentHeaderProperties contentHeader) throws AMQException + protected AbstractJMSMessage createMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException { - return new JMSStreamMessage(deliveryTag, contentHeader, exchange, routingKey, data); + return new JMSStreamMessage(delegate, data); } - public AbstractJMSMessage createMessage() throws JMSException + public AbstractJMSMessage createMessage(AMQMessageDelegateFactory delegateFactory) throws JMSException { - return new JMSStreamMessage(); + return new JMSStreamMessage(delegateFactory); } } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java index 4a43a7bba8..c290149cef 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java @@ -31,60 +31,49 @@ import org.apache.qpid.AMQException; import org.apache.qpid.client.CustomJMSXProperty; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.util.Strings; public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.TextMessage { private static final String MIME_TYPE = "text/plain"; - private static final AMQShortString MIME_TYPE_SHORT_STRING = new AMQShortString(MIME_TYPE); - private String _decodedValue; /** * This constant represents the name of a property that is set when the message payload is null. */ - private static final AMQShortString PAYLOAD_NULL_PROPERTY = CustomJMSXProperty.JMS_AMQP_NULL.getShortStringName(); + private static final String PAYLOAD_NULL_PROPERTY = CustomJMSXProperty.JMS_AMQP_NULL.toString(); private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); - public JMSTextMessage() throws JMSException + public JMSTextMessage(AMQMessageDelegateFactory delegateFactory) throws JMSException { - this(null, null); + this(delegateFactory, null, null); } - JMSTextMessage(ByteBuffer data, String encoding) throws JMSException + JMSTextMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data, String encoding) throws JMSException { - super(data); // this instantiates a content header - getContentHeaderProperties().setContentType(MIME_TYPE_SHORT_STRING); - getContentHeaderProperties().setEncoding(encoding); + super(delegateFactory, data); // this instantiates a content header + setContentType(getMimeType()); + setEncoding(encoding); } - JMSTextMessage(long deliveryTag, BasicContentHeaderProperties contentHeader, AMQShortString exchange, - AMQShortString routingKey, ByteBuffer data) + JMSTextMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException { - super(deliveryTag, contentHeader, exchange, routingKey, data); - contentHeader.setContentType(MIME_TYPE_SHORT_STRING); + super(delegate, data); + setContentType(getMimeType()); _data = data; } - JMSTextMessage(ByteBuffer data) throws JMSException - { - this(data, null); - } - - JMSTextMessage(String text) throws JMSException - { - super((ByteBuffer) null); - setText(text); - } public void clearBodyImpl() throws JMSException { if (_data != null) { _data.release(); + _data = null; } - _data = null; + _decodedValue = null; } @@ -93,14 +82,9 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text return getText(); } - public void setData(ByteBuffer data) + protected String getMimeType() { - _data = data; - } - - public AMQShortString getMimeTypeAsShortString() - { - return MIME_TYPE_SHORT_STRING; + return MIME_TYPE; } public void setText(String text) throws JMSException @@ -111,20 +95,17 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text try { if (text != null) - { - _data = ByteBuffer.allocate(text.length()); - _data.limit(text.length()) ; - //_data.sweep(); - _data.setAutoExpand(true); - final String encoding = getContentHeaderProperties().getEncodingAsString(); - if (encoding == null) + { + final String encoding = getEncoding(); + if (encoding == null || encoding.equalsIgnoreCase("UTF-8")) { - _data.put(text.getBytes(DEFAULT_CHARSET.name())); + _data = ByteBuffer.wrap(Strings.toUTF8(text)); } else { - _data.put(text.getBytes(encoding)); + _data = ByteBuffer.wrap(text.getBytes(encoding)); } + _data.position(_data.limit()); _changedData=true; } _decodedValue = text; @@ -156,11 +137,11 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text { return null; } - if (getContentHeaderProperties().getEncodingAsString() != null) + if (getEncoding() != null) { try { - _decodedValue = _data.getString(Charset.forName(getContentHeaderProperties().getEncodingAsString()).newDecoder()); + _decodedValue = _data.getString(Charset.forName(getEncoding()).newDecoder()); } catch (CharacterCodingException e) { @@ -199,4 +180,6 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text removeProperty(PAYLOAD_NULL_PROPERTY); } } + + } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessageFactory.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessageFactory.java index c578c15a6a..1f4d64c78f 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessageFactory.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessageFactory.java @@ -26,21 +26,17 @@ import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.ContentHeaderBody; public class JMSTextMessageFactory extends AbstractJMSMessageFactory { - public AbstractJMSMessage createMessage() throws JMSException + public AbstractJMSMessage createMessage(AMQMessageDelegateFactory delegateFactory) throws JMSException { - return new JMSTextMessage(); + return new JMSTextMessage(delegateFactory); } - protected AbstractJMSMessage createMessage(long deliveryTag, ByteBuffer data, - AMQShortString exchange, AMQShortString routingKey, - BasicContentHeaderProperties contentHeader) throws AMQException + protected AbstractJMSMessage createMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException { - return new JMSTextMessage(deliveryTag, contentHeader, - exchange, routingKey, data); + return new JMSTextMessage(delegate, data); } } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/MessageConverter.java b/java/client/src/main/java/org/apache/qpid/client/message/MessageConverter.java index f6b11c6f6c..e606ef11c9 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/MessageConverter.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/MessageConverter.java @@ -22,15 +22,9 @@ package org.apache.qpid.client.message; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.apache.qpid.client.AMQSession; -import javax.jms.BytesMessage; -import javax.jms.JMSException; -import javax.jms.MapMessage; -import javax.jms.Message; -import javax.jms.MessageEOFException; -import javax.jms.ObjectMessage; -import javax.jms.StreamMessage; -import javax.jms.TextMessage; +import javax.jms.*; import java.util.Enumeration; @@ -52,12 +46,11 @@ public class MessageConverter _newMessage = message; } - public MessageConverter(BytesMessage message) throws JMSException + public MessageConverter(AMQSession session, BytesMessage bytesMessage) throws JMSException { - BytesMessage bytesMessage = (BytesMessage) message; bytesMessage.reset(); - JMSBytesMessage nativeMsg = new JMSBytesMessage(); + JMSBytesMessage nativeMsg = (JMSBytesMessage) session.createBytesMessage(); byte[] buf = new byte[1024]; @@ -69,12 +62,12 @@ public class MessageConverter } _newMessage = nativeMsg; - setMessageProperties(message); + setMessageProperties(bytesMessage); } - public MessageConverter(MapMessage message) throws JMSException + public MessageConverter(AMQSession session, MapMessage message) throws JMSException { - MapMessage nativeMessage = new JMSMapMessage(); + MapMessage nativeMessage = session.createMapMessage(); Enumeration mapNames = message.getMapNames(); while (mapNames.hasMoreElements()) @@ -87,21 +80,21 @@ public class MessageConverter setMessageProperties(message); } - public MessageConverter(ObjectMessage message) throws JMSException + public MessageConverter(AMQSession session, ObjectMessage origMessage) throws JMSException { - ObjectMessage origMessage = (ObjectMessage) message; - ObjectMessage nativeMessage = new JMSObjectMessage(); + + ObjectMessage nativeMessage = session.createObjectMessage(); nativeMessage.setObject(origMessage.getObject()); _newMessage = (AbstractJMSMessage) nativeMessage; - setMessageProperties(message); + setMessageProperties(origMessage); } - public MessageConverter(TextMessage message) throws JMSException + public MessageConverter(AMQSession session, TextMessage message) throws JMSException { - TextMessage nativeMessage = new JMSTextMessage(); + TextMessage nativeMessage = session.createTextMessage(); nativeMessage.setText(message.getText()); @@ -109,9 +102,9 @@ public class MessageConverter setMessageProperties(message); } - public MessageConverter(StreamMessage message) throws JMSException + public MessageConverter(AMQSession session, StreamMessage message) throws JMSException { - StreamMessage nativeMessage = new JMSStreamMessage(); + StreamMessage nativeMessage = session.createStreamMessage(); try { @@ -130,11 +123,11 @@ public class MessageConverter setMessageProperties(message); } - public MessageConverter(Message message) throws JMSException + public MessageConverter(AMQSession session, Message message) throws JMSException { // Send a message with just properties. // Throwing away content - BytesMessage nativeMessage = new JMSBytesMessage(); + Message nativeMessage = session.createMessage(); _newMessage = (AbstractJMSMessage) nativeMessage; setMessageProperties(message); diff --git a/java/client/src/main/java/org/apache/qpid/client/message/MessageFactory.java b/java/client/src/main/java/org/apache/qpid/client/message/MessageFactory.java index c6b22592e0..e1275c37f7 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/MessageFactory.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/MessageFactory.java @@ -27,7 +27,7 @@ import javax.jms.JMSException; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpidity.transport.Struct; +import org.apache.qpid.transport.Struct; public interface MessageFactory @@ -39,10 +39,9 @@ public interface MessageFactory throws JMSException, AMQException; AbstractJMSMessage createMessage(long deliveryTag, boolean redelivered, - Struct[] contentHeader, - AMQShortString exchange, AMQShortString routingKey, - List bodies, String replyToURL) + Struct[] contentHeader, + java.nio.ByteBuffer body) throws JMSException, AMQException; - AbstractJMSMessage createMessage() throws JMSException; + AbstractJMSMessage createMessage(AMQMessageDelegateFactory delegateFactory) throws JMSException; } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java b/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java index 24ab471f10..948d6d0d7d 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java @@ -23,6 +23,7 @@ package org.apache.qpid.client.message; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.nio.ByteBuffer; import javax.jms.JMSException; @@ -30,9 +31,10 @@ import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.BasicContentHeaderProperties; import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpidity.transport.Struct; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageProperties; +import org.apache.qpid.transport.Struct; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.MessageTransfer; +import org.apache.qpid.transport.DeliveryProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -92,8 +94,7 @@ public class MessageFactoryRegistry * @param deliveryTag the AMQ message id * @param redelivered true if redelivered * @param contentHeader the content header that was received - * @param bodies a list of ContentBody instances - * @return the message. + * @param bodies a list of ContentBody instances @return the message. * @throws AMQException * @throws JMSException */ @@ -120,30 +121,35 @@ public class MessageFactoryRegistry } } - public AbstractJMSMessage createMessage(long deliveryTag, boolean redelivered, AMQShortString exchange, - AMQShortString routingKey, Struct[] contentHeader, List bodies, - String replyTo) throws AMQException, JMSException + public AbstractJMSMessage createMessage(MessageTransfer transfer) throws AMQException, JMSException { - MessageProperties mprop = (MessageProperties) contentHeader[0]; + + MessageProperties mprop = transfer.getHeader().get(MessageProperties.class); String messageType = mprop.getContentType(); if (messageType == null) { _logger.debug("no message type specified, building a byte message"); messageType = JMSBytesMessage.MIME_TYPE; } - MessageFactory mf = _mimeShortStringToFactoryMap.get(new AMQShortString(messageType)); + MessageFactory mf = _mimeStringToFactoryMap.get(messageType); if (mf == null) { throw new AMQException(null, "Unsupport MIME type of " + messageType, null); } else { - return mf.createMessage(deliveryTag, redelivered, contentHeader, exchange, routingKey, bodies, replyTo); + boolean redelivered = false; + DeliveryProperties deliverProps; + if((deliverProps = transfer.getHeader().get(DeliveryProperties.class)) != null) + { + redelivered = deliverProps.getRedelivered(); + } + return mf.createMessage(transfer.getId(), redelivered, transfer.getHeader().getStructs(), transfer.getBody()); } } - public AbstractJMSMessage createMessage(String mimeType) throws AMQException, JMSException + public AbstractJMSMessage createMessage(AMQMessageDelegateFactory delegateFactory, String mimeType) throws AMQException, JMSException { if (mimeType == null) { @@ -157,7 +163,7 @@ public class MessageFactoryRegistry } else { - return mf.createMessage(); + return mf.createMessage(delegateFactory); } } } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/ReturnMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/ReturnMessage.java index c866a5028e..ed590772d9 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/ReturnMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/ReturnMessage.java @@ -7,9 +7,9 @@ public class ReturnMessage extends UnprocessedMessage_0_8 final private AMQShortString _replyText; final private int _replyCode; - public ReturnMessage(int channelId,AMQShortString exchange,AMQShortString routingKey,AMQShortString replyText,int replyCode) + public ReturnMessage(AMQShortString exchange, AMQShortString routingKey, AMQShortString replyText, int replyCode) { - super(channelId,-1,null,exchange,routingKey,false); + super(-1,0,exchange,routingKey,false); _replyText = replyText; _replyCode = replyCode; } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage.java index 17efd7e24f..713c87260c 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage.java @@ -20,23 +20,7 @@ */ package org.apache.qpid.client.message; -import java.util.List; - -import org.apache.qpid.framing.AMQShortString; -import org.apache.mina.common.ByteBuffer; -import org.apache.qpid.AMQChannelException; -import org.apache.qpid.AMQConnectionException; -import org.apache.qpid.AMQException; import org.apache.qpid.client.BasicMessageConsumer; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.BasicDeliverBody; -import org.apache.qpid.framing.BasicReturnBody; -import org.apache.qpid.framing.ContentBody; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.MethodDispatcher; -import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.protocol.AMQVersionAwareProtocolSession; /** @@ -46,65 +30,24 @@ import org.apache.qpid.protocol.AMQVersionAwareProtocolSession; * Note that the actual work of creating a JMS message for the client code's use is done outside of the MINA dispatcher * thread in order to minimise the amount of work done in the MINA dispatcher thread. */ -public abstract class UnprocessedMessage<H,B> +public abstract class UnprocessedMessage { - private final int _channelId; - private final long _deliveryId; - private final AMQShortString _consumerTag; - protected AMQShortString _exchange; - protected AMQShortString _routingKey; - protected boolean _redelivered; + private final int _consumerTag; + - public UnprocessedMessage(int channelId,long deliveryId,AMQShortString consumerTag,AMQShortString exchange,AMQShortString routingKey,boolean redelivered) + public UnprocessedMessage(int consumerTag) { - _channelId = channelId; - _deliveryId = deliveryId; _consumerTag = consumerTag; - _exchange = exchange; - _routingKey = routingKey; - _redelivered = redelivered; } - public abstract void receiveBody(B nativeMessageBody); - public abstract void setContentHeader(H nativeMessageHeader); - - public int getChannelId() - { - return _channelId; - } + abstract public long getDeliveryTag(); - public long getDeliveryTag() - { - return _deliveryId; - } - public AMQShortString getConsumerTag() + public int getConsumerTag() { return _consumerTag; } - public AMQShortString getExchange() - { - return _exchange; - } - - public AMQShortString getRoutingKey() - { - return _routingKey; - } - public boolean isRedelivered() - { - return _redelivered; - } - public abstract List<B> getBodies(); - - public abstract H getContentHeader(); - - // specific to 0_10 - public String getReplyToURL() - { - return ""; - } -} +}
\ No newline at end of file diff --git a/java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage_0_10.java b/java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage_0_10.java index 09f41a9ba6..6b1301a33f 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage_0_10.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage_0_10.java @@ -20,13 +20,7 @@ */ package org.apache.qpid.client.message; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; - -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.Struct; +import org.apache.qpid.transport.MessageTransfer; /** * This class contains everything needed to process a JMS message. It assembles the deliver body, the content header and @@ -35,58 +29,25 @@ import org.apache.qpidity.transport.Struct; * Note that the actual work of creating a JMS message for the client code's use is done outside of the MINA dispatcher * thread in order to minimise the amount of work done in the MINA dispatcher thread. */ -public class UnprocessedMessage_0_10 extends UnprocessedMessage<Struct[],ByteBuffer> +public class UnprocessedMessage_0_10 extends UnprocessedMessage { - private Struct[] _headers; - private String _replyToURL; - - /** List of ContentBody instances. Due to fragmentation you don't know how big this will be in general */ - private List<ByteBuffer> _bodies = new ArrayList<ByteBuffer>(); - - public UnprocessedMessage_0_10(int channelId,long deliveryId,AMQShortString consumerTag,AMQShortString exchange,AMQShortString routingKey,boolean redelivered) - { - super(channelId,deliveryId,consumerTag,exchange,routingKey,redelivered); - } - - public void receiveBody(ByteBuffer body) - { - - _bodies.add(body); - } - - public void setContentHeader(Struct[] headers) - { - this._headers = headers; - for(Struct s: headers) - { - if (s instanceof DeliveryProperties) - { - DeliveryProperties props = (DeliveryProperties)s; - _exchange = new AMQShortString(props.getExchange()); - _routingKey = new AMQShortString(props.getRoutingKey()); - _redelivered = props.getRedelivered(); - } - } - } + private MessageTransfer _transfer; - public Struct[] getContentHeader() + public UnprocessedMessage_0_10(int consumerTag, MessageTransfer xfr) { - return _headers; - } - - public List<ByteBuffer> getBodies() - { - return _bodies; + super(consumerTag); + _transfer = xfr; } // additional 0_10 method - public String getReplyToURL() + + public long getDeliveryTag() { - return _replyToURL; + return _transfer.getId(); } - public void setReplyToURL(String url) + public MessageTransfer getMessageTransfer() { - _replyToURL = url; + return _transfer; } } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage_0_8.java b/java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage_0_8.java index 78da8cdca2..685e646d85 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage_0_8.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage_0_8.java @@ -26,7 +26,6 @@ import java.util.List; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.BasicDeliverBody; -import org.apache.qpid.framing.BasicReturnBody; import org.apache.qpid.framing.ContentBody; import org.apache.qpid.framing.ContentHeaderBody; @@ -37,32 +36,54 @@ import org.apache.qpid.framing.ContentHeaderBody; * Note that the actual work of creating a JMS message for the client code's use is done outside of the MINA dispatcher * thread in order to minimise the amount of work done in the MINA dispatcher thread. */ -public class UnprocessedMessage_0_8 extends UnprocessedMessage<ContentHeaderBody,ContentBody> +public class UnprocessedMessage_0_8 extends UnprocessedMessage { private long _bytesReceived = 0; + + private AMQShortString _exchange; + private AMQShortString _routingKey; + private final long _deliveryId; + protected boolean _redelivered; + private BasicDeliverBody _deliverBody; private ContentHeaderBody _contentHeader; /** List of ContentBody instances. Due to fragmentation you don't know how big this will be in general */ private List<ContentBody> _bodies; - public UnprocessedMessage_0_8(int channelId,long deliveryId,AMQShortString consumerTag,AMQShortString exchange,AMQShortString routingKey,boolean redelivered) + public UnprocessedMessage_0_8(long deliveryId, int consumerTag, AMQShortString exchange, AMQShortString routingKey, boolean redelivered) + { + super(consumerTag); + _exchange = exchange; + _routingKey = routingKey; + + _redelivered = redelivered; + _deliveryId = deliveryId; + } + + + public AMQShortString getExchange() + { + return _exchange; + } + + public AMQShortString getRoutingKey() { - super(channelId,deliveryId,consumerTag,exchange,routingKey,redelivered); + return _routingKey; } - public UnprocessedMessage_0_8(int channelId, BasicReturnBody body) + public long getDeliveryTag() { - //FIXME: TGM, SRSLY 4RL - super(channelId, 0, null, body.getExchange(), body.getRoutingKey(), false); + return _deliveryId; } - public UnprocessedMessage_0_8(int channelId, BasicDeliverBody body) + public boolean isRedelivered() { - super(channelId, body.getDeliveryTag(), body.getConsumerTag(), body.getExchange(), body.getRoutingKey(), false); + return _redelivered; } + public void receiveBody(ContentBody body) { @@ -124,7 +145,7 @@ public class UnprocessedMessage_0_8 extends UnprocessedMessage<ContentHeaderBody public String toString() { StringBuilder buf = new StringBuilder(); - buf.append("Channel Id : " + this.getChannelId()); + if (_contentHeader != null) { buf.append("ContentHeader " + _contentHeader); diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQIoTransportProtocolSession.java b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQIoTransportProtocolSession.java new file mode 100644 index 0000000000..1de0e7bdfc --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQIoTransportProtocolSession.java @@ -0,0 +1,125 @@ +package org.apache.qpid.client.protocol; + +import java.util.UUID; + +import javax.security.sasl.SaslClient; + +import org.apache.commons.lang.StringUtils; +import org.apache.mina.common.IdleStatus; +import org.apache.qpid.AMQException; +import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.client.ConnectionTuneParameters; +import org.apache.qpid.client.handler.ClientMethodDispatcherImpl; +import org.apache.qpid.client.state.AMQState; +import org.apache.qpid.framing.AMQDataBlock; +import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.ProtocolInitiation; +import org.apache.qpid.framing.ProtocolVersion; +import org.apache.qpid.transport.Sender; + +public class AMQIoTransportProtocolSession extends AMQProtocolSession +{ + + protected Sender<java.nio.ByteBuffer> _ioSender; + private SaslClient _saslClient; + private ConnectionTuneParameters _connectionTuneParameters; + + public AMQIoTransportProtocolSession(AMQProtocolHandler protocolHandler, AMQConnection connection) + { + super(protocolHandler, connection); + } + + @Override + public void closeProtocolSession(boolean waitLast) throws AMQException + { + _ioSender.close(); + _protocolHandler.getStateManager().changeState(AMQState.CONNECTION_CLOSED); + } + + @Override + public void init() + { + _ioSender.send(new ProtocolInitiation(_connection.getProtocolVersion()).toNioByteBuffer()); + _ioSender.flush(); + } + + @Override + protected AMQShortString generateQueueName() + { + int id; + synchronized (_queueIdLock) + { + id = _queueId++; + } + return new AMQShortString("tmp_" + UUID.randomUUID() + "_" + id); + } + + @Override + public AMQConnection getAMQConnection() + { + return _connection; + } + + @Override + public SaslClient getSaslClient() + { + return _saslClient; + } + + @Override + public void setSaslClient(SaslClient client) + { + _saslClient = client; + } + + /** @param delay delay in seconds (not ms) */ + @Override + void initHeartbeats(int delay) + { + if (delay > 0) + { + // FIXME: actually do something here + HeartbeatDiagnostics.init(delay, HeartbeatConfig.CONFIG.getTimeout(delay)); + } + } + + @Override + public void methodFrameReceived(final int channel, final AMQMethodBody amqMethodBody) throws AMQException + { + // FIXME? + _protocolHandler.methodBodyReceived(channel, amqMethodBody, null); + } + + @Override + public void writeFrame(AMQDataBlock frame, boolean wait) + { + _ioSender.send(frame.toNioByteBuffer()); + if (wait) + { + _ioSender.flush(); + } + } + + @Override + public void setSender(Sender<java.nio.ByteBuffer> sender) + { + _ioSender = sender; + } + + @Override + public ConnectionTuneParameters getConnectionTuneParameters() + { + return _connectionTuneParameters; + } + + @Override + public void setConnectionTuneParameters(ConnectionTuneParameters params) + { + _connectionTuneParameters = params; + AMQConnection con = getAMQConnection(); + con.setMaximumChannelCount(params.getChannelMax()); + con.setMaximumFrameSize(params.getFrameMax()); + initHeartbeats((int) params.getHeartbeat()); + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java index 2d8074eea2..e92817f713 100644 --- a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java @@ -43,14 +43,17 @@ import org.apache.qpid.client.failover.FailoverHandler; import org.apache.qpid.client.failover.FailoverState; import org.apache.qpid.client.state.AMQState; import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateWaiter; import org.apache.qpid.client.state.listener.SpecificMethodFrameListener; import org.apache.qpid.codec.AMQCodecFactory; import org.apache.qpid.framing.*; +import org.apache.qpid.jms.BrokerDetails; import org.apache.qpid.pool.ReadWriteThreadModel; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQMethodListener; import org.apache.qpid.ssl.SSLContextFactory; +import org.apache.qpid.transport.network.io.IoTransport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -100,28 +103,29 @@ import java.util.concurrent.CountDownLatch; * <p/><table id="crc"><caption>CRC Card</caption> * <tr><th> Responsibilities <th> Collaborations * <tr><td> Create the filter chain to filter this handlers events. - * <td> {@link ProtocolCodecFilter}, {@link SSLContextFactory}, {@link SSLFilter}, {@link ReadWriteThreadModel}. + * <td> {@link ProtocolCodecFilter}, {@link SSLContextFactory}, {@link SSLFilter}, {@link ReadWriteThreadModel}. * * <tr><td> Maintain fail-over state. * <tr><td> * </table> * * @todo Explain the system property: amqj.shared_read_write_pool. How does putting the protocol codec filter before the - * async write filter make it a shared pool? The pooling filter uses the same thread pool for reading and writing - * anyway, see {@link org.apache.qpid.pool.PoolingFilter}, docs for comments. Will putting the protocol codec - * filter before it mean not doing the read/write asynchronously but in the main filter thread? - * + * async write filter make it a shared pool? The pooling filter uses the same thread pool for reading and writing + * anyway, see {@link org.apache.qpid.pool.PoolingFilter}, docs for comments. Will putting the protocol codec + * filter before it mean not doing the read/write asynchronously but in the main filter thread? * @todo Use a single handler instance, by shifting everything to do with the 'protocol session' state, including - * failover state, into AMQProtocolSession, and tracking that from AMQConnection? The lifecycles of - * AMQProtocolSesssion and AMQConnection will be the same, so if there is high cohesion between them, they could - * be merged, although there is sense in keeping the session model seperate. Will clarify things by having data - * held per protocol handler, per protocol session, per network connection, per channel, in seperate classes, so - * that lifecycles of the fields match lifecycles of their containing objects. + * failover state, into AMQProtocolSession, and tracking that from AMQConnection? The lifecycles of + * AMQProtocolSesssion and AMQConnection will be the same, so if there is high cohesion between them, they could + * be merged, although there is sense in keeping the session model seperate. Will clarify things by having data + * held per protocol handler, per protocol session, per network connection, per channel, in seperate classes, so + * that lifecycles of the fields match lifecycles of their containing objects. */ public class AMQProtocolHandler extends IoHandlerAdapter { /** Used for debugging. */ private static final Logger _logger = LoggerFactory.getLogger(AMQProtocolHandler.class); + private static final Logger _protocolLogger = LoggerFactory.getLogger("qpid.protocol"); + private static final boolean PROTOCOL_DEBUG = (System.getProperty("amqj.protocol.logging.level") != null); /** * The connection that this protocol handler is associated with. There is a 1-1 mapping between connection @@ -136,7 +140,7 @@ public class AMQProtocolHandler extends IoHandlerAdapter private AMQStateManager _stateManager = new AMQStateManager(); /** Holds the method listeners, */ - private final CopyOnWriteArraySet _frameListeners = new CopyOnWriteArraySet(); + private final CopyOnWriteArraySet<AMQMethodListener> _frameListeners = new CopyOnWriteArraySet<AMQMethodListener>(); /** * We create the failover handler when the session is created since it needs a reference to the IoSession in order @@ -154,14 +158,12 @@ public class AMQProtocolHandler extends IoHandlerAdapter /** Used to provide a condition to wait upon for operations that are required to wait for failover to complete. */ private CountDownLatch _failoverLatch; - /** The last failover exception that occured */ private FailoverException _lastFailoverException; /** Defines the default timeout to use for synchronous protocol commands. */ private final long DEFAULT_SYNC_TIMEOUT = 1000 * 30; - /** * Creates a new protocol handler, associated with the specified client connection instance. * @@ -245,11 +247,27 @@ public class AMQProtocolHandler extends IoHandlerAdapter _logger.error("Unable to attach IO Read/Write Filter Protection :" + e.getMessage()); } } - _protocolSession = new AMQProtocolSession(this, session, _connection, getStateManager()); + _protocolSession = new AMQProtocolSession(this, session, _connection); + + _stateManager.setProtocolSession(_protocolSession); + _protocolSession.init(); } /** + * Called when we want to create a new IoTransport session + * @param brokerDetail + */ + public void createIoTransportSession(BrokerDetails brokerDetail) + { + _protocolSession = new AMQProtocolSession(this, _connection); + _stateManager.setProtocolSession(_protocolSession); + IoTransport.connect_0_9(getProtocolSession(), + brokerDetail.getHost(), brokerDetail.getPort()); + _protocolSession.init(); + } + + /** * Called when the network connection is closed. This can happen, either because the client explicitly requested * that the connection be closed, in which case nothing is done, or because the connection died. In the case * where the connection died, an attempt to failover automatically to a new connection may be started. The failover @@ -263,7 +281,7 @@ public class AMQProtocolHandler extends IoHandlerAdapter * @param session The MINA session. * * @todo Clarify: presumably exceptionCaught is called when the client is sending during a connection failure and - * not otherwise? The above comment doesn't make that clear. + * not otherwise? The above comment doesn't make that clear. */ public void sessionClosed(IoSession session) { @@ -374,7 +392,7 @@ public class AMQProtocolHandler extends IoHandlerAdapter "cause isn't AMQConnectionClosedException: " + cause, cause); AMQException amqe = new AMQException("Protocol handler error: " + cause, cause); - propagateExceptionToWaiters(amqe); + propagateExceptionToAllWaiters(amqe); } _connection.exceptionReceived(cause); @@ -395,7 +413,7 @@ public class AMQProtocolHandler extends IoHandlerAdapter // we notify the state manager of the error in case we have any clients waiting on a state // change. Those "waiters" will be interrupted and can handle the exception AMQException amqe = new AMQException("Protocol handler error: " + cause, cause); - propagateExceptionToWaiters(amqe); + propagateExceptionToAllWaiters(amqe); _connection.exceptionReceived(cause); } } @@ -405,11 +423,33 @@ public class AMQProtocolHandler extends IoHandlerAdapter * These are for the state manager (waiting for a state change) or a frame listener (waiting for a particular type * of frame to arrive). When an error occurs we need to notify these waiters so that they can react appropriately. * + * This should be called only when the exception is fatal for the connection. + * * @param e the exception to propagate + * + * @see #propagateExceptionToFrameListeners + * @see #propagateExceptionToStateWaiters */ - public void propagateExceptionToWaiters(Exception e) + public void propagateExceptionToAllWaiters(Exception e) + { + propagateExceptionToFrameListeners(e); + propagateExceptionToStateWaiters(e); + } + + /** + * This caters for the case where we only need to propogate an exception to the the frame listeners to interupt any + * protocol level waits. + * + * This will would normally be used to notify all Frame Listeners that Failover is about to occur and they should + * stop waiting and relinquish the Failover lock {@see FailoverHandler}. + * + * Once the {@link FailoverHandler} has re-established the connection then the listeners will be able to re-attempt + * their protocol request and so listen again for the correct frame. + * + * @param e the exception to propagate + */ + public void propagateExceptionToFrameListeners(Exception e) { - if (!_frameListeners.isEmpty()) { final Iterator it = _frameListeners.iterator(); @@ -421,6 +461,22 @@ public class AMQProtocolHandler extends IoHandlerAdapter } } + /** + * This caters for the case where we only need to propogate an exception to the the state manager to interupt any + * thing waiting for a state change. + * + * Currently (2008-07-15) the state manager is only used during 0-8/0-9 Connection establishement. + * + * Normally the state manager would not need to be notified without notifiying the frame listeners so in normal + * cases {@link #propagateExceptionToAllWaiters} would be the correct choice. + * + * @param e the exception to propagate + */ + public void propagateExceptionToStateWaiters(Exception e) + { + getStateManager().error(e); + } + public void notifyFailoverStarting() { // Set the last exception in the sync block to ensure the ordering with add. @@ -431,7 +487,9 @@ public class AMQProtocolHandler extends IoHandlerAdapter _lastFailoverException = new FailoverException("Failing over about to start"); } - propagateExceptionToWaiters(_lastFailoverException); + //Only notify the Frame listeners that failover is going to occur as the State listeners shouldn't be + // interupted unless failover cannot restore the state. + propagateExceptionToFrameListeners(_lastFailoverException); } public void failoverInProgress() @@ -443,6 +501,11 @@ public class AMQProtocolHandler extends IoHandlerAdapter public void messageReceived(IoSession session, Object message) throws Exception { + if (PROTOCOL_DEBUG) + { + _protocolLogger.info(String.format("RECV: [%s] %s", this, message)); + } + if(message instanceof AMQFrame) { final boolean debug = _logger.isDebugEnabled(); @@ -459,7 +522,7 @@ public class AMQProtocolHandler extends IoHandlerAdapter HeartbeatDiagnostics.received(bodyFrame instanceof HeartbeatBody); - bodyFrame.handle(frame.getChannel(),_protocolSession); + bodyFrame.handle(frame.getChannel(), _protocolSession); _connection.bytesReceived(_protocolSession.getIoSession().getReadBytes()); } @@ -508,20 +571,12 @@ public class AMQProtocolHandler extends IoHandlerAdapter if (!wasAnyoneInterested) { throw new AMQException(null, "AMQMethodEvent " + evt + " was not processed by any listener. Listeners:" - + _frameListeners, null); + + _frameListeners, null); } } catch (AMQException e) - { - if (!_frameListeners.isEmpty()) - { - Iterator it = _frameListeners.iterator(); - while (it.hasNext()) - { - final AMQMethodListener listener = (AMQMethodListener) it.next(); - listener.error(e); - } - } + { + propagateExceptionToFrameListeners(e); exceptionCaught(session, e); } @@ -532,6 +587,11 @@ public class AMQProtocolHandler extends IoHandlerAdapter public void messageSent(IoSession session, Object message) throws Exception { + if (PROTOCOL_DEBUG) + { + _protocolLogger.debug(String.format("SEND: [%s] %s", this, message)); + } + final long sentMessages = _messagesOut++; final boolean debug = _logger.isDebugEnabled(); @@ -542,34 +602,13 @@ public class AMQProtocolHandler extends IoHandlerAdapter } _connection.bytesSent(session.getWrittenBytes()); - if (debug) - { - _logger.debug("Sent frame " + message); - } - } - - /* - public void addFrameListener(AMQMethodListener listener) - { - _frameListeners.add(listener); - } - - public void removeFrameListener(AMQMethodListener listener) - { - _frameListeners.remove(listener); - } - */ - public void attainState(AMQState s) throws AMQException - { - getStateManager().attainState(s); } - public AMQState attainState(Set<AMQState> states) throws AMQException + public StateWaiter createWaiter(Set<AMQState> states) throws AMQException { - return getStateManager().attainState(states); + return getStateManager().createWaiter(states); } - /** * Convenience method that writes a frame to the protocol session. Equivalent to calling * getProtocolSession().write(). @@ -617,14 +656,12 @@ public class AMQProtocolHandler extends IoHandlerAdapter { throw _lastFailoverException; } - + _frameListeners.add(listener); } _protocolSession.writeFrame(frame); - AMQMethodEvent e = listener.blockForFrame(timeout); - - return e; + return listener.blockForFrame(timeout); // When control resumes before this line, a reply will have been received // that matches the criteria defined in the blocking listener } @@ -669,8 +706,7 @@ public class AMQProtocolHandler extends IoHandlerAdapter getStateManager().changeState(AMQState.CONNECTION_CLOSING); ConnectionCloseBody body = _protocolSession.getMethodRegistry().createConnectionCloseBody(AMQConstant.REPLY_SUCCESS.getCode(), // replyCode - new AMQShortString("JMS client is closing the connection."),0,0); - + new AMQShortString("JMS client is closing the connection."), 0, 0); final AMQFrame frame = body.generateFrame(0); @@ -745,10 +781,6 @@ public class AMQProtocolHandler extends IoHandlerAdapter public void setStateManager(AMQStateManager stateManager) { _stateManager = stateManager; - if (_protocolSession != null) - { - _protocolSession.setStateManager(stateManager); - } } public AMQProtocolSession getProtocolSession() @@ -778,7 +810,7 @@ public class AMQProtocolHandler extends IoHandlerAdapter public MethodRegistry getMethodRegistry() { - return getStateManager().getMethodRegistry(); + return _protocolSession.getMethodRegistry(); } public ProtocolVersion getProtocolVersion() diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java index 6e782e0bfc..5e12a5e6f8 100644 --- a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java +++ b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java @@ -30,7 +30,6 @@ import org.slf4j.LoggerFactory; import javax.jms.JMSException; import javax.security.sasl.SaslClient; -import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -38,13 +37,14 @@ import org.apache.qpid.AMQException; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.ConnectionTuneParameters; -import org.apache.qpid.client.message.ReturnMessage; import org.apache.qpid.client.message.UnprocessedMessage; import org.apache.qpid.client.message.UnprocessedMessage_0_8; import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.AMQState; import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQVersionAwareProtocolSession; +import org.apache.qpid.transport.Sender; import org.apache.qpid.client.handler.ClientMethodDispatcherImpl; /** @@ -67,8 +67,6 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession protected final IoSession _minaProtocolSession; - private AMQStateManager _stateManager; - protected WriteFuture _lastWriteFuture; /** @@ -86,7 +84,7 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession * Maps from a channel id to an unprocessed message. This is used to tie together the JmsDeliverBody (which arrives * first) with the subsequent content header and content bodies. */ - private final ConcurrentMap<Integer,UnprocessedMessage> _channelId2UnprocessedMsgMap = new ConcurrentHashMap<Integer,UnprocessedMessage>(); + private final ConcurrentMap<Integer, UnprocessedMessage> _channelId2UnprocessedMsgMap = new ConcurrentHashMap<Integer, UnprocessedMessage>(); private final UnprocessedMessage[] _channelId2UnprocessedMsgArray = new UnprocessedMessage[16]; /** Counter to ensure unique queue names */ @@ -97,26 +95,17 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession // private VersionSpecificRegistry _registry = // MainRegistry.getVersionSpecificRegistry(ProtocolVersion.getLatestSupportedVersion()); - private MethodRegistry _methodRegistry = MethodRegistry.getMethodRegistry(ProtocolVersion.getLatestSupportedVersion()); - private MethodDispatcher _methodDispatcher; + protected final AMQConnection _connection; - private final AMQConnection _connection; private static final int FAST_CHANNEL_ACCESS_MASK = 0xFFFFFFF0; public AMQProtocolSession(AMQProtocolHandler protocolHandler, IoSession protocolSession, AMQConnection connection) { - this(protocolHandler, protocolSession, connection, new AMQStateManager()); - - } - - public AMQProtocolSession(AMQProtocolHandler protocolHandler, IoSession protocolSession, AMQConnection connection, - AMQStateManager stateManager) - { _protocolHandler = protocolHandler; _minaProtocolSession = protocolSession; _minaProtocolSession.setAttachment(this); @@ -124,20 +113,27 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession _minaProtocolSession.setAttribute(AMQ_CONNECTION, connection); // fixme - real value needed _minaProtocolSession.setWriteTimeout(LAST_WRITE_FUTURE_JOIN_TIMEOUT); - _stateManager = stateManager; - _stateManager.setProtocolSession(this); _protocolVersion = connection.getProtocolVersion(); _methodDispatcher = ClientMethodDispatcherImpl.newMethodDispatcher(ProtocolVersion.getLatestSupportedVersion(), - stateManager); + this); _connection = connection; } + public AMQProtocolSession(AMQProtocolHandler protocolHandler, AMQConnection connection) + { + _protocolHandler = protocolHandler; + _minaProtocolSession = null; + _protocolVersion = connection.getProtocolVersion(); + _methodDispatcher = ClientMethodDispatcherImpl.newMethodDispatcher(ProtocolVersion.getLatestSupportedVersion(), + this); + _connection = connection; + } + public void init() { // start the process of setting up the connection. This is the first place that // data is written to the server. - _minaProtocolSession.write(new ProtocolInitiation(_connection.getProtocolVersion())); } @@ -161,14 +157,7 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession public AMQStateManager getStateManager() { - return _stateManager; - } - - public void setStateManager(AMQStateManager stateManager) - { - _stateManager = stateManager; - _methodDispatcher = ClientMethodDispatcherImpl.newMethodDispatcher(_protocolVersion, - stateManager); + return _protocolHandler.getStateManager(); } public String getVirtualHost() @@ -193,7 +182,7 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession public SaslClient getSaslClient() { - return (SaslClient) _minaProtocolSession.getAttribute(SASL_CLIENT); + return (SaslClient) _minaProtocolSession.getAttribute(SASL_CLIENT); } /** @@ -235,12 +224,11 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession * * @throws AMQException if this was not expected */ - public void unprocessedMessageReceived(UnprocessedMessage message) throws AMQException - { - final int channelId = message.getChannelId(); - if((channelId & FAST_CHANNEL_ACCESS_MASK) == 0) + public void unprocessedMessageReceived(final int channelId, UnprocessedMessage message) throws AMQException + { + if ((channelId & FAST_CHANNEL_ACCESS_MASK) == 0) { - _channelId2UnprocessedMsgArray[channelId] = message; + _channelId2UnprocessedMsgArray[channelId] = message; } else { @@ -250,18 +238,17 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession public void contentHeaderReceived(int channelId, ContentHeaderBody contentHeader) throws AMQException { - final UnprocessedMessage msg = (channelId & FAST_CHANNEL_ACCESS_MASK) == 0 ? _channelId2UnprocessedMsgArray[channelId] - : _channelId2UnprocessedMsgMap.get(channelId); - + final UnprocessedMessage_0_8 msg = (UnprocessedMessage_0_8) ((channelId & FAST_CHANNEL_ACCESS_MASK) == 0 ? _channelId2UnprocessedMsgArray[channelId] + : _channelId2UnprocessedMsgMap.get(channelId)); if (msg == null) { - throw new AMQException(null, "Error: received content header without having received a BasicDeliver frame first", null); + throw new AMQException(null, "Error: received content header without having received a BasicDeliver frame first on session:" + this, null); } if (msg.getContentHeader() != null) { - throw new AMQException(null, "Error: received duplicate content header or did not receive correct number of content body frames", null); + throw new AMQException(null, "Error: received duplicate content header or did not receive correct number of content body frames on session:" + this, null); } msg.setContentHeader(contentHeader); @@ -275,7 +262,7 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession { UnprocessedMessage_0_8 msg; final boolean fastAccess = (channelId & FAST_CHANNEL_ACCESS_MASK) == 0; - if(fastAccess) + if (fastAccess) { msg = (UnprocessedMessage_0_8) _channelId2UnprocessedMsgArray[channelId]; } @@ -291,7 +278,7 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession if (msg.getContentHeader() == null) { - if(fastAccess) + if (fastAccess) { _channelId2UnprocessedMsgArray[channelId] = null; } @@ -302,15 +289,7 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession throw new AMQException(null, "Error: received content body without having received a ContentHeader frame first", null); } - /*try - {*/ msg.receiveBody(contentBody); - /*} - catch (UnexpectedBodyReceivedException e) - { - _channelId2UnprocessedMsgMap.remove(channelId); - throw e; - }*/ if (msg.isAllBodyDataReceived()) { @@ -333,7 +312,7 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession { AMQSession session = getSession(channelId); session.messageReceived(msg); - if((channelId & FAST_CHANNEL_ACCESS_MASK) == 0) + if ((channelId & FAST_CHANNEL_ACCESS_MASK) == 0) { _channelId2UnprocessedMsgArray[channelId] = null; } @@ -431,12 +410,12 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession return (AMQConnection) _minaProtocolSession.getAttribute(AMQ_CONNECTION); } - public void closeProtocolSession() + public void closeProtocolSession() throws AMQException { closeProtocolSession(true); } - public void closeProtocolSession(boolean waitLast) + public void closeProtocolSession(boolean waitLast) throws AMQException { _logger.debug("Waiting for last write to join."); if (waitLast && (_lastWriteFuture != null)) @@ -445,7 +424,15 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession } _logger.debug("Closing protocol session"); + final CloseFuture future = _minaProtocolSession.close(); + + // There is no recovery we can do if the join on the close failes so simply mark the connection CLOSED + // then wait for the connection to close. + // ritchiem: Could this release BlockingWaiters to early? The close has been done as much as possible so any + // error now shouldn't matter. + + _protocolHandler.getStateManager().changeState(AMQState.CONNECTION_CLOSED); future.join(LAST_WRITE_FUTURE_JOIN_TIMEOUT); } @@ -482,16 +469,16 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession { final AMQSession session = getSession(channelId); - session.confirmConsumerCancelled(consumerTag); + session.confirmConsumerCancelled(consumerTag.toIntValue()); } public void setProtocolVersion(final ProtocolVersion pv) { _protocolVersion = pv; _methodRegistry = MethodRegistry.getMethodRegistry(pv); - _methodDispatcher = ClientMethodDispatcherImpl.newMethodDispatcher(pv, _stateManager); + _methodDispatcher = ClientMethodDispatcherImpl.newMethodDispatcher(pv, this); - // _registry = MainRegistry.getVersionSpecificRegistry(versionMajor, versionMinor); + // _registry = MainRegistry.getVersionSpecificRegistry(versionMajor, versionMinor); } public byte getProtocolMinorVersion() @@ -524,12 +511,12 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession return _methodDispatcher; } - public void setTicket(int ticket, int channelId) { final AMQSession session = getSession(channelId); session.setTicket(ticket); } + public void setMethodDispatcher(MethodDispatcher methodDispatcher) { _methodDispatcher = methodDispatcher; @@ -545,4 +532,14 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession { _protocolHandler.methodBodyReceived(channel, amqMethodBody, _minaProtocolSession); } + + public void notifyError(Exception error) + { + _protocolHandler.propagateExceptionToAllWaiters(error); + } + + public void setSender(Sender<java.nio.ByteBuffer> sender) + { + // No-op, interface munging + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/BlockingMethodFrameListener.java b/java/client/src/main/java/org/apache/qpid/client/protocol/BlockingMethodFrameListener.java index 0ab2e07340..2bc609ebf2 100644 --- a/java/client/src/main/java/org/apache/qpid/client/protocol/BlockingMethodFrameListener.java +++ b/java/client/src/main/java/org/apache/qpid/client/protocol/BlockingMethodFrameListener.java @@ -20,9 +20,14 @@ */ package org.apache.qpid.client.protocol; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + import org.apache.qpid.AMQException; import org.apache.qpid.AMQTimeoutException; import org.apache.qpid.client.failover.FailoverException; +import org.apache.qpid.client.util.BlockingWaiter; import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQMethodListener; @@ -54,38 +59,17 @@ import org.apache.qpid.protocol.AMQMethodListener; * </table> * * @todo Might be neater if this method listener simply wrapped another that provided the method handling using a - * methodRecevied method. The processMethod takes an additional channelId, however none of the implementations - * seem to use it. So wrapping the listeners is possible. - * - * @todo What is to stop a blocking method listener, receiving a second method whilst it is registered as a listener, - * overwriting the first one before the caller of the block method has had a chance to examine it? If one-shot - * behaviour is to be intended it should be enforced, perhaps by always returning false once the blocked for - * method has been received. - * - * @todo Interuption is caught but not handled. This could be allowed to fall through. This might actually be usefull - * for fail-over where a thread is blocking when failure happens, it could be interrupted to abandon or retry - * when this happens. At the very least, restore the interrupted status flag. - * + * methodRecevied method. The processMethod takes an additional channelId, however none of the implementations + * seem to use it. So wrapping the listeners is possible. * @todo If the retrotranslator can handle it, could use a SynchronousQueue to implement this rendezvous. Need to - * check that SynchronousQueue has a non-blocking put method available. + * check that SynchronousQueue has a non-blocking put method available. */ -public abstract class BlockingMethodFrameListener implements AMQMethodListener +public abstract class BlockingMethodFrameListener extends BlockingWaiter<AMQMethodEvent> implements AMQMethodListener { - /** This flag is used to indicate that the blocked for method has been received. */ - private volatile boolean _ready = false; - - /** Used to protect the shared event and ready flag between the producer and consumer. */ - private final Object _lock = new Object(); - - /** Used to hold the most recent exception that is passed to the {@link #error(Exception)} method. */ - private volatile Exception _error; /** Holds the channel id for the channel upon which this listener is waiting for a response. */ protected int _channelId; - /** Holds the incoming method. */ - protected AMQMethodEvent _doneEvt = null; - /** * Creates a new method listener, that filters incoming method to just those that match the specified channel id. * @@ -104,7 +88,14 @@ public abstract class BlockingMethodFrameListener implements AMQMethodListener * * @return <tt>true</tt> if the method was handled, <tt>false</tt> otherwise. */ - public abstract boolean processMethod(int channelId, AMQMethodBody frame); // throws AMQException; + public abstract boolean processMethod(int channelId, AMQMethodBody frame); + + public boolean process(AMQMethodEvent evt) + { + AMQMethodBody method = evt.getMethod(); + + return (evt.getChannelId() == _channelId) && processMethod(evt.getChannelId(), method); + } /** * Informs this listener that an AMQP method has been received. @@ -113,37 +104,9 @@ public abstract class BlockingMethodFrameListener implements AMQMethodListener * * @return <tt>true</tt> if this listener has handled the method, <tt>false</tt> otherwise. */ - public boolean methodReceived(AMQMethodEvent evt) // throws AMQException + public boolean methodReceived(AMQMethodEvent evt) { - AMQMethodBody method = evt.getMethod(); - - /*try - {*/ - boolean ready = (evt.getChannelId() == _channelId) && processMethod(evt.getChannelId(), method); - - if (ready) - { - // we only update the flag from inside the synchronized block - // so that the blockForFrame method cannot "miss" an update - it - // will only ever read the flag from within the synchronized block - synchronized (_lock) - { - _doneEvt = evt; - _ready = ready; - _lock.notify(); - } - } - - return ready; - - /*} - catch (AMQException e) - { - error(e); - // we rethrow the error here, and the code in the frame dispatcher will go round - // each listener informing them that an exception has been thrown - throw e; - }*/ + return received(evt); } /** @@ -159,75 +122,15 @@ public abstract class BlockingMethodFrameListener implements AMQMethodListener */ public AMQMethodEvent blockForFrame(long timeout) throws AMQException, FailoverException { - synchronized (_lock) + try { - while (!_ready) - { - try - { - if (timeout == -1) - { - _lock.wait(); - } - else - { - - _lock.wait(timeout); - if (!_ready) - { - _error = new AMQTimeoutException("Server did not respond in a timely fashion", null); - _ready = true; - } - } - } - catch (InterruptedException e) - { - // IGNORE -- //fixme this isn't ideal as being interrupted isn't equivellant to sucess - // if (!_ready && timeout != -1) - // { - // _error = new AMQException("Server did not respond timely"); - // _ready = true; - // } - } - } + return (AMQMethodEvent) block(timeout); } - - if (_error != null) + finally { - if (_error instanceof AMQException) - { - throw (AMQException) _error; - } - else if (_error instanceof FailoverException) - { - // This should ensure that FailoverException is not wrapped and can be caught. - throw (FailoverException) _error; // needed to expose FailoverException. - } - else - { - throw new AMQException(null, "Woken up due to " + _error.getClass(), _error); - } + //Prevent any more errors being notified to this waiter. + close(); } - - return _doneEvt; } - /** - * This is a callback, called by the MINA dispatcher thread only. It is also called from within this - * class to avoid code repetition but again is only called by the MINA dispatcher thread. - * - * @param e - */ - public void error(Exception e) - { - // set the error so that the thread that is blocking (against blockForFrame()) - // can pick up the exception and rethrow to the caller - _error = e; - - synchronized (_lock) - { - _ready = true; - _lock.notify(); - } - } } diff --git a/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java b/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java index eda1a1f5fd..f8645139f2 100644 --- a/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java +++ b/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java @@ -28,15 +28,28 @@ import org.apache.qpid.protocol.AMQMethodListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Iterator; import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; /** - * The state manager is responsible for managing the state of the protocol session. <p/> For each AMQProtocolHandler - * there is a separate state manager. + * The state manager is responsible for managing the state of the protocol session. <p/> + * For each {@link org.apache.qpid.client.protocol.AMQProtocolHandler} there is a separate state manager. + * + * The AMQStateManager is now attached to the {@link org.apache.qpid.client.protocol.AMQProtocolHandler} and that is the sole point of reference so that + * As the {@link AMQProtocolSession} changes due to failover the AMQStateManager need not be copied around. + * + * The StateManager works by any component can wait for a state change to occur by using the following sequence. + * + * <li>StateWaiter waiter = stateManager.createWaiter(Set<AMQState> states); + * <li> // Perform action that will cause state change + * <li>waiter.await(); + * + * The two step process is required as there is an inherit race condition between starting a process that will cause + * the state to change and then attempting to wait for that change. The interest in the change must be first set up so + * that any asynchrous errors that occur can be delivered to the correct waiters. */ -public class AMQStateManager +public class AMQStateManager implements AMQMethodListener { private static final Logger _logger = LoggerFactory.getLogger(AMQStateManager.class); @@ -45,16 +58,13 @@ public class AMQStateManager /** The current state */ private AMQState _currentState; - - /** - * Maps from an AMQState instance to a Map from Class to StateTransitionHandler. The class must be a subclass of - * AMQFrame. - */ - - private final Object _stateLock = new Object(); + private static final long MAXIMUM_STATE_WAIT_TIME = Long.parseLong(System.getProperty("amqj.MaximumStateWait", "30000")); + protected final List<StateWaiter> _waiters = new CopyOnWriteArrayList<StateWaiter>(); + private Exception _lastException; + public AMQStateManager() { this(null); @@ -62,18 +72,15 @@ public class AMQStateManager public AMQStateManager(AMQProtocolSession protocolSession) { - this(AMQState.CONNECTION_NOT_STARTED, true, protocolSession); + this(AMQState.CONNECTION_NOT_STARTED, protocolSession); } - protected AMQStateManager(AMQState state, boolean register, AMQProtocolSession protocolSession) + protected AMQStateManager(AMQState state, AMQProtocolSession protocolSession) { _protocolSession = protocolSession; _currentState = state; - } - - public AMQState getCurrentState() { return _currentState; @@ -86,107 +93,107 @@ public class AMQStateManager synchronized (_stateLock) { _currentState = newState; - _stateLock.notifyAll(); + + _logger.debug("Notififying State change to " + _waiters.size() + " : " + _waiters); + + for (StateWaiter waiter : _waiters) + { + waiter.received(newState); + } } } - public <B extends AMQMethodBody> boolean methodReceived(AMQMethodEvent<B> evt) throws AMQException { - B method = evt.getMethod(); - + // StateAwareMethodListener handler = findStateTransitionHandler(_currentState, evt.getMethod()); method.execute(_protocolSession.getMethodDispatcher(), evt.getChannelId()); return true; } - - public void attainState(final AMQState s) throws AMQException + /** + * Setting of the ProtocolSession will be required when Failover has been successfuly compeleted. + * + * The new {@link AMQProtocolSession} that has been re-established needs to be provided as that is now the + * connection to the network. + * + * @param session The new protocol session + */ + public void setProtocolSession(AMQProtocolSession session) { - synchronized (_stateLock) + if (_logger.isInfoEnabled()) { - final long waitUntilTime = System.currentTimeMillis() + MAXIMUM_STATE_WAIT_TIME; - long waitTime = MAXIMUM_STATE_WAIT_TIME; - - while ((_currentState != s) && (waitTime > 0)) - { - try - { - _stateLock.wait(MAXIMUM_STATE_WAIT_TIME); - } - catch (InterruptedException e) - { - _logger.warn("Thread interrupted"); - } - - if (_currentState != s) - { - waitTime = waitUntilTime - System.currentTimeMillis(); - } - } - - if (_currentState != s) - { - _logger.warn("State not achieved within permitted time. Current state " + _currentState - + ", desired state: " + s); - throw new AMQException(null, "State not achieved within permitted time. Current state " + _currentState - + ", desired state: " + s, null); - } + _logger.info("Setting ProtocolSession:" + session); } - - // at this point the state will have changed. + _protocolSession = session; } - public AMQProtocolSession getProtocolSession() + /** + * Propogate error to waiters + * + * @param error The error to propogate. + */ + public void error(Exception error) { - return _protocolSession; + if (_waiters.size() == 0) + { + _logger.error("No Waiters for error saving as last error:" + error.getMessage()); + _lastException = error; + } + for (StateWaiter waiter : _waiters) + { + _logger.error("Notifying Waiters(" + _waiters + ") for error:" + error.getMessage()); + waiter.error(error); + } } - public void setProtocolSession(AMQProtocolSession session) + /** + * This provides a single place that the maximum time for state change to occur can be accessed. + * It is currently set via System property amqj.MaximumStateWait + * + * @return long Milliseconds value for a timeout + */ + public long getWaitTimeout() { - _protocolSession = session; + return MAXIMUM_STATE_WAIT_TIME; } - public MethodRegistry getMethodRegistry() + /** + * Create and add a new waiter to the notifcation list. + * + * @param states The waiter will attempt to wait for one of these desired set states to be achived. + * + * @return the created StateWaiter. + */ + public StateWaiter createWaiter(Set<AMQState> states) { - return getProtocolSession().getMethodRegistry(); + final StateWaiter waiter; + synchronized (_stateLock) + { + waiter = new StateWaiter(this, _currentState, states); + + _waiters.add(waiter); + } + + return waiter; } - public AMQState attainState(Set<AMQState> stateSet) throws AMQException + /** + * Remove the waiter from the notification list. + * + * @param waiter The waiter to remove. + */ + public void removeWaiter(StateWaiter waiter) { synchronized (_stateLock) { - final long waitUntilTime = System.currentTimeMillis() + MAXIMUM_STATE_WAIT_TIME; - long waitTime = MAXIMUM_STATE_WAIT_TIME; - - while (!stateSet.contains(_currentState) && (waitTime > 0)) - { - try - { - _stateLock.wait(MAXIMUM_STATE_WAIT_TIME); - } - catch (InterruptedException e) - { - _logger.warn("Thread interrupted"); - } - - if (!stateSet.contains(_currentState)) - { - waitTime = waitUntilTime - System.currentTimeMillis(); - } - } - - if (!stateSet.contains(_currentState)) - { - _logger.warn("State not achieved within permitted time. Current state " + _currentState - + ", desired state: " + stateSet); - throw new AMQException(null, "State not achieved within permitted time. Current state " + _currentState - + ", desired state: " + stateSet, null); - } - return _currentState; + _waiters.remove(waiter); } + } - + public Exception getLastException() + { + return _lastException; } } diff --git a/java/client/src/main/java/org/apache/qpid/client/state/StateAwareMethodListener.java b/java/client/src/main/java/org/apache/qpid/client/state/StateAwareMethodListener.java index 8c65f56af3..17d04f4fa3 100644 --- a/java/client/src/main/java/org/apache/qpid/client/state/StateAwareMethodListener.java +++ b/java/client/src/main/java/org/apache/qpid/client/state/StateAwareMethodListener.java @@ -33,6 +33,6 @@ import org.apache.qpid.protocol.AMQMethodEvent; public interface StateAwareMethodListener<B extends AMQMethodBody> { - void methodReceived(AMQStateManager stateManager, B body, int channelId) throws AMQException; + void methodReceived(AMQProtocolSession session, B body, int channelId) throws AMQException; } diff --git a/java/client/src/main/java/org/apache/qpid/client/state/StateWaiter.java b/java/client/src/main/java/org/apache/qpid/client/state/StateWaiter.java index 8b8453a1b0..4695b195d5 100644 --- a/java/client/src/main/java/org/apache/qpid/client/state/StateWaiter.java +++ b/java/client/src/main/java/org/apache/qpid/client/state/StateWaiter.java @@ -20,103 +20,110 @@ */ package org.apache.qpid.client.state; +import org.apache.qpid.client.util.BlockingWaiter; +import org.apache.qpid.client.failover.FailoverException; import org.apache.qpid.AMQException; - -import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.slf4j.Logger; + +import java.util.Set; /** - * Waits for a particular state to be reached. + * This is an implementation of the {@link BlockingWaiter} to provide error handing and a waiting mechanism for state + * changes. + * + * On construction the current state and a set of States to await for is provided. + * + * When await() is called the state at constuction is compared against the awaitStates. If the state at construction is + * a desired state then await() returns immediately. + * + * Otherwise it will block for the set timeout for a desired state to be achieved. + * + * The state changes are notified via the {@link #process} method. + * + * Any notified error is handled by the BlockingWaiter and thrown from the {@link #block} method. + * */ -public class StateWaiter implements StateListener +public class StateWaiter extends BlockingWaiter<AMQState> { private static final Logger _logger = LoggerFactory.getLogger(StateWaiter.class); - private final AMQState _state; - - private volatile boolean _newStateAchieved; - - private volatile Throwable _throwable; - - private final Object _monitor = new Object(); - private static final long TIME_OUT = 1000 * 60 * 2; - - public StateWaiter(AMQState state) + Set<AMQState> _awaitStates; + private AMQState _startState; + private AMQStateManager _stateManager; + + /** + * + * @param stateManager The StateManager + * @param currentState + * @param awaitStates + */ + public StateWaiter(AMQStateManager stateManager, AMQState currentState, Set<AMQState> awaitStates) { - _state = state; + _logger.info("New StateWaiter :" + currentState + ":" + awaitStates); + _stateManager = stateManager; + _awaitStates = awaitStates; + _startState = currentState; } - public void waituntilStateHasChanged() throws AMQException + /** + * When the state is changed this StateWaiter is notified to process the change. + * + * @param state The new state that has been achieved. + * @return + */ + public boolean process(AMQState state) { - synchronized (_monitor) - { - // - // The guard is required in case we are woken up by a spurious - // notify(). - // - while (!_newStateAchieved && (_throwable == null)) - { - try - { - _logger.debug("State " + _state + " not achieved so waiting..."); - _monitor.wait(TIME_OUT); - // fixme this won't cause the timeout to exit the loop. need to set _throwable - } - catch (InterruptedException e) - { - _logger.debug("Interrupted exception caught while waiting: " + e, e); - } - } - } + return _awaitStates.contains(state); + } - if (_throwable != null) - { - _logger.debug("Throwable reached state waiter: " + _throwable); - if (_throwable instanceof AMQException) - { - throw (AMQException) _throwable; - } - else - { - throw new AMQException(null, "Error: " + _throwable, _throwable); // FIXME: this will wrap FailoverException in throwable which will prevent it being caught. - } - } + /** + * Await for the requried State to be achieved within the default timeout. + * @return The achieved state that was requested. + * @throws AMQException The exception that prevented the required state from being achived. + */ + public AMQState await() throws AMQException + { + return await(_stateManager.getWaitTimeout()); } - public void stateChanged(AMQState oldState, AMQState newState) + /** + * Await for the requried State to be achieved. + * + * <b>It is the responsibility of this class to remove the waiter from the StateManager + * + * @param timeout The time in milliseconds to wait for any of the states to be achived. + * @return The achieved state that was requested. + * @throws AMQException The exception that prevented the required state from being achived. + */ + public AMQState await(long timeout) throws AMQException { - synchronized (_monitor) + try { - if (_logger.isDebugEnabled()) + if (process(_startState)) { - _logger.debug("stateChanged called changing from :" + oldState + " to :" + newState); + return _startState; } - if (_state == newState) + try { - _newStateAchieved = true; - - if (_logger.isDebugEnabled()) - { - _logger.debug("New state reached so notifying monitor"); - } + return (AMQState) block(timeout); + } + catch (FailoverException e) + { + _logger.error("Failover occured whilst waiting for states:" + _awaitStates); - _monitor.notifyAll(); + e.printStackTrace(); + return null; } } - } - - public void error(Throwable t) - { - synchronized (_monitor) + finally { - if (_logger.isDebugEnabled()) - { - _logger.debug("exceptionThrown called"); - } + //Prevent any more errors being notified to this waiter. + close(); - _throwable = t; - _monitor.notifyAll(); + //Remove the waiter from the notifcation list in the statee manager + _stateManager.removeWaiter(this); } } } diff --git a/java/client/src/main/java/org/apache/qpid/client/state/listener/SpecificMethodFrameListener.java b/java/client/src/main/java/org/apache/qpid/client/state/listener/SpecificMethodFrameListener.java index 623591e0b6..f0d7feb059 100644 --- a/java/client/src/main/java/org/apache/qpid/client/state/listener/SpecificMethodFrameListener.java +++ b/java/client/src/main/java/org/apache/qpid/client/state/listener/SpecificMethodFrameListener.java @@ -20,7 +20,7 @@ */ package org.apache.qpid.client.state.listener; -import org.apache.qpid.AMQException; + import org.apache.qpid.client.protocol.BlockingMethodFrameListener; import org.apache.qpid.framing.AMQMethodBody; @@ -34,7 +34,7 @@ public class SpecificMethodFrameListener extends BlockingMethodFrameListener _expectedClass = expectedClass; } - public boolean processMethod(int channelId, AMQMethodBody frame) //throws AMQException + public boolean processMethod(int channelId, AMQMethodBody frame) { return _expectedClass.isInstance(frame); } diff --git a/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java b/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java index a871c754b5..6c12821c74 100644 --- a/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java +++ b/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java @@ -40,7 +40,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.net.Socket; - /** * The TransportConnection is a helper class responsible for connecting to an AMQ server. It sets up the underlying * connector, which currently always uses TCP/IP sockets. It creates the "protocol handler" which deals with MINA @@ -85,38 +84,18 @@ public class TransportConnection throw new AMQNoTransportForProtocolException(details, null, null); } - /* if (transport == _currentInstance) - { - if (transport == VM) - { - if (_currentVMPort == details.getPort()) - { - return _instance; - } - } - else - { - return _instance; - } - } - - _currentInstance = transport;*/ - - ITransportConnection instance; switch (transport) { case SOCKET: - instance = - new SocketTransportConnection(new SocketTransportConnection.SocketConnectorFactory() - { - public IoConnector newSocketConnector() - { - return new ExistingSocketConnector(); - } - }); - break; + return new SocketTransportConnection(new SocketTransportConnection.SocketConnectorFactory() + { + public IoConnector newSocketConnector() + { + return new ExistingSocketConnector(); + } + }); case TCP: - instance = new SocketTransportConnection(new SocketTransportConnection.SocketConnectorFactory() + return new SocketTransportConnection(new SocketTransportConnection.SocketConnectorFactory() { public IoConnector newSocketConnector() { @@ -125,8 +104,8 @@ public class TransportConnection if (Boolean.getBoolean("qpidnio")) { _logger.warn("Using Qpid MultiThreaded NIO - " + (System.getProperties().containsKey("qpidnio") - ? "Qpid NIO is new default" - : "Sysproperty 'qpidnio' is set")); + ? "Qpid NIO is new default" + : "Sysproperty 'qpidnio' is set")); result = new MultiThreadSocketConnector(); } else @@ -141,18 +120,13 @@ public class TransportConnection return result; } }); - break; case VM: { - instance = getVMTransport(details, Boolean.getBoolean("amqj.AutoCreateVMBroker")); - break; + return getVMTransport(details, Boolean.getBoolean("amqj.AutoCreateVMBroker")); } default: - // FIXME: TGM - throw new AMQNoTransportForProtocolException(details, null, null); + throw new AMQNoTransportForProtocolException(details, "Transport not recognised:" + transport, null); } - - return instance; } private static int getTransport(String transport) @@ -180,13 +154,22 @@ public class TransportConnection { int port = details.getPort(); - if (!_inVmPipeAddress.containsKey(port)) + synchronized (_inVmPipeAddress) { - if (AutoCreate) + if (!_inVmPipeAddress.containsKey(port)) { if (AutoCreate) { - createVMBroker(port); + if (AutoCreate) + { + _logger.warn("Auto Creating InVM Broker on port:" + port); + createVMBroker(port); + } + else + { + throw new AMQVMBrokerCreationException(null, port, "VM Broker on port " + port + + " does not exist. Auto create disabled.", null); + } } else { @@ -194,11 +177,6 @@ public class TransportConnection + " does not exist. Auto create disabled.", null); } } - else - { - throw new AMQVMBrokerCreationException(null, port, "VM Broker on port " + port - + " does not exist. Auto create disabled.", null); - } } return new VmPipeTransportConnection(port); @@ -214,70 +192,73 @@ public class TransportConnection config.setThreadModel(ReadWriteThreadModel.getInstance()); } - - if (!_inVmPipeAddress.containsKey(port)) + synchronized (_inVmPipeAddress) { - _logger.info("Creating InVM Qpid.AMQP listening on port " + port); - IoHandlerAdapter provider = null; - try - { - VmPipeAddress pipe = new VmPipeAddress(port); - - provider = createBrokerInstance(port); - - _acceptor.bind(pipe, provider); - _inVmPipeAddress.put(port, pipe); - _logger.info("Created InVM Qpid.AMQP listening on port " + port); - } - catch (IOException e) + if (!_inVmPipeAddress.containsKey(port)) { - _logger.error("Got IOException.", e); - - // Try and unbind provider + _logger.info("Creating InVM Qpid.AMQP listening on port " + port); + IoHandlerAdapter provider = null; try { VmPipeAddress pipe = new VmPipeAddress(port); - try - { - _acceptor.unbind(pipe); - } - catch (Exception ignore) - { - // ignore - } - - if (provider == null) - { - provider = createBrokerInstance(port); - } + provider = createBrokerInstance(port); _acceptor.bind(pipe, provider); + _inVmPipeAddress.put(port, pipe); _logger.info("Created InVM Qpid.AMQP listening on port " + port); } - catch (IOException justUseFirstException) + catch (IOException e) { - String because; - if (e.getCause() == null) + _logger.error("Got IOException.", e); + + // Try and unbind provider + try { - because = e.toString(); + VmPipeAddress pipe = new VmPipeAddress(port); + + try + { + _acceptor.unbind(pipe); + } + catch (Exception ignore) + { + // ignore + } + + if (provider == null) + { + provider = createBrokerInstance(port); + } + + _acceptor.bind(pipe, provider); + _inVmPipeAddress.put(port, pipe); + _logger.info("Created InVM Qpid.AMQP listening on port " + port); } - else + catch (IOException justUseFirstException) { - because = e.getCause().toString(); - } + String because; + if (e.getCause() == null) + { + because = e.toString(); + } + else + { + because = e.getCause().toString(); + } - throw new AMQVMBrokerCreationException(null, port, because + " Stopped binding of InVM Qpid.AMQP", e); + throw new AMQVMBrokerCreationException(null, port, because + " Stopped binding of InVM Qpid.AMQP", e); + } } + + } + else + { + _logger.info("InVM Qpid.AMQP on port " + port + " already exits."); } } - else - { - _logger.info("InVM Qpid.AMQP on port " + port + " already exits."); - } - } private static IoHandlerAdapter createBrokerInstance(int port) throws AMQVMBrokerCreationException @@ -324,7 +305,7 @@ public class TransportConnection _logger.info("Killing all VM Brokers"); if (_acceptor != null) { - _acceptor.unbindAll(); + _acceptor.unbindAll(); } synchronized (_inVmPipeAddress) { @@ -337,14 +318,17 @@ public class TransportConnection public static void killVMBroker(int port) { - VmPipeAddress pipe = (VmPipeAddress) _inVmPipeAddress.get(port); - if (pipe != null) + synchronized (_inVmPipeAddress) { - _logger.info("Killing VM Broker:" + port); - _inVmPipeAddress.remove(port); - // This does need to be sychronized as otherwise mina can hang - // if a new connection is made - _acceptor.unbind(pipe); + VmPipeAddress pipe = (VmPipeAddress) _inVmPipeAddress.get(port); + if (pipe != null) + { + _logger.info("Killing VM Broker:" + port); + _inVmPipeAddress.remove(port); + // This does need to be sychronized as otherwise mina can hang + // if a new connection is made + _acceptor.unbind(pipe); + } } } diff --git a/java/client/src/main/java/org/apache/qpid/client/util/BlockingWaiter.java b/java/client/src/main/java/org/apache/qpid/client/util/BlockingWaiter.java new file mode 100644 index 0000000000..67cda957fb --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/util/BlockingWaiter.java @@ -0,0 +1,348 @@ +/* + * + * 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.qpid.client.util; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import org.apache.qpid.AMQException; +import org.apache.qpid.AMQTimeoutException; +import org.apache.qpid.client.failover.FailoverException; +import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.protocol.AMQMethodEvent; +import org.apache.qpid.protocol.AMQMethodListener; + +/** + * BlockingWaiter is a 'rendezvous' which delegates handling of + * incoming Objects to a listener implemented as a sub-class of this and hands off the process or + * error to a consumer. The producer of the event does not have to wait for the consumer to take the event, so this + * differs from a 'rendezvous' in that sense. + * + * <p/>BlockingWaiters are used to coordinate when waiting for an an event that expect a response. + * They are always used in a 'one-shot' manner, that is, to recieve just one response. Usually the caller has to register + * them as method listeners with an event dispatcher and remember to de-register them (in a finally block) once they + * have been completed. + * + * <p/>The {@link #process} must return <tt>true</tt> on any incoming method that it handles. This indicates to + * this listeners that the object just processed ends the waiting process. + * + * <p/>Errors from the producer are rethrown to the consumer. + * + * <p/><table id="crc"><caption>CRC Card</caption> + * <tr><th> Responsibilities <th> Collaborations </td> + * <tr><td> Accept generic objects as events for processing via {@link #process}. <td> + * <tr><td> Delegate handling and undserstanding of the object to a concrete implementation. <td> + * <tr><td> Block until {@link #process} determines that waiting is no longer required <td> + * <tr><td> Propagate the most recent exception to the consumer.<td> + * </table> + * + * @todo Interuption is caught but not handled. This could be allowed to fall through. This might actually be usefull + * for fail-over where a thread is blocking when failure happens, it could be interrupted to abandon or retry + * when this happens. At the very least, restore the interrupted status flag. + * @todo If the retrotranslator can handle it, could use a SynchronousQueue to implement this rendezvous. Need to + * check that SynchronousQueue has a non-blocking put method available. + */ +public abstract class BlockingWaiter<T> +{ + /** This flag is used to indicate that the blocked for method has been received. */ + private volatile boolean _ready = false; + + /** This flag is used to indicate that the received error has been processed. */ + private volatile boolean _errorAck = false; + + /** Used to protect the shared event and ready flag between the producer and consumer. */ + private final ReentrantLock _lock = new ReentrantLock(); + + /** Used to signal that a method has been received */ + private final Condition _receivedCondition = _lock.newCondition(); + + /** Used to signal that a error has been processed */ + private final Condition _errorConditionAck = _lock.newCondition(); + + /** Used to hold the most recent exception that is passed to the {@link #error(Exception)} method. */ + private volatile Exception _error; + + /** Holds the incomming Object. */ + protected Object _doneObject = null; + private AtomicBoolean _waiting = new AtomicBoolean(false); + private boolean _closed = false; + + /** + * Delegates processing of the incomming object to the handler. + * + * @param object The object to process. + * + * @return <tt>true</tt> if the waiting is complete, <tt>false</tt> if waiting should continue. + */ + public abstract boolean process(T object); + + /** + * An Object has been received and should be processed to see if our wait condition has been reached. + * + * @param object The object received. + * + * @return <tt>true</tt> if the waiting is complete, <tt>false</tt> if waiting should continue. + */ + public boolean received(T object) + { + + boolean ready = process(object); + + if (ready) + { + // we only update the flag from inside the synchronized block + // so that the blockForFrame method cannot "miss" an update - it + // will only ever read the flag from within the synchronized block + _lock.lock(); + try + { + _doneObject = object; + _ready = ready; + _receivedCondition.signal(); + } + finally + { + _lock.unlock(); + } + } + + return ready; + } + + /** + * Blocks until an object is received that is handled by process, or the specified timeout + * has passed. + * + * Once closed any attempt to wait will throw an exception. + * + * @param timeout The timeout in milliseconds. + * + * @return The object that resolved the blocking. + * + * @throws AMQException + * @throws FailoverException + */ + public Object block(long timeout) throws AMQException, FailoverException + { + long nanoTimeout = TimeUnit.MILLISECONDS.toNanos(timeout); + + _lock.lock(); + + try + { + if (_closed) + { + throw throwClosedException(); + } + + if (_error == null) + { + _waiting.set(true); + + while (!_ready) + { + try + { + if (timeout == -1) + { + _receivedCondition.await(); + } + else + { + nanoTimeout = _receivedCondition.awaitNanos(nanoTimeout); + + if (nanoTimeout <= 0 && !_ready && _error == null) + { + _error = new AMQTimeoutException("Server did not respond in a timely fashion", null); + _ready = true; + } + } + } + catch (InterruptedException e) + { + System.err.println(e.getMessage()); + // IGNORE -- //fixme this isn't ideal as being interrupted isn't equivellant to sucess + // if (!_ready && timeout != -1) + // { + // _error = new AMQException("Server did not respond timely"); + // _ready = true; + // } + } + } + } + + if (_error != null) + { + if (_error instanceof AMQException) + { + throw (AMQException) _error; + } + else if (_error instanceof FailoverException) + { + // This should ensure that FailoverException is not wrapped and can be caught. + throw (FailoverException) _error; // needed to expose FailoverException. + } + else + { + throw new AMQException("Woken up due to " + _error.getClass(), _error); + } + } + + } + finally + { + _waiting.set(false); + + //Release Error handling thread + if (_error != null) + { + _errorAck = true; + _errorConditionAck.signal(); + + _error = null; + } + _lock.unlock(); + } + + return _doneObject; + } + + /** + * This is a callback, called when an error has occured that should interupt any waiter. + * It is also called from within this class to avoid code repetition but it should only be called by the MINA threads. + * + * Once closed any notification of an exception will be ignored. + * + * @param e The exception being propogated. + */ + public void error(Exception e) + { + // set the error so that the thread that is blocking (against blockForFrame()) + // can pick up the exception and rethrow to the caller + + _lock.lock(); + + if (_closed) + { + return; + } + + if (_error == null) + { + _error = e; + } + else + { + System.err.println("WARNING: new error arrived while old one not yet processed"); + } + + try + { + if (_waiting.get()) + { + + _ready = true; + _receivedCondition.signal(); + + while (!_errorAck) + { + try + { + _errorConditionAck.await(); + } + catch (InterruptedException e1) + { + System.err.println(e.getMessage()); + } + } + _errorAck = false; + } + } + finally + { + _lock.unlock(); + } + } + + /** + * Close this Waiter so that no more errors are processed. + * This is a preventative method to ensure that a second error thread does not get stuck in the error method after + * the await has returned. This has not happend but in practise but if two errors occur on the Connection at + * the same time then it is conceiveably possible for the second to get stuck if the first one is processed by a + * waiter. + * + * Once closed any attempt to wait will throw an exception. + * Any notification of an exception will be ignored. + */ + public void close() + { + _lock.lock(); + try + { + //if we have already closed then our job is done. + if (_closed) + { + return; + } + + //Close Waiter so no more exceptions are processed + _closed = true; + + //Wake up any await() threads + + //If we are waiting then use the error() to wake them up. + if (_waiting.get()) + { + error(throwClosedException()); + } + //If they are not waiting then there is nothing to do. + + // Wake up any error handling threads + + if (!_errorAck) + { + _errorAck = true; + _errorConditionAck.signal(); + + _error = null; + } + } + finally + { + _lock.unlock(); + } + } + + /** + * Helper method to generate the a closed Exception. + * + * todo: This should be converted to something more friendly. + * + * @return AMQException to throw to waiters when the Waiter is closed. + */ + private AMQException throwClosedException() + { + return new AMQException(null, "Waiter was closed.", null); + } + +} diff --git a/java/client/src/main/java/org/apache/qpid/client/util/FlowControllingBlockingQueue.java b/java/client/src/main/java/org/apache/qpid/client/util/FlowControllingBlockingQueue.java index 0fc39a9318..bddbc329ab 100644 --- a/java/client/src/main/java/org/apache/qpid/client/util/FlowControllingBlockingQueue.java +++ b/java/client/src/main/java/org/apache/qpid/client/util/FlowControllingBlockingQueue.java @@ -21,8 +21,10 @@ package org.apache.qpid.client.util; import java.util.Iterator; +import java.util.Queue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ConcurrentLinkedQueue; /** * A blocking queue that emits events above a user specified threshold allowing the caller to take action (e.g. flow @@ -35,7 +37,7 @@ import java.util.concurrent.LinkedBlockingQueue; public class FlowControllingBlockingQueue { /** This queue is bounded and is used to store messages before being dispatched to the consumer */ - private final BlockingQueue _queue = new LinkedBlockingQueue(); + private final Queue _queue = new ConcurrentLinkedQueue(); private final int _flowControlHighThreshold; private final int _flowControlLowThreshold; @@ -71,7 +73,17 @@ public class FlowControllingBlockingQueue public Object take() throws InterruptedException { - Object o = _queue.take(); + Object o = _queue.poll(); + if(o == null) + { + synchronized(this) + { + while((o = _queue.poll())==null) + { + wait(); + } + } + } if (_listener != null) { synchronized (_listener) @@ -88,7 +100,12 @@ public class FlowControllingBlockingQueue public void add(Object o) { - _queue.add(o); + synchronized(this) + { + _queue.add(o); + + notifyAll(); + } if (_listener != null) { synchronized (_listener) diff --git a/java/client/src/main/java/org/apache/qpidity/filter/ArithmeticExpression.java b/java/client/src/main/java/org/apache/qpid/filter/ArithmeticExpression.java index 279716598d..56d1bdcdc5 100644 --- a/java/client/src/main/java/org/apache/qpidity/filter/ArithmeticExpression.java +++ b/java/client/src/main/java/org/apache/qpid/filter/ArithmeticExpression.java @@ -15,9 +15,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.filter; +package org.apache.qpid.filter; -import org.apache.qpidity.QpidException; +import org.apache.qpid.QpidException; import org.apache.qpid.client.message.AbstractJMSMessage; diff --git a/java/client/src/main/java/org/apache/qpidity/filter/BinaryExpression.java b/java/client/src/main/java/org/apache/qpid/filter/BinaryExpression.java index 465b504ae3..f97f858fad 100644 --- a/java/client/src/main/java/org/apache/qpidity/filter/BinaryExpression.java +++ b/java/client/src/main/java/org/apache/qpid/filter/BinaryExpression.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.filter; +package org.apache.qpid.filter; /** * An expression which performs an operation on two expression values. diff --git a/java/client/src/main/java/org/apache/qpidity/filter/BooleanExpression.java b/java/client/src/main/java/org/apache/qpid/filter/BooleanExpression.java index 9a3b1c3106..cc24c81729 100644 --- a/java/client/src/main/java/org/apache/qpidity/filter/BooleanExpression.java +++ b/java/client/src/main/java/org/apache/qpid/filter/BooleanExpression.java @@ -15,9 +15,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.filter; +package org.apache.qpid.filter; -import org.apache.qpidity.QpidException; +import org.apache.qpid.QpidException; import org.apache.qpid.client.message.AbstractJMSMessage; diff --git a/java/client/src/main/java/org/apache/qpidity/filter/ComparisonExpression.java b/java/client/src/main/java/org/apache/qpid/filter/ComparisonExpression.java index 46f387b293..adf360698b 100644 --- a/java/client/src/main/java/org/apache/qpidity/filter/ComparisonExpression.java +++ b/java/client/src/main/java/org/apache/qpid/filter/ComparisonExpression.java @@ -15,9 +15,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.filter; +package org.apache.qpid.filter; -import org.apache.qpidity.QpidException; +import org.apache.qpid.QpidException; import org.apache.qpid.client.message.AbstractJMSMessage; import java.util.HashSet; diff --git a/java/client/src/main/java/org/apache/qpidity/filter/ConstantExpression.java b/java/client/src/main/java/org/apache/qpid/filter/ConstantExpression.java index 26aeec2de8..447de914a4 100644 --- a/java/client/src/main/java/org/apache/qpidity/filter/ConstantExpression.java +++ b/java/client/src/main/java/org/apache/qpid/filter/ConstantExpression.java @@ -15,9 +15,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.filter; +package org.apache.qpid.filter; -import org.apache.qpidity.QpidException; +import org.apache.qpid.QpidException; import org.apache.qpid.client.message.AbstractJMSMessage; import java.math.BigDecimal; diff --git a/java/client/src/main/java/org/apache/qpidity/filter/Expression.java b/java/client/src/main/java/org/apache/qpid/filter/Expression.java index bdc3c9cccc..e578775a77 100644 --- a/java/client/src/main/java/org/apache/qpidity/filter/Expression.java +++ b/java/client/src/main/java/org/apache/qpid/filter/Expression.java @@ -15,9 +15,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.filter; +package org.apache.qpid.filter; -import org.apache.qpidity.QpidException; +import org.apache.qpid.QpidException; import org.apache.qpid.client.message.AbstractJMSMessage; diff --git a/java/client/src/main/java/org/apache/qpidity/filter/JMSSelectorFilter.java b/java/client/src/main/java/org/apache/qpid/filter/JMSSelectorFilter.java index c73da1682a..dcfb9a9940 100644 --- a/java/client/src/main/java/org/apache/qpidity/filter/JMSSelectorFilter.java +++ b/java/client/src/main/java/org/apache/qpid/filter/JMSSelectorFilter.java @@ -15,12 +15,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.filter; +package org.apache.qpid.filter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.qpidity.QpidException; -import org.apache.qpidity.filter.selector.SelectorParser; +import org.apache.qpid.QpidException; +import org.apache.qpid.filter.selector.SelectorParser; import org.apache.qpid.client.message.AbstractJMSMessage; diff --git a/java/client/src/main/java/org/apache/qpidity/filter/LogicExpression.java b/java/client/src/main/java/org/apache/qpid/filter/LogicExpression.java index 7f5909df43..d7aabd5a46 100644 --- a/java/client/src/main/java/org/apache/qpidity/filter/LogicExpression.java +++ b/java/client/src/main/java/org/apache/qpid/filter/LogicExpression.java @@ -15,9 +15,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.filter; +package org.apache.qpid.filter; -import org.apache.qpidity.QpidException; +import org.apache.qpid.QpidException; import org.apache.qpid.client.message.AbstractJMSMessage; diff --git a/java/client/src/main/java/org/apache/qpidity/filter/MessageFilter.java b/java/client/src/main/java/org/apache/qpid/filter/MessageFilter.java index aa1303a373..a775080d81 100644 --- a/java/client/src/main/java/org/apache/qpidity/filter/MessageFilter.java +++ b/java/client/src/main/java/org/apache/qpid/filter/MessageFilter.java @@ -15,9 +15,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.filter; +package org.apache.qpid.filter; -import org.apache.qpidity.QpidException; +import org.apache.qpid.QpidException; import org.apache.qpid.client.message.AbstractJMSMessage; diff --git a/java/client/src/main/java/org/apache/qpidity/filter/PropertyExpression.java b/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java index 5ea2004d75..2c05f5ce0f 100644 --- a/java/client/src/main/java/org/apache/qpidity/filter/PropertyExpression.java +++ b/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java @@ -15,12 +15,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.filter; +package org.apache.qpid.filter; -import org.apache.qpid.framing.CommonContentHeaderProperties; -import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.client.message.AbstractJMSMessage; -import org.apache.qpidity.QpidException; +import org.apache.qpid.QpidException; +import org.apache.qpid.ErrorCode; import org.slf4j.LoggerFactory; import org.slf4j.Logger; @@ -54,20 +53,7 @@ public class PropertyExpression implements Expression { public Object evaluate(AbstractJMSMessage message) { - try - { - CommonContentHeaderProperties _properties = - message.getContentHeaderProperties(); - AMQShortString replyTo = _properties.getReplyTo(); - - return (replyTo == null) ? null : replyTo.toString(); - } - catch (Exception e) - { - _logger.warn("Error evaluating property", e); - - return null; - } + return message.getReplyToString(); } }); @@ -77,13 +63,9 @@ public class PropertyExpression implements Expression { try { - CommonContentHeaderProperties _properties = - message.getContentHeaderProperties(); - AMQShortString type = _properties.getType(); - - return (type == null) ? null : type.toString(); + return message.getJMSType(); } - catch (Exception e) + catch (JMSException e) { _logger.warn("Error evaluating property", e); @@ -107,7 +89,7 @@ public class PropertyExpression implements Expression return mode; } - catch (Exception e) + catch (JMSException e) { _logger.warn("Error evaluating property",e); } @@ -122,9 +104,7 @@ public class PropertyExpression implements Expression { try { - CommonContentHeaderProperties _properties = - message.getContentHeaderProperties(); - return (int) _properties.getPriority(); + return message.getJMSPriority(); } catch (Exception e) { @@ -142,13 +122,9 @@ public class PropertyExpression implements Expression try { - CommonContentHeaderProperties _properties = - message.getContentHeaderProperties(); - AMQShortString messageId = _properties.getMessageId(); - - return (messageId == null) ? null : messageId; + return message.getJMSMessageID(); } - catch (Exception e) + catch (JMSException e) { _logger.warn("Error evaluating property",e); @@ -164,9 +140,7 @@ public class PropertyExpression implements Expression { try { - CommonContentHeaderProperties _properties = - message.getContentHeaderProperties(); - return _properties.getTimestamp(); + return message.getJMSTimestamp(); } catch (Exception e) { @@ -185,12 +159,9 @@ public class PropertyExpression implements Expression try { - CommonContentHeaderProperties _properties = - message.getContentHeaderProperties(); - AMQShortString correlationId = _properties.getCorrelationId(); - return (correlationId == null) ? null : correlationId.toString(); + return message.getJMSCorrelationID(); } - catch (Exception e) + catch (JMSException e) { _logger.warn("Error evaluating property",e); @@ -207,11 +178,9 @@ public class PropertyExpression implements Expression try { - CommonContentHeaderProperties _properties = - message.getContentHeaderProperties(); - return _properties.getExpiration(); + return message.getJMSExpiration(); } - catch (Exception e) + catch (JMSException e) { _logger.warn("Error evaluating property",e); return null; @@ -257,13 +226,20 @@ public class PropertyExpression implements Expression else { - CommonContentHeaderProperties _properties = message.getContentHeaderProperties(); - if (_logger.isDebugEnabled()) + try + { + + if (_logger.isDebugEnabled()) + { + _logger.debug("Looking up property:" + name); + _logger.debug("Properties are:" + message.getPropertyNames()); + } + return message.getObjectProperty(name); + } + catch(JMSException e) { - _logger.debug("Looking up property:" + name); - _logger.debug("Properties are:" + _properties.getHeaders().keySet()); + throw new QpidException("Exception evaluating properties for filter", ErrorCode.INTERNAL_ERROR, e); } - return _properties.getHeaders().getObject(name); } } diff --git a/java/client/src/main/java/org/apache/qpidity/filter/UnaryExpression.java b/java/client/src/main/java/org/apache/qpid/filter/UnaryExpression.java index f73449679c..b620b107c4 100644 --- a/java/client/src/main/java/org/apache/qpidity/filter/UnaryExpression.java +++ b/java/client/src/main/java/org/apache/qpid/filter/UnaryExpression.java @@ -15,9 +15,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.filter; +package org.apache.qpid.filter; -import org.apache.qpidity.QpidException; +import org.apache.qpid.QpidException; import org.apache.qpid.client.message.AbstractJMSMessage; import java.math.BigDecimal; diff --git a/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java b/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java index 72ba16086d..0316255b2c 100644 --- a/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java +++ b/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java @@ -48,7 +48,7 @@ public interface BrokerDetails public static final long DEFAULT_CONNECT_TIMEOUT = 30000L; public static final boolean USE_SSL_DEFAULT = false; - // pulled these properties from the new BrokerDetails class in the qpidity package + // pulled these properties from the new BrokerDetails class in the qpid package public static final String PROTOCOL_TCP = "tcp"; public static final String PROTOCOL_TLS = "tls"; diff --git a/java/client/src/main/java/org/apache/qpid/jms/Message.java b/java/client/src/main/java/org/apache/qpid/jms/Message.java index e65f9ad2f4..53c615a1fd 100644 --- a/java/client/src/main/java/org/apache/qpid/jms/Message.java +++ b/java/client/src/main/java/org/apache/qpid/jms/Message.java @@ -24,5 +24,7 @@ import javax.jms.JMSException; public interface Message extends javax.jms.Message { + public static final String JMS_TYPE = "x-jms-type"; + public void acknowledgeThis() throws JMSException; } diff --git a/java/client/src/main/java/org/apache/qpidity/naming/ReadOnlyContext.java b/java/client/src/main/java/org/apache/qpid/naming/ReadOnlyContext.java index c73d6e4b35..59ec4cfba7 100644 --- a/java/client/src/main/java/org/apache/qpidity/naming/ReadOnlyContext.java +++ b/java/client/src/main/java/org/apache/qpid/naming/ReadOnlyContext.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.naming; +package org.apache.qpid.naming; import org.apache.qpid.jndi.NameParserImpl; diff --git a/java/client/src/main/java/org/apache/qpidity/naming/jndi.properties b/java/client/src/main/java/org/apache/qpid/naming/jndi.properties index e451cf53fa..830de5f619 100644 --- a/java/client/src/main/java/org/apache/qpidity/naming/jndi.properties +++ b/java/client/src/main/java/org/apache/qpid/naming/jndi.properties @@ -16,7 +16,7 @@ # specific language governing permissions and limitations # under the License. # -java.naming.factory.initial = org.apache.qpidity.naming.PropertiesFileInitialConextFactory +java.naming.factory.initial = org.apache.qpid.naming.PropertiesFileInitialConextFactory # use the following property to configure the default connector #java.naming.provider.url - ignored. diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/Client.java b/java/client/src/main/java/org/apache/qpid/nclient/Client.java index bc88160137..af0e724e42 100644 --- a/java/client/src/main/java/org/apache/qpidity/nclient/Client.java +++ b/java/client/src/main/java/org/apache/qpid/nclient/Client.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.qpidity.nclient; +package org.apache.qpid.nclient; import java.util.List; import java.util.UUID; @@ -25,34 +25,31 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.TimeUnit; import org.apache.qpid.client.url.URLParser_0_10; import org.apache.qpid.jms.BrokerDetails; import org.apache.qpid.url.QpidURL; -import org.apache.qpidity.ErrorCode; -import org.apache.qpidity.QpidException; -import org.apache.qpidity.ProtocolException; -import org.apache.qpidity.nclient.impl.ClientSession; -import org.apache.qpidity.nclient.impl.ClientSessionDelegate; -import org.apache.qpidity.transport.Channel; -import org.apache.qpidity.transport.ClientDelegate; -import org.apache.qpidity.transport.Connection; -import org.apache.qpidity.transport.ConnectionClose; -import org.apache.qpidity.transport.ConnectionCloseCode; -import org.apache.qpidity.transport.ConnectionCloseOk; -import org.apache.qpidity.transport.ConnectionEvent; -import org.apache.qpidity.transport.TransportConstants; -import org.apache.qpidity.transport.ProtocolHeader; -import org.apache.qpidity.transport.SessionDelegate; -import org.apache.qpidity.transport.network.io.IoHandler; -import org.apache.qpidity.transport.network.mina.MinaHandler; -import org.apache.qpidity.transport.network.nio.NioHandler; +import org.apache.qpid.ErrorCode; +import org.apache.qpid.QpidException; +import org.apache.qpid.nclient.impl.ClientSession; +import org.apache.qpid.nclient.impl.ClientSessionDelegate; +import org.apache.qpid.transport.Channel; +import org.apache.qpid.transport.ClientDelegate; +import org.apache.qpid.transport.Connection; +import org.apache.qpid.transport.ConnectionClose; +import org.apache.qpid.transport.ConnectionCloseCode; +import org.apache.qpid.transport.ConnectionCloseOk; +import org.apache.qpid.transport.ProtocolHeader; +import org.apache.qpid.transport.ProtocolVersionException; +import org.apache.qpid.transport.SessionDelegate; +import org.apache.qpid.transport.network.io.IoTransport; +import org.apache.qpid.transport.network.mina.MinaHandler; +import org.apache.qpid.transport.network.nio.NioHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class Client implements org.apache.qpidity.nclient.Connection +public class Client implements org.apache.qpid.nclient.Connection { private Connection _conn; private ClosedListener _closedListner; @@ -60,12 +57,15 @@ public class Client implements org.apache.qpidity.nclient.Connection private static Logger _logger = LoggerFactory.getLogger(Client.class); private Condition closeOk; private boolean closed = false; + private long timeout = 60000; + + private ProtocolHeader header = null; /** * * @return returns a new connection to the broker. */ - public static org.apache.qpidity.nclient.Connection createConnection() + public static org.apache.qpid.nclient.Connection createConnection() { return new Client(); } @@ -80,7 +80,6 @@ public class Client implements org.apache.qpidity.nclient.Connection ClientDelegate connectionDelegate = new ClientDelegate() { private boolean receivedClose = false; - private String _unsupportedProtocol; public SessionDelegate getSessionDelegate() { return new ClientSessionDelegate(); @@ -123,6 +122,7 @@ public class Client implements org.apache.qpidity.nclient.Connection @Override public void connectionClose(Channel context, ConnectionClose connectionClose) { + super.connectionClose(context, connectionClose); ErrorCode errorCode = ErrorCode.get(connectionClose.getReplyCode().getValue()); if (_closedListner == null && errorCode != ErrorCode.NO_ERROR) { @@ -139,28 +139,18 @@ public class Client implements org.apache.qpidity.nclient.Connection this.receivedClose = true; } - @Override public void init(Channel ch, ProtocolHeader hdr) { // TODO: once the merge is done we'll need to update this code - // for handling 0.8 protocol version type i.e. major=8 and minor=0 :( - if (hdr.getMajor() != TransportConstants.getVersionMajor() - || hdr.getMinor() != TransportConstants.getVersionMinor()) + // for handling 0.8 protocol version type i.e. major=8 and mino + if (hdr.getMajor() != 0 || hdr.getMinor() != 10) { - _unsupportedProtocol = TransportConstants.getVersionMajor() + "." + - TransportConstants.getVersionMinor(); - TransportConstants.setVersionMajor( hdr.getMajor() ); - TransportConstants.setVersionMinor( hdr.getMinor() ); + Client.this.header = hdr; _lock.lock(); negotiationComplete.signalAll(); _lock.unlock(); } } - - @Override public String getUnsupportedProtocol() - { - return _unsupportedProtocol; - } }; connectionDelegate.setCondition(_lock,negotiationComplete); @@ -168,15 +158,16 @@ public class Client implements org.apache.qpidity.nclient.Connection connectionDelegate.setPassword(password); connectionDelegate.setVirtualHost(virtualHost); - if (System.getProperty("transport","mina").equalsIgnoreCase("nio")) + String transport = System.getProperty("transport","io"); + if (transport.equalsIgnoreCase("nio")) { _logger.info("using NIO Transport"); _conn = NioHandler.connect(host, port,connectionDelegate); } - else if (System.getProperty("transport","mina").equalsIgnoreCase("io")) + else if (transport.equalsIgnoreCase("io")) { _logger.info("using Plain IO Transport"); - _conn = IoHandler.connect(host, port,connectionDelegate); + _conn = IoTransport.connect(host, port,connectionDelegate); } else { @@ -186,23 +177,20 @@ public class Client implements org.apache.qpidity.nclient.Connection } // XXX: hardcoded version numbers - _conn.send(new ConnectionEvent(0, new ProtocolHeader(1, TransportConstants.getVersionMajor(), - TransportConstants.getVersionMinor()))); + _conn.send(new ProtocolHeader(1, 0, 10)); try { - negotiationComplete.await(); - if( connectionDelegate.getUnsupportedProtocol() != null ) + negotiationComplete.await(timeout, TimeUnit.MILLISECONDS); + if (header != null) { _conn.close(); - throw new ProtocolException("Unsupported protocol version: " + connectionDelegate.getUnsupportedProtocol() - , ErrorCode.UNSUPPORTED_PROTOCOL, null); - + throw new ProtocolVersionException(header.getMajor(), header.getMinor()); } } catch (InterruptedException e) { - // + throw new RuntimeException(e); } finally { @@ -257,7 +245,6 @@ public class Client implements org.apache.qpidity.nclient.Connection { try { - long timeout = 60000; long start = System.currentTimeMillis(); long elapsed = 0; while (!closed && elapsed < timeout) @@ -289,20 +276,6 @@ public class Client implements org.apache.qpidity.nclient.Connection ssn.attach(ch); ssn.sessionAttach(ssn.getName()); ssn.sessionRequestTimeout(expiryInSeconds); - String transport = System.getProperty("transport","mina"); - - try - { - if (Boolean.getBoolean("batch") && ("io".equalsIgnoreCase(transport) || "nio".equalsIgnoreCase(transport))) - { - _logger.debug("using batch mode in transport " + transport); - IoHandler.startBatchingFrames(_conn.getConnectionId()); - } - } - catch(Exception e) - { - e.printStackTrace(); - } return ssn; } diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/ClosedListener.java b/java/client/src/main/java/org/apache/qpid/nclient/ClosedListener.java index c0c6978a14..4cf0cab1ec 100644 --- a/java/client/src/main/java/org/apache/qpidity/nclient/ClosedListener.java +++ b/java/client/src/main/java/org/apache/qpid/nclient/ClosedListener.java @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.nclient; +package org.apache.qpid.nclient; -import org.apache.qpidity.ErrorCode; +import org.apache.qpid.ErrorCode; /** diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/Connection.java b/java/client/src/main/java/org/apache/qpid/nclient/Connection.java index 49167750d1..2d5b50b33a 100644 --- a/java/client/src/main/java/org/apache/qpidity/nclient/Connection.java +++ b/java/client/src/main/java/org/apache/qpid/nclient/Connection.java @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.nclient; +package org.apache.qpid.nclient; -import org.apache.qpidity.QpidException; +import org.apache.qpid.QpidException; /** * This represents a physical connection to a broker. diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/DtxSession.java b/java/client/src/main/java/org/apache/qpid/nclient/DtxSession.java index 6f15f16470..8a859f2d84 100644 --- a/java/client/src/main/java/org/apache/qpidity/nclient/DtxSession.java +++ b/java/client/src/main/java/org/apache/qpid/nclient/DtxSession.java @@ -16,14 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.nclient; +package org.apache.qpid.nclient; -import org.apache.qpidity.transport.Future; -import org.apache.qpidity.transport.GetTimeoutResult; -import org.apache.qpidity.transport.Option; -import org.apache.qpidity.transport.RecoverResult; -import org.apache.qpidity.transport.XaResult; -import org.apache.qpidity.transport.Xid; +import org.apache.qpid.transport.Future; +import org.apache.qpid.transport.GetTimeoutResult; +import org.apache.qpid.transport.Option; +import org.apache.qpid.transport.RecoverResult; +import org.apache.qpid.transport.XaResult; +import org.apache.qpid.transport.Xid; /** * The resources for this session are controlled under the scope of a distributed transaction. @@ -83,7 +83,7 @@ public interface DtxSession extends Session * * @param xid Specifies the xid of the transaction branch to be forgotten. */ - public void dtxForget(Xid xid); + public void dtxForget(Xid xid, Option ... options); /** * This method obtains the current transaction timeout value in seconds. If set-timeout was not @@ -93,7 +93,7 @@ public interface DtxSession extends Session * @param xid Specifies the xid of the transaction branch used for getting the timeout. * @return The current transaction timeout value in seconds. */ - public Future<GetTimeoutResult> dtxGetTimeout(Xid xid); + public Future<GetTimeoutResult> dtxGetTimeout(Xid xid, Option ... options); /** * This method prepares any message produced or consumed on behalf of xid, ready for commitment. @@ -109,14 +109,14 @@ public interface DtxSession extends Session * <p/> * xa-rbtimeout: The work represented by this transaction branch took too long. */ - public Future<XaResult> dtxPrepare(Xid xid); + public Future<XaResult> dtxPrepare(Xid xid, Option ... options); /** * This method is called to obtain a list of transaction branches that are in a prepared or * heuristically completed state. * @return a array of xids to be recovered. */ - public Future<RecoverResult> dtxRecover(); + public Future<RecoverResult> dtxRecover(Option ... options); /** * This method rolls back the work associated with xid. Any produced messages are discarded and @@ -125,7 +125,7 @@ public interface DtxSession extends Session * @param xid Specifies the xid of the transaction branch to be rolled back. * @return Confirms to the client that the transaction branch is rolled back or specifies the error condition. */ - public Future<XaResult> dtxRollback(Xid xid); + public Future<XaResult> dtxRollback(Xid xid, Option ... options); /** * Sets the specified transaction branch timeout value in seconds. @@ -133,5 +133,5 @@ public interface DtxSession extends Session * @param xid Specifies the xid of the transaction branch for setting the timeout. * @param timeout The transaction timeout value in seconds. */ - public void dtxSetTimeout(Xid xid, long timeout); + public void dtxSetTimeout(Xid xid, long timeout, Option ... options); } diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/JMSTestCase.java b/java/client/src/main/java/org/apache/qpid/nclient/JMSTestCase.java index feb4c1c94d..4e1b9058e6 100644 --- a/java/client/src/main/java/org/apache/qpidity/nclient/JMSTestCase.java +++ b/java/client/src/main/java/org/apache/qpid/nclient/JMSTestCase.java @@ -1,4 +1,4 @@ - package org.apache.qpidity.nclient; + package org.apache.qpid.nclient; import java.util.Enumeration; diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/MessagePartListener.java b/java/client/src/main/java/org/apache/qpid/nclient/MessagePartListener.java index 7c7881502a..6f07dcb469 100644 --- a/java/client/src/main/java/org/apache/qpidity/nclient/MessagePartListener.java +++ b/java/client/src/main/java/org/apache/qpid/nclient/MessagePartListener.java @@ -15,11 +15,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.nclient; +package org.apache.qpid.nclient; import java.nio.ByteBuffer; -import org.apache.qpidity.transport.Header; +import org.apache.qpid.transport.Header; +import org.apache.qpid.transport.MessageTransfer; /** * Assembles message parts. @@ -33,31 +34,13 @@ import org.apache.qpidity.transport.Header; * are transferred. */ public interface MessagePartListener -{ - /** - * Indicates the Message transfer has started. - * - * @param transferId The message transfer ID. - */ - public void messageTransfer(int transferId); - - /** - * Add the following a header to the message being received. - * - * @param header Either <code>DeliveryProperties</code> or <code>ApplicationProperties</code> - */ - public void messageHeader(Header header); +{ /** - * Add the following byte array to the content of the message being received + * Inform the listener of the message transfer * - * @param src Data to be added or streamed. - */ - public void data(ByteBuffer src); - - /** - * Indicates that the message has been fully received. + * @param xfr the message transfer object */ - public void messageReceived(); + public void messageTransfer(MessageTransfer xfr); } diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/Session.java b/java/client/src/main/java/org/apache/qpid/nclient/Session.java index 717ea43654..0d84394c7c 100644 --- a/java/client/src/main/java/org/apache/qpidity/nclient/Session.java +++ b/java/client/src/main/java/org/apache/qpid/nclient/Session.java @@ -16,14 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.nclient; +package org.apache.qpid.nclient; import java.io.IOException; import java.nio.ByteBuffer; import java.util.Map; -import org.apache.qpidity.transport.*; -import org.apache.qpidity.api.Message; +import org.apache.qpid.transport.*; +import org.apache.qpid.api.Message; /** * <p>A session is associated with a connection. @@ -65,9 +65,9 @@ public interface Session public void close(); - public void sessionDetach(byte[] name); + public void sessionDetach(byte[] name, Option ... options); - public void sessionRequestTimeout(long expiry); + public void sessionRequestTimeout(long expiry, Option ... options); public byte[] getName(); @@ -109,42 +109,6 @@ public interface Session /** - * <p>This transfer streams a complete message using a single method. - * It uses pull-semantics instead of doing a push.</p> - * <p>Data is pulled from a Message object using read() - * and pushed using messageTransfer() and headers() followed by data() and endData(). - * <br><b><i>This method should only be used by large messages</b></i><br> - * There are two convenience Message classes to do this. - * <ul> - * <li> <code>{@link org.apache.qpidity.nclient.util.FileMessage}</code> - * <li> <code>{@link org.apache.qpidity.nclient.util.StreamingMessage}</code> - * </ul> - * You can also implement a <code>Message</code> interface to wrap any - * data stream. - * </p> - * - * @param destination The exchange the message is being sent to. - * @param msg The Message to be sent. - * @param confirmMode <ul> </li>off ({@link Session#TRANSFER_CONFIRM_MODE_NOT_REQUIRED}): confirmation - * is not required. Once a message has been transferred in pre-acquire - * mode (or once acquire has been sent in no-acquire mode) the message is considered - * transferred. - * <p/> - * <li> on ({@link Session#TRANSFER_CONFIRM_MODE_REQUIRED}): an acquired message - * is not considered transferred until the original - * transfer is complete. A complete transfer is signaled by execution.complete. - * </ul> - * @param acquireMode <ul> - * <li> no-acquire ({@link Session#TRANSFER_ACQUIRE_MODE_NO_ACQUIRE}): the message - * must be explicitly acquired. - * <li> pre-acquire ({@link Session#TRANSFER_ACQUIRE_MODE_PRE_ACQUIRE}): the message - * is acquired when the transfer starts. - * </ul> - * @throws java.io.IOException If transferring a message fails due to some internal communication error, an exception is thrown. - */ - public void messageStream(String destination, Message msg, short confirmMode, short acquireMode) throws IOException; - - /** * This command transfers a message between two peers. * * @param destination Specifies the destination to which the message is to be transferred. @@ -153,46 +117,32 @@ public interface Session * * @param acquireMode Indicates whether or not the transferred message has been acquired. */ - public void messageTransfer(String destination, MessageAcceptMode acceptMode, MessageAcquireMode acquireMode); + public void messageTransfer(String destination, MessageAcceptMode acceptMode, MessageAcquireMode acquireMode, + Header header, ByteBuffer body, Option ... options); /** - * Make a set of headers to be sent together with a message - * - * @param headers headers to be added - * @see org.apache.qpidity.transport.DeliveryProperties - * @see org.apache.qpidity.transport.MessageProperties - * @return The added headers. - */ - public Header header(Struct... headers); - - /** - * Add a byte array to the content of the message being sent. - * - * @param data Data to be added. - */ - public void data(byte[] data); - - /** - * A Add a ByteBuffer to the content of the message being sent. - * <p> Note that only the data between the buffer's current position and the - * buffer limit is added. - * It is therefore recommended to flip the buffer before adding it to the message, + * This command transfers a message between two peers. * - * @param buf Data to be added. + * @param destination Specifies the destination to which the message is to be transferred. + * @param acceptMode Indicates whether message.accept, session.complete, + * or nothing at all is required to indicate successful transfer of the message. + * + * @param acquireMode Indicates whether or not the transferred message has been acquired. */ - public void data(ByteBuffer buf); + public void messageTransfer(String destination, MessageAcceptMode acceptMode, MessageAcquireMode acquireMode, + Header header, byte[] body, Option ... options); /** - * Add a string to the content of the message being sent. + * This command transfers a message between two peers. * - * @param str String to be added. - */ - public void data(String str); - - /** - * Signals the end of data for the message. + * @param destination Specifies the destination to which the message is to be transferred. + * @param acceptMode Indicates whether message.accept, session.complete, + * or nothing at all is required to indicate successful transfer of the message. + * + * @param acquireMode Indicates whether or not the transferred message has been acquired. */ - public void endData(); + public void messageTransfer(String destination, MessageAcceptMode acceptMode, MessageAcquireMode acquireMode, + Header header, String body, Option ... options); //------------------------------------------------------ // Messaging methods @@ -207,7 +157,7 @@ public interface Session * <ul> * <li>{@link Option#EXCLUSIVE}: <p> Requests exclusive subscription access, so that only this * subscription can access the queue. - * <li>{@link Option#NO_OPTION}: <p> This is an empty option, and has no effect. + * <li>{@link Option#NONE}: <p> This is an empty option, and has no effect. * </ul> * * @param queue The queue that the receiver is receiving messages from. @@ -228,9 +178,9 @@ public interface Session * acquired when the transfer starts. * </ul> * @param listener The listener for this destination. To transfer large messages - * use a {@link org.apache.qpidity.nclient.MessagePartListener}. + * use a {@link org.apache.qpid.nclient.MessagePartListener}. * @param options Set of options. Valid options are {{@link Option#EXCLUSIVE} - * and {@link Option#NO_OPTION}. + * and {@link Option#NONE}. * @param filter A set of filters for the subscription. The syntax and semantics of these filters varies * according to the provider's implementation. */ @@ -246,7 +196,7 @@ public interface Session * * @param destination The destination to be cancelled. */ - public void messageCancel(String destination); + public void messageCancel(String destination, Option ... options); /** * Associate a message listener with a destination. @@ -274,7 +224,7 @@ public interface Session * @param mode <ul> <li>credit ({@link Session#MESSAGE_FLOW_MODE_CREDIT}): choose credit based flow control * <li> window ({@link Session#MESSAGE_FLOW_MODE_WINDOW}): choose window based flow control</ul> */ - public void messageSetFlowMode(String destination, MessageFlowMode mode); + public void messageSetFlowMode(String destination, MessageFlowMode mode, Option ... options); /** @@ -295,7 +245,7 @@ public interface Session * </ul> * @param value Number of credits, a value of 0 indicates an infinite amount of credit. */ - public void messageFlow(String destination, MessageCreditUnit unit, long value); + public void messageFlow(String destination, MessageCreditUnit unit, long value, Option ... options); /** * Forces the broker to exhaust its credit supply. @@ -304,7 +254,7 @@ public interface Session * * @param destination The destination on which the credit supply is to be exhausted. */ - public void messageFlush(String destination); + public void messageFlush(String destination, Option ... options); /** * On receipt of this method, the brokers set credit to zero for a given @@ -314,7 +264,7 @@ public interface Session * * @param destination The destination on which to reset credit. */ - public void messageStop(String destination); + public void messageStop(String destination, Option ... options); /** * Acknowledge the receipt of a range of messages. @@ -338,7 +288,7 @@ public interface Session * failed). * @param text String describing the reason for a message transfer rejection. */ - public void messageReject(RangeSet ranges, MessageRejectCode code, String text); + public void messageReject(RangeSet ranges, MessageRejectCode code, String text, Option ... options); /** * As it is possible that the broker does not manage to reject some messages, after completion of @@ -367,7 +317,7 @@ public interface Session * @param ranges Ranges of messages to be acquired. * @return Indicates the acquired messages */ - public Future<Acquired> messageAcquire(RangeSet ranges); + public Future<Acquired> messageAcquire(RangeSet ranges, Option ... options); /** * Give up responsibility for processing ranges of messages. @@ -384,21 +334,21 @@ public interface Session /** * Selects the session for local transaction support. */ - public void txSelect(); + public void txSelect(Option ... options); /** * Commit the receipt and delivery of all messages exchanged by this session's resources. * * @throws IllegalStateException If this session is not transacted, an exception will be thrown. */ - public void txCommit() throws IllegalStateException; + public void txCommit(Option ... options) throws IllegalStateException; /** * Roll back the receipt and delivery of all messages exchanged by this session's resources. * * @throws IllegalStateException If this session is not transacted, an exception will be thrown. */ - public void txRollback() throws IllegalStateException; + public void txRollback(Option ... options) throws IllegalStateException; //--------------------------------------------- // Queue methods @@ -423,7 +373,7 @@ public interface Session * declaring connection closes. * <li> {@link Option#PASSIVE}: <p> If set, the server will not create the queue. * This field allows the client to assert the presence of a queue without modifying the server state. - * <li>{@link Option#NO_OPTION}: <p> Has no effect as it represents an �empty� option. + * <li>{@link Option#NONE}: <p> Has no effect as it represents an empty option. * </ul> * <p>In the absence of a particular option, the defaul value is false for each option * @@ -435,7 +385,7 @@ public interface Session * the queue. </ol> * @param arguments Used for backward compatibility * @param options Set of Options ( valide options are: {@link Option#AUTO_DELETE}, {@link Option#DURABLE}, - * {@link Option#EXCLUSIVE}, {@link Option#PASSIVE} and {@link Option#NO_OPTION}) + * {@link Option#EXCLUSIVE}, {@link Option#PASSIVE} and {@link Option#NONE}) * @see Option */ public void queueDeclare(String queueName, String alternateExchange, Map<String, Object> arguments, @@ -456,7 +406,8 @@ public interface Session * routing keys depends on the exchange implementation. * @param arguments Used for backward compatibility */ - public void exchangeBind(String queueName, String exchangeName, String routingKey, Map<String, Object> arguments); + public void exchangeBind(String queueName, String exchangeName, String routingKey, Map<String, Object> arguments, + Option ... options); /** * Unbind a queue from an exchange. @@ -465,7 +416,7 @@ public interface Session * @param exchangeName The name of the exchange to unbind from. * @param routingKey Specifies the routing key of the binding to unbind. */ - public void exchangeUnbind(String queueName, String exchangeName, String routingKey); + public void exchangeUnbind(String queueName, String exchangeName, String routingKey, Option ... options); /** * This method removes all messages from a queue. It does not cancel consumers. Purged messages @@ -474,7 +425,7 @@ public interface Session * @param queueName Specifies the name of the queue to purge. If the queue name is empty, refers to the * current queue for the session, which is the last declared queue. */ - public void queuePurge(String queueName); + public void queuePurge(String queueName, Option ... options); /** * This method deletes a queue. When a queue is deleted any pending messages are sent to a @@ -485,7 +436,7 @@ public interface Session * <li> {@link Option#IF_EMPTY}: <p> If set, the server will only delete the queue if it has no messages. * <li> {@link Option#IF_UNUSED}: <p> If set, the server will only delete the queue if it has no consumers. * If the queue has consumers the server does does not delete it but raises a channel exception instead. - * <li>{@link Option#NO_OPTION}: <p> Has no effect as it represents an �empty� option. + * <li>{@link Option#NONE}: <p> Has no effect as it represents an empty option. * </ul> * </p> * <p/> @@ -494,7 +445,7 @@ public interface Session * @param queueName Specifies the name of the queue to delete. If the queue name is empty, refers to the * current queue for the session, which is the last declared queue. * @param options Set of options (Valid options are: {@link Option#IF_EMPTY}, {@link Option#IF_UNUSED} - * and {@link Option#NO_OPTION}) + * and {@link Option#NONE}) * @see Option */ public void queueDelete(String queueName, Option... options); @@ -506,7 +457,7 @@ public interface Session * @param queueName The name of the queue for which information is requested. * @return Information on the specified queue. */ - public Future<QueueQueryResult> queueQuery(String queueName); + public Future<QueueQueryResult> queueQuery(String queueName, Option ... options); /** @@ -519,7 +470,7 @@ public interface Session * @return Information on the specified binding. */ public Future<ExchangeBoundResult> exchangeBound(String exchange, String queue, String routingKey, - Map<String, Object> arguments); + Map<String, Object> arguments, Option ... options); // -------------------------------------- // exhcange methods @@ -536,7 +487,7 @@ public interface Session * exchanges) are purged when a server restarts. * <li>{@link Option#PASSIVE}: <p>If set, the server will not create the exchange. * The client can use this to check whether an exchange exists without modifying the server state. - * <li> {@link Option#NO_OPTION}: <p>This option is an empty option, and has no effect. + * <li> {@link Option#NONE}: <p>This option is an empty option, and has no effect. * </ul> * <p>In the absence of a particular option, the defaul value is false for each option</p> * @@ -548,7 +499,7 @@ public interface Session * @param alternateExchange In the event that a message cannot be routed, this is the name of the exchange to which * the message will be sent. * @param options Set of options (valid options are: {@link Option#AUTO_DELETE}, {@link Option#DURABLE}, - * {@link Option#PASSIVE}, {@link Option#NO_OPTION}) + * {@link Option#PASSIVE}, {@link Option#NONE}) * @param arguments Used for backward compatibility * @see Option */ @@ -563,12 +514,12 @@ public interface Session * <li> {@link Option#IF_UNUSED}: <p> If set, the server will only delete the exchange if it has no queue bindings. If the * exchange has queue bindings the server does not delete it but raises a channel exception * instead. - * <li> {@link Option#NO_OPTION}: <p> Has no effect as it represents an empty option. + * <li> {@link Option#NONE}: <p> Has no effect as it represents an empty option. * </ul> * <p>Note that if an option is not set, it will default to false. * * @param exchangeName The name of exchange to be deleted. - * @param options Set of options. Valid options are: {@link Option#IF_UNUSED}, {@link Option#NO_OPTION}. + * @param options Set of options. Valid options are: {@link Option#IF_UNUSED}, {@link Option#NONE}. * @see Option */ public void exchangeDelete(String exchangeName, Option... options); @@ -581,7 +532,7 @@ public interface Session * return information about the default exchange. * @return Information on the specified exchange. */ - public Future<ExchangeQueryResult> exchangeQuery(String exchangeName); + public Future<ExchangeQueryResult> exchangeQuery(String exchangeName, Option ... options); /** * If the session receives a sessionClosed with an error code it diff --git a/java/client/src/main/java/org/apache/qpid/nclient/impl/ClientSession.java b/java/client/src/main/java/org/apache/qpid/nclient/impl/ClientSession.java new file mode 100644 index 0000000000..27805a1f39 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/impl/ClientSession.java @@ -0,0 +1,142 @@ +package org.apache.qpid.nclient.impl; + +import java.io.EOFException; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.qpid.QpidException; +import org.apache.qpid.api.Message; +import org.apache.qpid.nclient.ClosedListener; +import org.apache.qpid.nclient.MessagePartListener; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.transport.MessageAcceptMode; +import org.apache.qpid.transport.MessageAcquireMode; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.Option; +import org.apache.qpid.transport.Range; +import org.apache.qpid.transport.RangeSet; + +import static org.apache.qpid.transport.Option.*; + +/** + * Implements a Qpid Sesion. + */ +public class ClientSession extends org.apache.qpid.transport.Session implements org.apache.qpid.nclient.DtxSession +{ + static + { + String max = "message_size_before_sync"; // KB's + try + { + MAX_NOT_SYNC_DATA_LENGH = new Long(System.getProperties().getProperty(max, "200000000")); + } + catch (NumberFormatException e) + { + // use default size + MAX_NOT_SYNC_DATA_LENGH = 200000000; + } + String flush = "message_size_before_flush"; + try + { + MAX_NOT_FLUSH_DATA_LENGH = new Long(System.getProperties().getProperty(flush, "2000000")); + } + catch (NumberFormatException e) + { + // use default size + MAX_NOT_FLUSH_DATA_LENGH = 20000000; + } + } + + private static long MAX_NOT_SYNC_DATA_LENGH; + private static long MAX_NOT_FLUSH_DATA_LENGH; + + private Map<String,MessagePartListener> _messageListeners = new ConcurrentHashMap<String,MessagePartListener>(); + private ClosedListener _exceptionListner; + private RangeSet _rejectedMessages; + private long _currentDataSizeNotSynced; + private long _currentDataSizeNotFlushed; + + public ClientSession(byte[] name) + { + super(name); + } + + public void messageAcknowledge(RangeSet ranges, boolean accept) + { + for (Range range : ranges) + { + super.processed(range); + } + super.flushProcessed(accept ? BATCH : NONE); + if (accept) + { + messageAccept(ranges); + } + } + + public void messageSubscribe(String queue, String destination, short acceptMode, short acquireMode, MessagePartListener listener, Map<String, Object> filter, Option... options) + { + setMessageListener(destination,listener); + super.messageSubscribe(queue, destination, MessageAcceptMode.get(acceptMode), + MessageAcquireMode.get(acquireMode), null, 0, filter, + options); + } + + public void messageTransfer(String destination, Message msg, short acceptMode, short acquireMode) throws IOException + { + DeliveryProperties dp = msg.getDeliveryProperties(); + MessageProperties mp = msg.getMessageProperties(); + ByteBuffer body = msg.readData(); + int size = body.remaining(); + super.messageTransfer + (destination, MessageAcceptMode.get(acceptMode), + MessageAcquireMode.get(acquireMode), + new Header(dp, mp), body); + _currentDataSizeNotSynced += size; + _currentDataSizeNotFlushed += size; + } + + public void sync() + { + super.sync(); + _currentDataSizeNotSynced = 0; + } + + public RangeSet getRejectedMessages() + { + return _rejectedMessages; + } + + public void setMessageListener(String destination, MessagePartListener listener) + { + if (listener == null) + { + throw new IllegalArgumentException("Cannot set message listener to null"); + } + _messageListeners.put(destination, listener); + } + + public void setClosedListener(ClosedListener exceptionListner) + { + _exceptionListner = exceptionListner; + } + + void setRejectedMessages(RangeSet rejectedMessages) + { + _rejectedMessages = rejectedMessages; + } + + void notifyException(QpidException ex) + { + _exceptionListner.onClosed(null, null, null); + } + + Map<String,MessagePartListener> getMessageListeners() + { + return _messageListeners; + } +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/impl/ClientSessionDelegate.java b/java/client/src/main/java/org/apache/qpid/nclient/impl/ClientSessionDelegate.java new file mode 100644 index 0000000000..620cf14c33 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/impl/ClientSessionDelegate.java @@ -0,0 +1,47 @@ +package org.apache.qpid.nclient.impl; + +import java.nio.ByteBuffer; + +import org.apache.qpid.ErrorCode; + +import org.apache.qpid.nclient.MessagePartListener; + +import org.apache.qpid.QpidException; +import org.apache.qpid.transport.Header; +import org.apache.qpid.transport.MessageReject; +import org.apache.qpid.transport.MessageTransfer; +import org.apache.qpid.transport.Range; +import org.apache.qpid.transport.Session; +import org.apache.qpid.transport.SessionDetached; +import org.apache.qpid.transport.SessionDelegate; + + +public class ClientSessionDelegate extends SessionDelegate +{ + + // -------------------------------------------- + // Message methods + // -------------------------------------------- + @Override public void messageTransfer(Session session, MessageTransfer xfr) + { + MessagePartListener listener = ((ClientSession)session).getMessageListeners() + .get(xfr.getDestination()); + listener.messageTransfer(xfr); + } + + @Override public void messageReject(Session session, MessageReject struct) + { + for (Range range : struct.getTransfers()) + { + for (long l = range.getLower(); l <= range.getUpper(); l++) + { + System.out.println("message rejected: " + + session.getCommand((int) l)); + } + } + ((ClientSession)session).setRejectedMessages(struct.getTransfers()); + ((ClientSession)session).notifyException(new QpidException("Message Rejected",ErrorCode.MESSAGE_REJECTED,null)); + session.processed(struct); + } + +} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/impl/Constants.java b/java/client/src/main/java/org/apache/qpid/nclient/impl/Constants.java index 83d491baad..f689e9abde 100644 --- a/java/client/src/main/java/org/apache/qpidity/nclient/impl/Constants.java +++ b/java/client/src/main/java/org/apache/qpid/nclient/impl/Constants.java @@ -19,7 +19,7 @@ * */ -package org.apache.qpidity.nclient.impl; +package org.apache.qpid.nclient.impl; /** * This class holds all the 0.10 client constants which value can be set diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/impl/DemoClient.java b/java/client/src/main/java/org/apache/qpid/nclient/impl/DemoClient.java index 05b99a3cf1..88b5dc6392 100644 --- a/java/client/src/main/java/org/apache/qpidity/nclient/impl/DemoClient.java +++ b/java/client/src/main/java/org/apache/qpid/nclient/impl/DemoClient.java @@ -1,18 +1,20 @@ -package org.apache.qpidity.nclient.impl; +package org.apache.qpid.nclient.impl; -import org.apache.qpidity.ErrorCode; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.ClosedListener; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.nclient.util.MessageListener; -import org.apache.qpidity.nclient.util.MessagePartListenerAdapter; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageAcceptMode; -import org.apache.qpidity.transport.MessageAcquireMode; -import org.apache.qpidity.transport.MessageProperties; +import org.apache.qpid.ErrorCode; +import org.apache.qpid.api.Message; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.ClosedListener; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.nclient.util.MessageListener; +import org.apache.qpid.nclient.util.MessagePartListenerAdapter; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.transport.MessageAcceptMode; +import org.apache.qpid.transport.MessageAcquireMode; +import org.apache.qpid.transport.MessageProperties; +import java.nio.ByteBuffer; import java.util.UUID; public class DemoClient @@ -56,17 +58,15 @@ public class DemoClient ssn.messageSubscribe("queue1", "myDest", (short)0, (short)0,createAdapter(), null); // queue - ssn.messageTransfer("amq.direct", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED); - ssn.header(new DeliveryProperties().setRoutingKey("queue1"), - new MessageProperties().setMessageId(UUID.randomUUID())); - ssn.data("this is the data"); - ssn.endData(); + ssn.messageTransfer("amq.direct", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED, + new Header(new DeliveryProperties().setRoutingKey("queue1"), + new MessageProperties().setMessageId(UUID.randomUUID())), + ByteBuffer.wrap("this is the data".getBytes())); //reject - ssn.messageTransfer("amq.direct", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED); - ssn.data("this should be rejected"); - ssn.header(new DeliveryProperties().setRoutingKey("stocks")); - ssn.endData(); + ssn.messageTransfer("amq.direct", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED, + new Header(new DeliveryProperties().setRoutingKey("stocks")), + ByteBuffer.wrap("this should be rejected".getBytes())); ssn.sync(); // topic subs @@ -84,11 +84,10 @@ public class DemoClient ssn.sync(); // topic - ssn.messageTransfer("amq.topic", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED); - ssn.data("Topic message"); - ssn.header(new DeliveryProperties().setRoutingKey("stock.us.ibm"), - new MessageProperties().setMessageId(UUID.randomUUID())); - ssn.endData(); + ssn.messageTransfer("amq.topic", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED, + new Header(new DeliveryProperties().setRoutingKey("stock.us.ibm"), + new MessageProperties().setMessageId(UUID.randomUUID())), + ByteBuffer.wrap("Topic message".getBytes())); } } diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/interop/BasicInteropTest.java b/java/client/src/main/java/org/apache/qpid/nclient/interop/BasicInteropTest.java index e452091622..9ea9297e14 100644 --- a/java/client/src/main/java/org/apache/qpidity/nclient/interop/BasicInteropTest.java +++ b/java/client/src/main/java/org/apache/qpid/nclient/interop/BasicInteropTest.java @@ -1,24 +1,26 @@ -package org.apache.qpidity.nclient.interop; +package org.apache.qpid.nclient.interop; +import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; -import org.apache.qpidity.ErrorCode; -import org.apache.qpidity.QpidException; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.ClosedListener; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.nclient.util.MessageListener; -import org.apache.qpidity.nclient.util.MessagePartListenerAdapter; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageAcceptMode; -import org.apache.qpidity.transport.MessageAcquireMode; -import org.apache.qpidity.transport.MessageCreditUnit; -import org.apache.qpidity.transport.MessageFlowMode; -import org.apache.qpidity.transport.MessageProperties; -import org.apache.qpidity.transport.RangeSet; +import org.apache.qpid.ErrorCode; +import org.apache.qpid.QpidException; +import org.apache.qpid.api.Message; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.ClosedListener; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.nclient.util.MessageListener; +import org.apache.qpid.nclient.util.MessagePartListenerAdapter; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.transport.MessageAcceptMode; +import org.apache.qpid.transport.MessageAcquireMode; +import org.apache.qpid.transport.MessageCreditUnit; +import org.apache.qpid.transport.MessageFlowMode; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.RangeSet; public class BasicInteropTest implements ClosedListener { @@ -77,18 +79,15 @@ public class BasicInteropTest implements ClosedListener public void testSendMessage(){ System.out.println("------- Sending a message --------"); - session.messageTransfer("test", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED); - Map<String,Object> props = new HashMap<String,Object>(); props.put("name", "rajith"); props.put("age", 10); props.put("spf", 8.5); - session.header(new DeliveryProperties().setRoutingKey("testKey"),new MessageProperties().setApplicationHeaders(props)); - - //session.header(new DeliveryProperties().setRoutingKey("testKey")); + session.messageTransfer("test", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED, + new Header(new DeliveryProperties().setRoutingKey("testKey"), + new MessageProperties().setApplicationHeaders(props)), + ByteBuffer.wrap("TestMessage".getBytes())); - session.data("TestMessage"); - session.endData(); session.sync(); System.out.println("------- Message sent --------"); } diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/util/ByteBufferMessage.java b/java/client/src/main/java/org/apache/qpid/nclient/util/ByteBufferMessage.java index 833f905b58..64c89c960c 100644 --- a/java/client/src/main/java/org/apache/qpidity/nclient/util/ByteBufferMessage.java +++ b/java/client/src/main/java/org/apache/qpid/nclient/util/ByteBufferMessage.java @@ -1,14 +1,13 @@ -package org.apache.qpidity.nclient.util; +package org.apache.qpid.nclient.util; import java.io.IOException; import java.nio.ByteBuffer; -import java.util.LinkedList; -import java.util.Queue; +import java.util.*; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageProperties; -import org.apache.qpidity.transport.Header; -import org.apache.qpidity.api.Message; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.api.Message; /** * <p>A Simple implementation of the message interface @@ -22,7 +21,7 @@ import org.apache.qpidity.api.Message; */ public class ByteBufferMessage implements Message { - private Queue<ByteBuffer> _data = new LinkedList<ByteBuffer>(); + private List<ByteBuffer> _data;// = new ArrayList<ByteBuffer>(); private ByteBuffer _readBuffer; private int _dataSize; private DeliveryProperties _currentDeliveryProps; @@ -30,6 +29,12 @@ public class ByteBufferMessage implements Message private int _transferId; private Header _header; + public ByteBufferMessage(MessageProperties messageProperties, DeliveryProperties deliveryProperties) + { + _currentMessageProps = messageProperties; + _currentDeliveryProps = deliveryProperties; + } + public void setHeader(Header header) { _header = header; } @@ -70,7 +75,18 @@ public class ByteBufferMessage implements Message */ public void appendData(ByteBuffer src) throws IOException { - _data.offer(src); + if(_data == null) + { + _data = Collections.singletonList(src); + } + else + { + if(_data.size() == 1) + { + _data = new ArrayList<ByteBuffer>(_data); + } + _data.add(src); + } _dataSize += src.remaining(); } @@ -94,12 +110,12 @@ public class ByteBufferMessage implements Message _currentMessageProps = props; } - public void readData(byte[] target) throws IOException + public void readData(byte[] target) { getReadBuffer().get(target); } - public ByteBuffer readData() throws IOException + public ByteBuffer readData() { return getReadBuffer(); } @@ -109,7 +125,7 @@ public class ByteBufferMessage implements Message //optimize for the simple cases if(_data.size() == 1) { - _readBuffer = _data.element().duplicate(); + _readBuffer = _data.get(0).duplicate(); } else { @@ -122,7 +138,7 @@ public class ByteBufferMessage implements Message } } - private ByteBuffer getReadBuffer() throws IOException + private ByteBuffer getReadBuffer() { if (_readBuffer != null ) { @@ -137,7 +153,7 @@ public class ByteBufferMessage implements Message } else { - throw new IOException("No Data to read"); + return ByteBuffer.allocate(0); } } } @@ -145,16 +161,9 @@ public class ByteBufferMessage implements Message //hack for testing @Override public String toString() { - try - { - ByteBuffer temp = getReadBuffer(); - byte[] b = new byte[temp.remaining()]; - temp.get(b); - return new String(b); - } - catch(IOException e) - { - return "No data"; - } + ByteBuffer temp = getReadBuffer(); + byte[] b = new byte[temp.remaining()]; + temp.get(b); + return new String(b); } } diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/util/FileMessage.java b/java/client/src/main/java/org/apache/qpid/nclient/util/FileMessage.java index 289d03574d..179c91c2e9 100644 --- a/java/client/src/main/java/org/apache/qpidity/nclient/util/FileMessage.java +++ b/java/client/src/main/java/org/apache/qpid/nclient/util/FileMessage.java @@ -1,4 +1,4 @@ -package org.apache.qpidity.nclient.util; +package org.apache.qpid.nclient.util; import java.io.EOFException; import java.io.FileInputStream; @@ -7,10 +7,10 @@ import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageProperties; -import org.apache.qpidity.transport.Header; -import org.apache.qpidity.api.Message; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.api.Message; /** * FileMessage provides pull style semantics for diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/util/MessageListener.java b/java/client/src/main/java/org/apache/qpid/nclient/util/MessageListener.java index 43c20eb6b5..c5edd62143 100644 --- a/java/client/src/main/java/org/apache/qpidity/nclient/util/MessageListener.java +++ b/java/client/src/main/java/org/apache/qpid/nclient/util/MessageListener.java @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.nclient.util; +package org.apache.qpid.nclient.util; -import org.apache.qpidity.api.Message; +import org.apache.qpid.api.Message; /** *A message listener diff --git a/java/client/src/main/java/org/apache/qpid/nclient/util/MessagePartListenerAdapter.java b/java/client/src/main/java/org/apache/qpid/nclient/util/MessagePartListenerAdapter.java new file mode 100644 index 0000000000..0e54e04a99 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/util/MessagePartListenerAdapter.java @@ -0,0 +1,67 @@ +package org.apache.qpid.nclient.util; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import org.apache.qpid.transport.*; +import org.apache.qpid.nclient.MessagePartListener; + +/** + * This is a simple message assembler. + * Will call onMessage method of the adaptee + * when all message data is read. + * + * This is a good convinience utility for handling + * small messages + */ +public class MessagePartListenerAdapter implements MessagePartListener +{ + MessageListener _adaptee; + ByteBufferMessage _currentMsg; + + public MessagePartListenerAdapter(MessageListener listener) + { + _adaptee = listener; + } + + public void messageTransfer(MessageTransfer xfr) + { + _currentMsg = new ByteBufferMessage(xfr.getId()); + + for (Struct st : xfr.getHeader().getStructs()) + { + if(st instanceof DeliveryProperties) + { + _currentMsg.setDeliveryProperties((DeliveryProperties)st); + + } + else if(st instanceof MessageProperties) + { + _currentMsg.setMessageProperties((MessageProperties)st); + } + + } + + + ByteBuffer body = xfr.getBody(); + if (body == null) + { + body = ByteBuffer.allocate(0); + } + + + try + { + _currentMsg.appendData(body); + } + catch(IOException e) + { + // A chance for IO exception + // doesn't occur as we are using + // a ByteBuffer + } + + _adaptee.onMessage(_currentMsg); + } + +} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/util/ReadOnlyMessage.java b/java/client/src/main/java/org/apache/qpid/nclient/util/ReadOnlyMessage.java index 8ff5c62a25..6583a95c7e 100644 --- a/java/client/src/main/java/org/apache/qpidity/nclient/util/ReadOnlyMessage.java +++ b/java/client/src/main/java/org/apache/qpid/nclient/util/ReadOnlyMessage.java @@ -1,10 +1,10 @@ -package org.apache.qpidity.nclient.util; +package org.apache.qpid.nclient.util; import java.nio.ByteBuffer; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageProperties; -import org.apache.qpidity.api.Message; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.api.Message; public abstract class ReadOnlyMessage implements Message { diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/util/StreamingMessage.java b/java/client/src/main/java/org/apache/qpid/nclient/util/StreamingMessage.java index 6c7f9e9db7..a4574438ac 100644 --- a/java/client/src/main/java/org/apache/qpidity/nclient/util/StreamingMessage.java +++ b/java/client/src/main/java/org/apache/qpid/nclient/util/StreamingMessage.java @@ -1,14 +1,14 @@ -package org.apache.qpidity.nclient.util; +package org.apache.qpid.nclient.util; import java.io.EOFException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageProperties; -import org.apache.qpidity.transport.Header; -import org.apache.qpidity.api.Message; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.api.Message; public class StreamingMessage extends ReadOnlyMessage implements Message { diff --git a/java/client/src/main/java/org/apache/qpidity/njms/ExceptionHelper.java b/java/client/src/main/java/org/apache/qpid/njms/ExceptionHelper.java index e00f9008d3..ce790a3b24 100644 --- a/java/client/src/main/java/org/apache/qpidity/njms/ExceptionHelper.java +++ b/java/client/src/main/java/org/apache/qpid/njms/ExceptionHelper.java @@ -15,9 +15,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.qpidity.njms; +package org.apache.qpid.njms; -import org.apache.qpidity.QpidException; +import org.apache.qpid.QpidException; import javax.jms.JMSException; import javax.transaction.xa.XAException; diff --git a/java/client/src/main/java/org/apache/qpid/testutil/QpidTestCase.java b/java/client/src/main/java/org/apache/qpid/testutil/QpidTestCase.java deleted file mode 100644 index 1fe9a3ae51..0000000000 --- a/java/client/src/main/java/org/apache/qpid/testutil/QpidTestCase.java +++ /dev/null @@ -1,456 +0,0 @@ -/* 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.qpid.testutil; - -import junit.framework.TestCase; -import junit.framework.TestResult; - -import javax.jms.Connection; -import javax.naming.InitialContext; -import java.io.*; -import java.util.ArrayList; -import java.util.List; -import java.util.StringTokenizer; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQConnectionFactory; - - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * - */ -public class QpidTestCase extends TestCase -{ - - private static final Logger _logger = LoggerFactory.getLogger(QpidTestCase.class); - - /** - * Some tests are excluded when the property test.excludes is set to true. - * An exclusion list is either a file (prop test.excludesfile) which contains one test name - * to be excluded per line or a String (prop test.excludeslist) where tests to be excluded are - * separated by " ". Excluded tests are specified following the format: - * className#testName where className is the class of the test to be - * excluded and testName is the name of the test to be excluded. - * className#* excludes all the tests of the specified class. - */ - static - { - if (Boolean.getBoolean("test.excludes")) - { - _logger.info("Some tests should be excluded, building the exclude list"); - String exclusionListURI = System.getProperties().getProperty("test.excludesfile", ""); - String exclusionListString = System.getProperties().getProperty("test.excludeslist", ""); - File file=new File(exclusionListURI); - List<String> exclusionList = new ArrayList<String>(); - if (file.exists()) - { - _logger.info("Using exclude file: " + exclusionListURI); - try - { - BufferedReader in = new BufferedReader(new FileReader(file)); - String excludedTest = in.readLine(); - do - { - exclusionList.add(excludedTest); - excludedTest = in.readLine(); - } - while (excludedTest != null); - } - catch (IOException e) - { - _logger.warn("Exception when reading exclusion list", e); - } - } - else if( ! exclusionListString.equals("")) - { - _logger.info("Using excludeslist: " + exclusionListString); - // the exclusion list may be specified as a string - StringTokenizer t = new StringTokenizer(exclusionListString, " "); - while (t.hasMoreTokens()) - { - exclusionList.add(t.nextToken()); - } - } - else - { - throw new RuntimeException("Aborting test: Cannot find excludes file nor excludes list"); - } - _exclusionList = exclusionList; - } - } - - private static List<String> _exclusionList; - - // system properties - private static final String BROKER = "broker"; - private static final String BROKER_CLEAN = "broker.clean"; - private static final String BROKER_VERSION = "broker.version"; - private static final String BROKER_READY = "broker.ready"; - - // values - protected static final String VM = "vm"; - private static final String EXTERNAL = "external"; - private static final String VERSION_08 = "0-8"; - private static final String VERSION_010 = "0-10"; - - protected String _broker = System.getProperty(BROKER, VM); - private String _brokerClean = System.getProperty(BROKER_CLEAN, null); - private String _brokerVersion = System.getProperty(BROKER_VERSION, VERSION_08); - - private Process _brokerProcess; - - private InitialContext _initialContext; - private AMQConnectionFactory _connectionFactory; - private boolean _brokerStarted; - - // the connections created for a given test - protected List<Connection> _connections = new ArrayList<Connection>(); - - public QpidTestCase(String name) - { - super(name); - } - - public QpidTestCase() - { - super("QpidTestCase"); - } - - public void runBare() throws Throwable - { - String name = getClass().getSimpleName() + "." + getName(); - _logger.info("========== start " + name + " =========="); - startBroker(); - try - { - super.runBare(); - } - finally - { - try - { - stopBroker(); - } - catch (Exception e) - { - _logger.error("exception stopping broker", e); - } - _logger.info("========== stop " + name + " =========="); - } - } - - public void run(TestResult testResult) - { - if( _exclusionList != null && (_exclusionList.contains( getClass().getName() + "#*") || - _exclusionList.contains( getClass().getName() + "#" + getName()))) - { - _logger.info("Test: " + getName() + " is excluded"); - testResult.endTest(this); - } - else - { - super.run(testResult); - } - } - - - private static final class Piper extends Thread - { - - private LineNumberReader in; - private String ready; - private CountDownLatch latch; - - public Piper(InputStream in, String ready) - { - this.in = new LineNumberReader(new InputStreamReader(in)); - this.ready = ready; - if (this.ready != null && !this.ready.equals("")) - { - this.latch = new CountDownLatch(1); - } - else - { - this.latch = null; - } - } - - public Piper(InputStream in) - { - this(in, null); - } - - public boolean await(long timeout, TimeUnit unit) throws InterruptedException - { - if (latch == null) - { - return true; - } - else - { - return latch.await(timeout, unit); - } - } - - public void run() - { - try - { - String line; - while ((line = in.readLine()) != null) - { - System.out.println(line); - if (latch != null && line.contains(ready)) - { - latch.countDown(); - } - } - } - catch (IOException e) - { - // this seems to happen regularly even when - // exits are normal - } - finally - { - if (latch != null) - { - latch.countDown(); - } - } - } - } - - public void startBroker() throws Exception - { - if (_broker.equals(VM)) - { - // create an in_VM broker - TransportConnection.createVMBroker(1); - } - else if (!_broker.equals(EXTERNAL)) - { - _logger.info("starting broker: " + _broker); - ProcessBuilder pb = new ProcessBuilder(_broker.split("\\s+")); - pb.redirectErrorStream(true); - _brokerProcess = pb.start(); - - Piper p = new Piper(_brokerProcess.getInputStream(), - System.getProperty(BROKER_READY)); - - p.start(); - - if (!p.await(30, TimeUnit.SECONDS)) - { - _logger.info("broker failed to become ready"); - cleanBroker(); - throw new RuntimeException("broker failed to become ready"); - } - - try - { - int exit = _brokerProcess.exitValue(); - _logger.info("broker aborted: " + exit); - cleanBroker(); - throw new RuntimeException("broker aborted: " + exit); - } - catch (IllegalThreadStateException e) - { - // this is expect if the broker started succesfully - } - } - _brokerStarted = true; - } - - public void cleanBroker() - { - if (_brokerClean != null) - { - _logger.info("clean: " + _brokerClean); - - try - { - ProcessBuilder pb = new ProcessBuilder(_brokerClean.split("\\s+")); - pb.redirectErrorStream(true); - Process clean = pb.start(); - new Piper(clean.getInputStream()).start(); - - clean.waitFor(); - - _logger.info("clean exited: " + clean.exitValue()); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - catch (InterruptedException e) - { - throw new RuntimeException(e); - } - } - } - - public void stopBroker() throws Exception - { - _logger.info("stopping broker: " + _broker); - if (_brokerProcess != null) - { - _brokerProcess.destroy(); - _brokerProcess.waitFor(); - _logger.info("broker exited: " + _brokerProcess.exitValue()); - _brokerProcess = null; - } - else if (_broker.equals(VM)) - { - TransportConnection.killAllVMBrokers(); - } - _brokerStarted = false; - } - - /** - * Check whether the broker is an 0.8 - * @return true if the broker is an 0_8 version, false otherwise. - */ - public boolean isBroker08() - { - return _brokerVersion.equals(VERSION_08); - } - - public boolean isBroker010() - { - return _brokerVersion.equals(VERSION_010); - } - - public void shutdownServer() throws Exception - { - stopBroker(); - startBroker(); - } - /** - * we assume that the environment is correctly set - * i.e. -Djava.naming.provider.url="..//example010.properties" - * TODO should be a way of setting that through maven - * - * @return an initial context - * @throws Exception if there is an error getting the context - */ - public InitialContext getInitialContext() throws Exception - { - _logger.info("get InitialContext"); - if (_initialContext == null) - { - _initialContext = new InitialContext(); - } - return _initialContext; - } - - /** - * Get the default connection factory for the currently used broker - * Default factory is "local" - * - * @return A conection factory - * @throws Exception if there is an error getting the tactory - */ - public AMQConnectionFactory getConnectionFactory() throws Exception - { - _logger.info("get ConnectionFactory"); - if (_connectionFactory == null) - { - if (_broker.equals(VM)) - { - _connectionFactory = getConnectionFactory("vm"); - } - else - { - _connectionFactory = getConnectionFactory("local"); - } - } - return _connectionFactory; - } - - /** - * Get a connection factory for the currently used broker - * - * @param factoryName The factory name - * @return A conection factory - * @throws Exception if there is an error getting the tactory - */ - public AMQConnectionFactory getConnectionFactory(String factoryName) throws Exception - { - return (AMQConnectionFactory) getInitialContext().lookup(factoryName); - } - - public Connection getConnection() throws Exception - { - return getConnection("guest", "guest"); - } - - /** - * Get a connection (remote or in-VM) - * - * @param username The user name - * @param password The user password - * @return a newly created connection - * @throws Exception if there is an error getting the connection - */ - public Connection getConnection(String username, String password) throws Exception - { - _logger.info("get Connection"); - Connection con = getConnectionFactory().createConnection(username, password); - //add the connection in the lis of connections - _connections.add(con); - return con; - } - - public Connection getConnection(String username, String password, String id) throws Exception - { - _logger.info("get Connection"); - Connection con; - if (_broker.equals(VM)) - { - con = new AMQConnection("vm://:1", username, password, id, "test"); - } - else - { - con = getConnectionFactory().createConnection(username, password); - } - //add the connection in the lis of connections - _connections.add(con); - return con; - } - - protected void tearDown() throws java.lang.Exception - { - // close all the connections used by this test. - if (_brokerStarted) - { - for (Connection c : _connections) - { - c.close(); - } - } - } - -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/impl/ClientSession.java b/java/client/src/main/java/org/apache/qpidity/nclient/impl/ClientSession.java deleted file mode 100644 index f7d54a681f..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/impl/ClientSession.java +++ /dev/null @@ -1,204 +0,0 @@ -package org.apache.qpidity.nclient.impl; - -import java.io.EOFException; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.qpidity.QpidException; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.nclient.ClosedListener; -import org.apache.qpidity.nclient.MessagePartListener; -import org.apache.qpidity.transport.MessageAcceptMode; -import org.apache.qpidity.transport.MessageAcquireMode; -import org.apache.qpidity.transport.Option; -import org.apache.qpidity.transport.Range; -import org.apache.qpidity.transport.RangeSet; - -/** - * Implements a Qpid Sesion. - */ -public class ClientSession extends org.apache.qpidity.transport.Session implements org.apache.qpidity.nclient.DtxSession -{ - static - { - String max = "message_size_before_sync"; // KB's - try - { - MAX_NOT_SYNC_DATA_LENGH = new Long(System.getProperties().getProperty(max, "200000000")); - } - catch (NumberFormatException e) - { - // use default size - MAX_NOT_SYNC_DATA_LENGH = 200000000; - } - String flush = "message_size_before_flush"; - try - { - MAX_NOT_FLUSH_DATA_LENGH = new Long(System.getProperties().getProperty(flush, "2000000")); - } - catch (NumberFormatException e) - { - // use default size - MAX_NOT_FLUSH_DATA_LENGH = 20000000; - } - } - - private static long MAX_NOT_SYNC_DATA_LENGH; - private static long MAX_NOT_FLUSH_DATA_LENGH; - - private Map<String,MessagePartListener> _messageListeners = new ConcurrentHashMap<String,MessagePartListener>(); - private ClosedListener _exceptionListner; - private RangeSet _rejectedMessages; - private long _currentDataSizeNotSynced; - private long _currentDataSizeNotFlushed; - - public ClientSession(byte[] name) - { - super(name); - } - - public void messageAcknowledge(RangeSet ranges, boolean accept) - { - for (Range range : ranges) - { - super.processed(range); - } - super.flushProcessed(); - if( accept ) - { - messageAccept(ranges); - } - } - - public void messageSubscribe(String queue, String destination, short acceptMode, short acquireMode, MessagePartListener listener, Map<String, Object> filter, Option... options) - { - setMessageListener(destination,listener); - super.messageSubscribe(queue, destination, MessageAcceptMode.get(acceptMode), - MessageAcquireMode.get(acquireMode), null, 0, filter, - options); - } - - public void messageTransfer(String destination, Message msg, short acceptMode, short acquireMode) throws IOException - { - // The javadoc clearly says that this method is suitable for small messages - // therefore reading the content in one shot. - ByteBuffer data = msg.readData(); - super.messageTransfer(destination, MessageAcceptMode.get(acceptMode), - MessageAcquireMode.get(acquireMode)); - // super.header(msg.getDeliveryProperties(),msg.getMessageProperties() ); - if( msg.getHeader() == null || msg.getDeliveryProperties().isDirty() || msg.getMessageProperties().isDirty() ) - { - msg.setHeader( super.header(msg.getDeliveryProperties(),msg.getMessageProperties()) ); - msg.getDeliveryProperties().setDirty(false); - msg.getMessageProperties().setDirty(false); - } - else - { - super.header(msg.getHeader()); - } - data( data ); - endData(); - } - - public void sync() - { - super.sync(); - _currentDataSizeNotSynced = 0; - } - - /* ------------------------- - * Data methods - * ------------------------*/ - - public void data(ByteBuffer buf) - { - _currentDataSizeNotSynced = _currentDataSizeNotSynced + buf.remaining(); - _currentDataSizeNotFlushed = _currentDataSizeNotFlushed + buf.remaining(); - super.data(buf); - } - - public void data(String str) - { - _currentDataSizeNotSynced = _currentDataSizeNotSynced + str.getBytes().length; - super.data(str); - } - - public void data(byte[] bytes) - { - _currentDataSizeNotSynced = _currentDataSizeNotSynced + bytes.length; - super.data(bytes); - } - - public void messageStream(String destination, Message msg, short acceptMode, short acquireMode) throws IOException - { - super.messageTransfer(destination, MessageAcceptMode.get(acceptMode), - MessageAcquireMode.get(acquireMode)); - super.header(msg.getDeliveryProperties(),msg.getMessageProperties()); - boolean b = true; - int count = 0; - while(b) - { - try - { - System.out.println("count : " + count++); - data(msg.readData()); - } - catch(EOFException e) - { - b = false; - } - } - endData(); - } - - public void endData() - { - super.endData(); - /* if( MAX_NOT_SYNC_DATA_LENGH != -1 && _currentDataSizeNotSynced >= MAX_NOT_SYNC_DATA_LENGH) - { - sync(); - } - if( MAX_NOT_FLUSH_DATA_LENGH != -1 && _currentDataSizeNotFlushed >= MAX_NOT_FLUSH_DATA_LENGH) - { - executionFlush(); - _currentDataSizeNotFlushed = 0; - }*/ - } - - public RangeSet getRejectedMessages() - { - return _rejectedMessages; - } - - public void setMessageListener(String destination, MessagePartListener listener) - { - if (listener == null) - { - throw new IllegalArgumentException("Cannot set message listener to null"); - } - _messageListeners.put(destination, listener); - } - - public void setClosedListener(ClosedListener exceptionListner) - { - _exceptionListner = exceptionListner; - } - - void setRejectedMessages(RangeSet rejectedMessages) - { - _rejectedMessages = rejectedMessages; - } - - void notifyException(QpidException ex) - { - _exceptionListner.onClosed(null, null, null); - } - - Map<String,MessagePartListener> getMessageListeners() - { - return _messageListeners; - } -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/impl/ClientSessionDelegate.java b/java/client/src/main/java/org/apache/qpidity/nclient/impl/ClientSessionDelegate.java deleted file mode 100644 index e57dd08448..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/impl/ClientSessionDelegate.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.apache.qpidity.nclient.impl; - -import java.nio.ByteBuffer; - -import org.apache.qpidity.ErrorCode; - -import org.apache.qpidity.nclient.MessagePartListener; - -import org.apache.qpidity.QpidException; -import org.apache.qpidity.transport.Data; -import org.apache.qpidity.transport.Header; -import org.apache.qpidity.transport.MessageReject; -import org.apache.qpidity.transport.MessageTransfer; -import org.apache.qpidity.transport.Range; -import org.apache.qpidity.transport.Session; -import org.apache.qpidity.transport.SessionDetached; -import org.apache.qpidity.transport.SessionDelegate; - - -public class ClientSessionDelegate extends SessionDelegate -{ - private MessageTransfer _currentTransfer; - private MessagePartListener _currentMessageListener; - - @Override public void sessionDetached(Session ssn, SessionDetached dtc) - { - ((ClientSession)ssn).notifyException(new QpidException("", ErrorCode.get(dtc.getCode().getValue()),null)); - } - - // -------------------------------------------- - // Message methods - // -------------------------------------------- - @Override public void data(Session ssn, Data data) - { - for (ByteBuffer b : data.getFragments()) - { - _currentMessageListener.data(b); - } - if (data.isLast()) - { - _currentMessageListener.messageReceived(); - } - - } - - @Override public void header(Session ssn, Header header) - { - _currentMessageListener.messageHeader(header); - if( header.hasNoPayload()) - { - _currentMessageListener.data(ByteBuffer.allocate(0)); - _currentMessageListener.messageReceived(); - } - } - - - @Override public void messageTransfer(Session session, MessageTransfer currentTransfer) - { - _currentTransfer = currentTransfer; - _currentMessageListener = ((ClientSession)session).getMessageListeners().get(currentTransfer.getDestination()); - _currentMessageListener.messageTransfer(currentTransfer.getId()); - } - - @Override public void messageReject(Session session, MessageReject struct) - { - for (Range range : struct.getTransfers()) - { - for (long l = range.getLower(); l <= range.getUpper(); l++) - { - System.out.println("message rejected: " + - session.getCommand((int) l)); - } - } - ((ClientSession)session).setRejectedMessages(struct.getTransfers()); - ((ClientSession)session).notifyException(new QpidException("Message Rejected",ErrorCode.MESSAGE_REJECTED,null)); - session.processed(struct); - } - -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/impl/LargeMsgDemoClient.java b/java/client/src/main/java/org/apache/qpidity/nclient/impl/LargeMsgDemoClient.java deleted file mode 100644 index 64ffe17fe0..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/impl/LargeMsgDemoClient.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.apache.qpidity.nclient.impl; - -import java.io.FileInputStream; - -import org.apache.qpidity.ErrorCode; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.ClosedListener; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.nclient.util.FileMessage; -import org.apache.qpidity.nclient.util.MessageListener; -import org.apache.qpidity.nclient.util.MessagePartListenerAdapter; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageProperties; - -import java.util.UUID; - -public class LargeMsgDemoClient -{ - public static MessagePartListenerAdapter createAdapter() - { - return new MessagePartListenerAdapter(new MessageListener() - { - public void onMessage(Message m) - { - System.out.println("\n================== Received Msg =================="); - System.out.println("Message Id : " + m.getMessageProperties().getMessageId()); - System.out.println(m.toString()); - System.out.println("================== End Msg ==================\n"); - } - - }); - } - - public static final void main(String[] args) - { - Connection conn = Client.createConnection(); - try{ - conn.connect("0.0.0.0", 5672, "test", "guest", "guest"); - }catch(Exception e){ - e.printStackTrace(); - } - - Session ssn = conn.createSession(50000); - ssn.setClosedListener(new ClosedListener() - { - public void onClosed(ErrorCode errorCode, String reason, Throwable t) - { - System.out.println("ErrorCode : " + errorCode + " reason : " + reason); - } - }); - ssn.queueDeclare("queue1", null, null); - ssn.exchangeBind("queue1", "amq.direct", "queue1",null); - ssn.sync(); - - ssn.messageSubscribe("queue1", "myDest", (short)0, (short)0,createAdapter(), null); - - try - { - FileMessage msg = new FileMessage(new FileInputStream("/home/rajith/TestFile"), - 1024, - new DeliveryProperties().setRoutingKey("queue1"), - new MessageProperties().setMessageId(UUID.randomUUID())); - - // queue - ssn.messageStream("amq.direct",msg, (short) 0, (short) 1); - ssn.sync(); - } - catch(Exception e) - { - e.printStackTrace(); - } - } - -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/util/MessagePartListenerAdapter.java b/java/client/src/main/java/org/apache/qpidity/nclient/util/MessagePartListenerAdapter.java deleted file mode 100644 index 757d44fbbb..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/util/MessagePartListenerAdapter.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.apache.qpidity.nclient.util; - -import java.io.IOException; -import java.nio.ByteBuffer; - -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageProperties; -import org.apache.qpidity.transport.Header; -import org.apache.qpidity.nclient.MessagePartListener; - -/** - * This is a simple message assembler. - * Will call onMessage method of the adaptee - * when all message data is read. - * - * This is a good convinience utility for handling - * small messages - */ -public class MessagePartListenerAdapter implements MessagePartListener -{ - MessageListener _adaptee; - ByteBufferMessage _currentMsg; - - public MessagePartListenerAdapter(MessageListener listener) - { - _adaptee = listener; - } - - public void messageTransfer(int transferId) - { - _currentMsg = new ByteBufferMessage(transferId); - } - - public void data(ByteBuffer src) - { - try - { - _currentMsg.appendData(src); - } - catch(IOException e) - { - // A chance for IO exception - // doesn't occur as we are using - // a ByteBuffer - } - } - - public void messageHeader(Header header) - { - _currentMsg.setDeliveryProperties(header.get(DeliveryProperties.class)); - _currentMsg.setMessageProperties(header.get(MessageProperties.class)); - } - - public void messageReceived() - { - _adaptee.onMessage(_currentMsg); - } - -} diff --git a/java/client/src/test/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.java b/java/client/src/test/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.java new file mode 100644 index 0000000000..5323ad28bf --- /dev/null +++ b/java/client/src/test/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.java @@ -0,0 +1,125 @@ +/* + * + * 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.mina.transport.vmpipe.support; + +import org.apache.mina.common.IdleStatus; + +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * This file is a patch to override MINA, because of the IdentityHashMap bug. Workaround to be supplied in MINA 1.0.7. + * This patched file will be removed once upgraded onto a newer MINA. + * + * Dectects idle sessions and fires <tt>sessionIdle</tt> events to them. + * + * @author The Apache Directory Project (mina-dev@directory.apache.org) + */ +public class VmPipeIdleStatusChecker +{ + private static final VmPipeIdleStatusChecker INSTANCE = new VmPipeIdleStatusChecker(); + + public static VmPipeIdleStatusChecker getInstance() + { + return INSTANCE; + } + + private final Map sessions = new HashMap(); // will use as a set + + private final Worker worker = new Worker(); + + private VmPipeIdleStatusChecker() + { + worker.start(); + } + + public void addSession(VmPipeSessionImpl session) + { + synchronized (sessions) + { + sessions.put(session, session); + } + } + + private class Worker extends Thread + { + private Worker() + { + super("VmPipeIdleStatusChecker"); + setDaemon(true); + } + + public void run() + { + for (;;) + { + try + { + Thread.sleep(1000); + } + catch (InterruptedException e) + { } + + long currentTime = System.currentTimeMillis(); + + synchronized (sessions) + { + Iterator it = sessions.keySet().iterator(); + while (it.hasNext()) + { + VmPipeSessionImpl session = (VmPipeSessionImpl) it.next(); + if (!session.isConnected()) + { + it.remove(); + } + else + { + notifyIdleSession(session, currentTime); + } + } + } + } + } + } + + private void notifyIdleSession(VmPipeSessionImpl session, long currentTime) + { + notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.BOTH_IDLE), IdleStatus.BOTH_IDLE, + Math.max(session.getLastIoTime(), session.getLastIdleTime(IdleStatus.BOTH_IDLE))); + notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.READER_IDLE), IdleStatus.READER_IDLE, + Math.max(session.getLastReadTime(), session.getLastIdleTime(IdleStatus.READER_IDLE))); + notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.WRITER_IDLE), IdleStatus.WRITER_IDLE, + Math.max(session.getLastWriteTime(), session.getLastIdleTime(IdleStatus.WRITER_IDLE))); + } + + private void notifyIdleSession0(VmPipeSessionImpl session, long currentTime, long idleTime, IdleStatus status, + long lastIoTime) + { + if ((idleTime > 0) && (lastIoTime != 0) && ((currentTime - lastIoTime) >= idleTime)) + { + session.increaseIdleCount(status); + session.getFilterChain().fireSessionIdle(session, status); + } + } + +} diff --git a/java/client/src/test/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java b/java/client/src/test/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java deleted file mode 100644 index fe418535d6..0000000000 --- a/java/client/src/test/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * - * 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.qpid.client; - -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.TextMessage; - -import junit.framework.TestCase; - -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.jms.Session; -import org.apache.qpid.client.transport.TransportConnection; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This class tests all the alerts an AMQQueue can throw based on threshold - * values of different parameters - */ -public class AMQQueueDeferredOrderingTest extends TestCase -{ - - private static final int NUM_MESSAGES = 1000; - - private AMQConnection con; - private Session session; - private AMQQueue queue; - private MessageConsumer consumer; - - private static final Logger _logger = LoggerFactory.getLogger(AMQQueueDeferredOrderingTest.class); - - private ASyncProducer producerThread; - private static final String BROKER = "vm://:1"; - - private class ASyncProducer extends Thread - { - - private MessageProducer producer; - private final Logger _logger = LoggerFactory.getLogger(ASyncProducer.class); - private Session session; - private int start; - private int end; - - public ASyncProducer(AMQQueue q, int start, int end) throws Exception - { - this.session = con.createSession(false, Session.AUTO_ACKNOWLEDGE); - this._logger.info("Create Consumer of Q1"); - this.producer = this.session.createProducer(q); - this.start = start; - this.end = end; - } - - public void run() - { - try - { - this._logger.info("Starting to send messages"); - for (int i = start; i < end && !interrupted(); i++) - { - producer.send(session.createTextMessage(Integer.toString(i))); - } - this._logger.info("Sent " + (end - start) + " messages"); - } - catch (JMSException e) - { - throw new RuntimeException(e); - } - } - } - - protected void setUp() throws Exception - { - super.setUp(); - TransportConnection.createVMBroker(1); - - _logger.info("Create Connection"); - con = new AMQConnection(BROKER, "guest", "guest", "OrderingTest", "test"); - _logger.info("Create Session"); - session = con.createSession(false, Session.AUTO_ACKNOWLEDGE); - _logger.info("Create Q"); - queue = new AMQQueue(session.getDefaultQueueExchangeName(), new AMQShortString("Q"), new AMQShortString("Q"), - false, true); - _logger.info("Create Consumer of Q"); - consumer = session.createConsumer(queue); - _logger.info("Start Connection"); - con.start(); - } - - public void testPausedOrder() throws Exception - { - - // Setup initial messages - _logger.info("Creating first producer thread"); - producerThread = new ASyncProducer(queue, 0, NUM_MESSAGES / 2); - producerThread.start(); - // Wait for them to be done - producerThread.join(); - - // Setup second set of messages to produce while we consume - _logger.info("Creating second producer thread"); - producerThread = new ASyncProducer(queue, NUM_MESSAGES / 2, NUM_MESSAGES); - producerThread.start(); - - // Start consuming and checking they're in order - _logger.info("Consuming messages"); - for (int i = 0; i < NUM_MESSAGES; i++) - { - Message msg = consumer.receive(3000); - assertNotNull("Message should not be null", msg); - assertTrue("Message should be a text message", msg instanceof TextMessage); - assertEquals("Message content does not match expected", Integer.toString(i), ((TextMessage) msg).getText()); - } - } - - protected void tearDown() throws Exception - { - _logger.info("Interuptting producer thread"); - producerThread.interrupt(); - _logger.info("Closing connection"); - con.close(); - - TransportConnection.killAllVMBrokers(); - super.tearDown(); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(AMQQueueDeferredOrderingTest.class); - } - -} diff --git a/java/client/src/test/java/org/apache/qpid/client/DispatcherTest.java b/java/client/src/test/java/org/apache/qpid/client/DispatcherTest.java deleted file mode 100644 index 7cca22de6c..0000000000 --- a/java/client/src/test/java/org/apache/qpid/client/DispatcherTest.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * 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.qpid.client; - -import junit.framework.TestCase; - -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.jndi.PropertiesFileInitialContextFactory; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.naming.Context; -import javax.naming.spi.InitialContextFactory; - -import java.util.Hashtable; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * QPID-293 Setting MessageListener after connection has started can cause messages to be "lost" on a internal delivery queue - * <p/> - * The message delivery process: - * Mina puts a message on _queue in AMQSession and the dispatcher thread take()s - * from here and dispatches to the _consumers. If the _consumer doesn't have a message listener set at connection start - * then messages are stored on _synchronousQueue (which needs to be > 1 to pass JMS TCK as multiple consumers on a - * session can run in any order and a synchronous put/poll will block the dispatcher). - * <p/> - * When setting the message listener later the _synchronousQueue is just poll()'ed and the first message delivered - * the remaining messages will be left on the queue and lost, subsequent messages on the session will arrive first. - */ -public class DispatcherTest extends TestCase -{ - private static final Logger _logger = LoggerFactory.getLogger(DispatcherTest.class); - - Context _context; - - private static final int MSG_COUNT = 6; - private int _receivedCount = 0; - private int _receivedCountWhileStopped = 0; - private Connection _clientConnection, _producerConnection; - private MessageConsumer _consumer; - MessageProducer _producer; - Session _clientSession, _producerSession; - - private final CountDownLatch _allFirstMessagesSent = new CountDownLatch(1); // all messages Sent Lock - private final CountDownLatch _allSecondMessagesSent = new CountDownLatch(1); // all messages Sent Lock - - private volatile boolean _connectionStopped = false; - - protected void setUp() throws Exception - { - super.setUp(); - TransportConnection.createVMBroker(1); - - InitialContextFactory factory = new PropertiesFileInitialContextFactory(); - - Hashtable<String, String> env = new Hashtable<String, String>(); - - env.put("connectionfactory.connection", "amqp://guest:guest@MLT_ID/test?brokerlist='vm://:1'"); - env.put("queue.queue", "MessageListenerTest"); - - _context = factory.getInitialContext(env); - - Queue queue = (Queue) _context.lookup("queue"); - - // Create Client 1 - _clientConnection = ((ConnectionFactory) _context.lookup("connection")).createConnection(); - - _clientSession = _clientConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - _consumer = _clientSession.createConsumer(queue); - - // Create Producer - _producerConnection = ((ConnectionFactory) _context.lookup("connection")).createConnection(); - - _producerConnection.start(); - - _producerSession = _producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - _producer = _producerSession.createProducer(queue); - - for (int msg = 0; msg < MSG_COUNT; msg++) - { - _producer.send(_producerSession.createTextMessage("Message " + msg)); - } - } - - protected void tearDown() throws Exception - { - - _clientConnection.close(); - - _producerConnection.close(); - super.tearDown(); - TransportConnection.killAllVMBrokers(); - } - - public void testAsynchronousRecieve() - { - _logger.info("Test Start"); - - assertTrue(!((AMQConnection) _clientConnection).started()); - - // Set default Message Listener - try - { - _consumer.setMessageListener(new MessageListener() - { - public void onMessage(Message message) - { - _logger.info("Client 1 ML 1 Received Message(" + _receivedCount + "):" + message); - - _receivedCount++; - - if (_receivedCount == MSG_COUNT) - { - _allFirstMessagesSent.countDown(); - } - - if (_connectionStopped) - { - _logger.info("Running with Message:" + _receivedCount); - } - - if (_connectionStopped && (_allFirstMessagesSent.getCount() == 0)) - { - _receivedCountWhileStopped++; - } - - if (_allFirstMessagesSent.getCount() == 0) - { - if (_receivedCount == (MSG_COUNT * 2)) - { - _allSecondMessagesSent.countDown(); - } - } - } - }); - - assertTrue("Connecion should not be started", !((AMQConnection) _clientConnection).started()); - _clientConnection.start(); - } - catch (JMSException e) - { - _logger.error("Error Setting Default ML on consumer1"); - } - - try - { - _allFirstMessagesSent.await(1000, TimeUnit.MILLISECONDS); - } - catch (InterruptedException e) - { - // do nothing - } - - try - { - assertTrue("Connecion should be started", ((AMQConnection) _clientConnection).started()); - _clientConnection.stop(); - _connectionStopped = true; - } - catch (JMSException e) - { - _logger.error("Error stopping connection"); - } - - try - { - _logger.error("Send additional messages"); - - for (int msg = 0; msg < MSG_COUNT; msg++) - { - _producer.send(_producerSession.createTextMessage("Message " + msg)); - } - } - catch (JMSException e) - { - _logger.error("Unable to send additional messages", e); - } - - try - { - Thread.sleep(1000); - } - catch (InterruptedException e) - { - // ignore - } - - try - { - _logger.info("Restarting connection"); - - _connectionStopped = false; - _clientConnection.start(); - } - catch (JMSException e) - { - _logger.error("Error Setting Better ML on consumer1", e); - } - - _logger.info("Waiting upto 2 seconds for messages"); - - try - { - _allSecondMessagesSent.await(1000, TimeUnit.MILLISECONDS); - } - catch (InterruptedException e) - { - // do nothing - } - - assertEquals("Messages not received correctly", 0, _allFirstMessagesSent.getCount()); - assertEquals("Messages not received correctly", 0, _allSecondMessagesSent.getCount()); - assertEquals("Client didn't get all messages", MSG_COUNT * 2, _receivedCount); - assertEquals("Messages received while stopped is not 0", 0, _receivedCountWhileStopped); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(DispatcherTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerImmediatePrefetch.java b/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerImmediatePrefetch.java deleted file mode 100644 index 7461f6c200..0000000000 --- a/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerImmediatePrefetch.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.qpid.client; - -/** - * QPID-293 Setting MessageListener after connection has started can cause messages to be "lost" on a internal delivery - * queue <p/> The message delivery process: Mina puts a message on _queue in AMQSession and the dispatcher thread - * take()s from here and dispatches to the _consumers. If the _consumer1 doesn't have a message listener set at - * connection start then messages are stored on _synchronousQueue (which needs to be > 1 to pass JMS TCK as multiple - * consumers on a session can run in any order and a synchronous put/poll will block the dispatcher). <p/> When setting - * the message listener later the _synchronousQueue is just poll()'ed and the first message delivered the remaining - * messages will be left on the queue and lost, subsequent messages on the session will arrive first. - */ -public class MessageListenerMultiConsumerImmediatePrefetch extends MessageListenerMultiConsumerTest -{ - protected void setUp() throws Exception - { - System.setProperty(AMQSession.IMMEDIATE_PREFETCH, "true"); - super.setUp(); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(MessageListenerMultiConsumerImmediatePrefetch.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java b/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java deleted file mode 100644 index 136b9b94b6..0000000000 --- a/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * 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.qpid.client; - -import junit.framework.TestCase; - -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.jndi.PropertiesFileInitialContextFactory; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.naming.Context; -import javax.naming.spi.InitialContextFactory; - -import java.util.Hashtable; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * QPID-293 Setting MessageListener after connection has started can cause messages to be "lost" on a internal delivery - * queue <p/> The message delivery process: Mina puts a message on _queue in AMQSession and the dispatcher thread - * take()s from here and dispatches to the _consumers. If the _consumer1 doesn't have a message listener set at - * connection start then messages are stored on _synchronousQueue (which needs to be > 1 to pass JMS TCK as multiple - * consumers on a session can run in any order and a synchronous put/poll will block the dispatcher). <p/> When setting - * the message listener later the _synchronousQueue is just poll()'ed and the first message delivered the remaining - * messages will be left on the queue and lost, subsequent messages on the session will arrive first. - */ -public class MessageListenerMultiConsumerTest extends QpidTestCase -{ - private static final Logger _logger = LoggerFactory.getLogger(MessageListenerMultiConsumerTest.class); - - Context _context; - - private static final int MSG_COUNT = 6; - private int receivedCount1 = 0; - private int receivedCount2 = 0; - private Connection _clientConnection; - private MessageConsumer _consumer1; - private MessageConsumer _consumer2; - private Session _clientSession1; - private Queue _queue; - private final CountDownLatch _allMessagesSent = new CountDownLatch(2); // all messages Sent Lock - - protected void setUp() throws Exception - { - super.setUp(); - - // Create Client 1 - _clientConnection = getConnection("guest", "guest"); - - _clientConnection.start(); - - _clientSession1 = _clientConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - _queue =_clientSession1.createQueue("queue"); - - _consumer1 = _clientSession1.createConsumer(_queue); - - // Create Client 2 - Session clientSession2 = _clientConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - _consumer2 = clientSession2.createConsumer(_queue); - - // Create Producer - Connection producerConnection = getConnection("guest", "guest"); - - producerConnection.start(); - - Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - MessageProducer producer = producerSession.createProducer(_queue); - - for (int msg = 0; msg < MSG_COUNT; msg++) - { - producer.send(producerSession.createTextMessage("Message " + msg)); - } - - producerConnection.close(); - - } - - protected void tearDown() throws Exception - { - _clientConnection.close(); - super.tearDown(); - } - - public void testRecieveInterleaved() throws Exception - { - int msg = 0; - int MAX_LOOPS = MSG_COUNT * 2; - for (int loops = 0; (msg < MSG_COUNT) || (loops < MAX_LOOPS); loops++) - { - - if (_consumer1.receive(100) != null) - { - msg++; - } - - if (_consumer2.receive(100) != null) - { - msg++; - } - } - - assertEquals("Not all messages received.", MSG_COUNT, msg); - } - - public void testAsynchronousRecieve() throws Exception - { - _consumer1.setMessageListener(new MessageListener() - { - public void onMessage(Message message) - { - _logger.info("Client 1 Received Message(" + receivedCount1 + "):" + message); - - receivedCount1++; - - if (receivedCount1 == (MSG_COUNT / 2)) - { - _allMessagesSent.countDown(); - } - - } - }); - - _consumer2.setMessageListener(new MessageListener() - { - public void onMessage(Message message) - { - _logger.info("Client 2 Received Message(" + receivedCount2 + "):" + message); - - receivedCount2++; - if (receivedCount2 == (MSG_COUNT / 2)) - { - _allMessagesSent.countDown(); - } - } - }); - - _logger.info("Waiting upto 2 seconds for messages"); - - try - { - _allMessagesSent.await(4000, TimeUnit.MILLISECONDS); - } - catch (InterruptedException e) - { - // do nothing - } - - assertEquals(MSG_COUNT, receivedCount1 + receivedCount2); - } - - public void testRecieveC2Only() throws Exception - { - if ( - !Boolean.parseBoolean( - System.getProperties().getProperty(AMQSession.IMMEDIATE_PREFETCH, - AMQSession.IMMEDIATE_PREFETCH_DEFAULT))) - { - _logger.info("Performing Receive only on C2"); - for (int msg = 0; msg < MSG_COUNT; msg++) - { - assertTrue(MSG_COUNT + " msg should be received. Only received:" + msg, _consumer2.receive(1000) != null); - } - } - } - - public void testRecieveBoth() throws Exception - { - if ( - !Boolean.parseBoolean( - System.getProperties().getProperty(AMQSession.IMMEDIATE_PREFETCH, - AMQSession.IMMEDIATE_PREFETCH_DEFAULT))) - { - _logger.info("Performing Receive only with two consumers on one session "); - - MessageConsumer consumer2 = _clientSession1.createConsumer(_queue); - - for (int msg = 0; msg < (MSG_COUNT / 2); msg++) - { - - assertTrue(_consumer1.receive(3000) != null); - } - - for (int msg = 0; msg < (MSG_COUNT / 2); msg++) - { - assertTrue(consumer2.receive(3000) != null); - } - } - else - { - _logger.info("Performing Receive only on both C1 and C2"); - - for (int msg = 0; msg < (MSG_COUNT / 2); msg++) - { - - assertTrue(_consumer1.receive(3000) != null); - } - - for (int msg = 0; msg < (MSG_COUNT / 2); msg++) - { - assertTrue(_consumer2.receive(3000) != null); - } - } - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(MessageListenerMultiConsumerTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java b/java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java deleted file mode 100644 index 12b84b1495..0000000000 --- a/java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * 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.qpid.client; - -import junit.framework.TestCase; - -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.jndi.PropertiesFileInitialContextFactory; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.naming.Context; -import javax.naming.spi.InitialContextFactory; - -import java.util.Hashtable; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * QPID-293 Setting MessageListener after connection has started can cause messages to be "lost" on a internal delivery - * queue <p/> The message delivery process: Mina puts a message on _queue in AMQSession and the dispatcher thread - * take()s from here and dispatches to the _consumers. If the _consumer doesn't have a message listener set at - * connection start then messages are stored on _synchronousQueue (which needs to be > 1 to pass JMS TCK as multiple - * consumers on a session can run in any order and a synchronous put/poll will block the dispatcher). <p/> When setting - * the message listener later the _synchronousQueue is just poll()'ed and the first message delivered the remaining - * messages will be left on the queue and lost, subsequent messages on the session will arrive first. - */ -public class MessageListenerTest extends QpidTestCase implements MessageListener -{ - private static final Logger _logger = LoggerFactory.getLogger(MessageListenerTest.class); - - Context _context; - - private static final int MSG_COUNT = 5; - private int receivedCount = 0; - private MessageConsumer _consumer; - private Connection _clientConnection; - private CountDownLatch _awaitMessages = new CountDownLatch(MSG_COUNT); - - protected void setUp() throws Exception - { - super.setUp(); - - // Create Client - _clientConnection = getConnection("guest", "guest"); - - _clientConnection.start(); - - Session clientSession = _clientConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - Queue queue =clientSession.createQueue("message-listener-test-queue"); - - _consumer = clientSession.createConsumer(queue); - - // Create Producer - - Connection producerConnection = getConnection("guest", "guest"); - - producerConnection.start(); - - Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - MessageProducer producer = producerSession.createProducer(queue); - - for (int msg = 0; msg < MSG_COUNT; msg++) - { - producer.send(producerSession.createTextMessage("Message " + msg)); - } - - producerConnection.close(); - - } - - protected void tearDown() throws Exception - { - _clientConnection.close(); - super.tearDown(); - } - - public void testSynchronousRecieve() throws Exception - { - for (int msg = 0; msg < MSG_COUNT; msg++) - { - assertTrue(_consumer.receive(2000) != null); - } - } - - public void testAsynchronousRecieve() throws Exception - { - _consumer.setMessageListener(this); - - _logger.info("Waiting 3 seconds for messages"); - - try - { - _awaitMessages.await(3000, TimeUnit.MILLISECONDS); - } - catch (InterruptedException e) - { - // do nothing - } - // Should have recieved all async messages - assertEquals(MSG_COUNT, receivedCount); - - } - - public void testRecieveTheUseMessageListener() throws Exception - { - - _logger.error("Test disabled as initial receive is not called first"); - // Perform initial receive to start connection - // assertTrue(_consumer.receive(2000) != null); - // receivedCount++; - - // Sleep to ensure remaining 4 msgs end up on _synchronousQueue - // Thread.sleep(1000); - - // Set the message listener and wait for the messages to come in. - _consumer.setMessageListener(this); - - _logger.info("Waiting 3 seconds for messages"); - - try - { - _awaitMessages.await(3000, TimeUnit.MILLISECONDS); - } - catch (InterruptedException e) - { - // do nothing - } - // Should have recieved all async messages - assertEquals(MSG_COUNT, receivedCount); - - } - - public void onMessage(Message message) - { - _logger.info("Received Message(" + receivedCount + "):" + message); - - receivedCount++; - _awaitMessages.countDown(); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(MessageListenerTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/client/ResetMessageListenerTest.java b/java/client/src/test/java/org/apache/qpid/client/ResetMessageListenerTest.java deleted file mode 100644 index c920499a07..0000000000 --- a/java/client/src/test/java/org/apache/qpid/client/ResetMessageListenerTest.java +++ /dev/null @@ -1,393 +0,0 @@ -/* - * 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.qpid.client; - -import junit.framework.TestCase; - -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.jndi.PropertiesFileInitialContextFactory; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.TextMessage; -import javax.naming.Context; -import javax.naming.spi.InitialContextFactory; - -import java.util.Hashtable; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * QPID-293 Setting MessageListener after connection has started can cause messages to be "lost" on a internal delivery - * queue <p/> The message delivery process: Mina puts a message on _queue in AMQSession and the dispatcher thread - * take()s from here and dispatches to the _consumers. If the _consumer1 doesn't have a message listener set at - * connection start then messages are stored on _synchronousQueue (which needs to be > 1 to pass JMS TCK as multiple - * consumers on a session can run in any order and a synchronous put/poll will block the dispatcher). <p/> When setting - * the message listener later the _synchronousQueue is just poll()'ed and the first message delivered the remaining - * messages will be left on the queue and lost, subsequent messages on the session will arrive first. - */ -public class ResetMessageListenerTest extends QpidTestCase -{ - private static final Logger _logger = LoggerFactory.getLogger(ResetMessageListenerTest.class); - - Context _context; - - private static final int MSG_COUNT = 6; - private int receivedCount1ML1 = 0; - private int receivedCount1ML2 = 0; - private int receivedCount2 = 0; - private Connection _clientConnection, _producerConnection; - private MessageConsumer _consumer1; - private MessageConsumer _consumer2; - MessageProducer _producer; - Session _clientSession, _producerSession; - - private final CountDownLatch _allFirstMessagesSent = new CountDownLatch(2); // all messages Sent Lock - private final CountDownLatch _allSecondMessagesSent = new CountDownLatch(2); // all messages Sent Lock - private final CountDownLatch _allFirstMessagesSent010 = new CountDownLatch(MSG_COUNT); // all messages Sent Lock - private final CountDownLatch _allSecondMessagesSent010 = new CountDownLatch(MSG_COUNT); // all messages Sent Lock - - private String oldImmediatePrefetch; - - protected void setUp() throws Exception - { - super.setUp(); - - oldImmediatePrefetch = System.getProperty(AMQSession.IMMEDIATE_PREFETCH); - System.setProperty(AMQSession.IMMEDIATE_PREFETCH, "true"); - - _clientConnection = getConnection("guest", "guest"); - - // Create Client 1 - - _clientSession = _clientConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - Queue queue = _clientSession.createQueue("reset-message-listener-test-queue"); - - _consumer1 = _clientSession.createConsumer(queue); - - // Create Client 2 on same session - _consumer2 = _clientSession.createConsumer(queue); - - // Create Producer - _producerConnection = getConnection("guest", "guest"); - - _producerConnection.start(); - - _producerSession = _producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - _producer = _producerSession.createProducer(queue); - - TextMessage m = _producerSession.createTextMessage(); - m.setStringProperty("rank", "first"); - for (int msg = 0; msg < MSG_COUNT; msg++) - { - m.setText("Message " + msg); - _producer.send(m); - } - - } - - protected void tearDown() throws Exception - { - _clientConnection.close(); - - super.tearDown(); - if (oldImmediatePrefetch == null) - { - oldImmediatePrefetch = AMQSession.IMMEDIATE_PREFETCH_DEFAULT; - } - System.setProperty(AMQSession.IMMEDIATE_PREFETCH, oldImmediatePrefetch); - } - - public void testAsynchronousRecieve() - { - - _logger.info("Test Start"); - if (isBroker08()) - { - // Set default Message Listener - try - { - _consumer1.setMessageListener(new MessageListener() - { - public void onMessage(Message message) - { - _logger.info("Client 1 ML 1 Received Message(" + receivedCount1ML1 + "):" + message); - - receivedCount1ML1++; - if (receivedCount1ML1 == (MSG_COUNT / 2)) - { - _allFirstMessagesSent.countDown(); - } - } - }); - } - catch (JMSException e) - { - _logger.error("Error Setting Default ML on consumer1"); - } - - try - { - _consumer2.setMessageListener(new MessageListener() - { - public void onMessage(Message message) - { - _logger.info("Client 2 Received Message(" + receivedCount2 + "):" + message); - - receivedCount2++; - if (receivedCount2 == (MSG_COUNT / 2)) - { - _logger.info("Client 2 received all its messages1"); - _allFirstMessagesSent.countDown(); - } - - if (receivedCount2 == MSG_COUNT) - { - _logger.info("Client 2 received all its messages2"); - _allSecondMessagesSent.countDown(); - } - } - }); - - _clientConnection.start(); - } - catch (JMSException e) - { - _logger.error("Error Setting Default ML on consumer2"); - - } - - try - { - _allFirstMessagesSent.await(1000, TimeUnit.MILLISECONDS); - _logger.info("Received first batch of messages"); - } - catch (InterruptedException e) - { - // do nothing - } - - try - { - _clientConnection.stop(); - } - catch (JMSException e) - { - _logger.error("Error stopping connection"); - } - - _logger.info("Reset Message Listener to better listener while connection stopped, will restart session"); - try - { - _consumer1.setMessageListener(new MessageListener() - { - public void onMessage(Message message) - { - _logger.info("Client 1 ML2 Received Message(" + receivedCount1ML1 + "):" + message); - - receivedCount1ML2++; - if (receivedCount1ML2 == (MSG_COUNT / 2)) - { - _allSecondMessagesSent.countDown(); - } - } - }); - - _clientConnection.start(); - } - catch (javax.jms.IllegalStateException e) - { - _logger.error("Connection not stopped while setting ML", e); - fail("Unable to change message listener:" + e.getCause()); - } - catch (JMSException e) - { - _logger.error("Error Setting Better ML on consumer1", e); - } - - try - { - _logger.info("Send additional messages"); - - for (int msg = 0; msg < MSG_COUNT; msg++) - { - _producer.send(_producerSession.createTextMessage("Message " + msg)); - } - } - catch (JMSException e) - { - _logger.error("Unable to send additional messages", e); - } - - _logger.info("Waiting upto 2 seconds for messages"); - - try - { - _allSecondMessagesSent.await(5000, TimeUnit.MILLISECONDS); - } - catch (InterruptedException e) - { - // do nothing - } - assertEquals("First batch of messages not received correctly", 0, _allFirstMessagesSent.getCount()); - assertEquals("Second batch of messages not received correctly", 0, _allSecondMessagesSent.getCount()); - assertEquals("Client 1 ML1 didn't get all messages", MSG_COUNT / 2, receivedCount1ML1); - assertEquals("Client 2 didn't get all messages", MSG_COUNT, receivedCount2); - assertEquals("Client 1 ML2 didn't get all messages", MSG_COUNT / 2, receivedCount1ML2); - } - else - { - try - { - _consumer2.close(); - _consumer1.setMessageListener(new MessageListener() - { - public void onMessage(Message message) - { - _logger.info("Received Message(" + receivedCount1ML1 + "):" + message); - - try - { - if (message.getStringProperty("rank").equals("first")) - { - _allFirstMessagesSent010.countDown(); - } - } - catch (JMSException e) - { - e.printStackTrace(); - fail("error receiving message"); - } - } - }); - } - catch (JMSException e) - { - _logger.error("Error Setting Default ML on consumer1"); - } - try - { - _allFirstMessagesSent.await(1000, TimeUnit.MILLISECONDS); - _logger.info("Received first batch of messages"); - } - catch (InterruptedException e) - { - // do nothing - } - - try - { - _clientConnection.stop(); - } - catch (JMSException e) - { - _logger.error("Error stopping connection"); - } - - _logger.info("Reset Message Listener "); - try - { - _consumer1.setMessageListener(new MessageListener() - { - public void onMessage(Message message) - { - _logger.info("Received Message(" + receivedCount1ML1 + "):" + message); - - try - { - if (message.getStringProperty("rank").equals("first")) - { - _allFirstMessagesSent010.countDown(); - } - else - { - _allSecondMessagesSent010.countDown(); - } - } - catch (JMSException e) - { - e.printStackTrace(); - fail("error receiving message"); - } - } - }); - - _clientConnection.start(); - } - catch (javax.jms.IllegalStateException e) - { - _logger.error("Connection not stopped while setting ML", e); - fail("Unable to change message listener:" + e.getCause()); - } - catch (JMSException e) - { - _logger.error("Error Setting Better ML on consumer1", e); - } - - try - { - _logger.info("Send additional messages"); - TextMessage m = _producerSession.createTextMessage(); - m.setStringProperty("rank", "second"); - for (int msg = 0; msg < MSG_COUNT; msg++) - { - m.setText("Message " + msg); - _producer.send(m); - } - } - catch (JMSException e) - { - _logger.error("Unable to send additional messages", e); - } - - _logger.info("Waiting upto 2 seconds for messages"); - - try - { - _allSecondMessagesSent.await(1000, TimeUnit.MILLISECONDS); - } - catch (InterruptedException e) - { - // do nothing - } - assertEquals("First batch of messages not received correctly", 0, _allFirstMessagesSent010.getCount()); - assertEquals("Second batch of messages not received correctly", 0, _allSecondMessagesSent010.getCount()); - } - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(ResetMessageListenerTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/client/message/NonQpidObjectMessage.java b/java/client/src/test/java/org/apache/qpid/client/message/NonQpidObjectMessage.java deleted file mode 100644 index 60a26c8e62..0000000000 --- a/java/client/src/test/java/org/apache/qpid/client/message/NonQpidObjectMessage.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * - * 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.qpid.client.message; - -import java.io.Serializable; -import java.util.Enumeration; - -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.ObjectMessage; - -public class NonQpidObjectMessage implements ObjectMessage { - - private JMSObjectMessage _realMessage; - private String _contentString; - - /** - * Allows us to construct a JMS message which - * does not inherit from the Qpid message superclasses - * and expand our unit testing of MessageConverter et al - */ - public NonQpidObjectMessage() - { - _realMessage = new JMSObjectMessage(); - } - - public String getJMSMessageID() throws JMSException { - return _realMessage.getJMSMessageID(); - } - - public void setJMSMessageID(String string) throws JMSException { - _realMessage.setJMSMessageID(string); - } - - public long getJMSTimestamp() throws JMSException { - return _realMessage.getJMSTimestamp(); - } - - public void setJMSTimestamp(long l) throws JMSException { - _realMessage.setJMSTimestamp(l); - } - - public byte[] getJMSCorrelationIDAsBytes() throws JMSException { - return _realMessage.getJMSCorrelationIDAsBytes(); - } - - public void setJMSCorrelationIDAsBytes(byte[] bytes) throws JMSException { - _realMessage.setJMSCorrelationIDAsBytes(bytes); - } - - public void setJMSCorrelationID(String string) throws JMSException { - _realMessage.setJMSCorrelationID(string); - } - - public String getJMSCorrelationID() throws JMSException { - return _realMessage.getJMSCorrelationID(); - } - - public Destination getJMSReplyTo() throws JMSException { - return _realMessage.getJMSReplyTo(); - } - - public void setJMSReplyTo(Destination destination) throws JMSException { - _realMessage.setJMSReplyTo(destination); - } - - public Destination getJMSDestination() throws JMSException { - return _realMessage.getJMSDestination(); - } - - public void setJMSDestination(Destination destination) throws JMSException { - _realMessage.setJMSDestination(destination); - } - - public int getJMSDeliveryMode() throws JMSException { - return _realMessage.getJMSDeliveryMode(); - } - - public void setJMSDeliveryMode(int i) throws JMSException { - _realMessage.setJMSDeliveryMode(i); - } - - public boolean getJMSRedelivered() throws JMSException { - return _realMessage.getJMSRedelivered(); - } - - public void setJMSRedelivered(boolean b) throws JMSException { - _realMessage.setJMSRedelivered(b); - } - - public String getJMSType() throws JMSException { - return _realMessage.getJMSType(); - } - - public void setJMSType(String string) throws JMSException { - _realMessage.setJMSType(string); - } - - public long getJMSExpiration() throws JMSException { - return _realMessage.getJMSExpiration(); - } - - public void setJMSExpiration(long l) throws JMSException { - _realMessage.setJMSExpiration(l); - } - - public int getJMSPriority() throws JMSException { - return _realMessage.getJMSPriority(); - } - - public void setJMSPriority(int i) throws JMSException { - _realMessage.setJMSPriority(i); - } - - public void clearProperties() throws JMSException { - _realMessage.clearProperties(); - } - - public boolean propertyExists(String string) throws JMSException { - return _realMessage.propertyExists(string); - } - - public boolean getBooleanProperty(String string) throws JMSException { - return _realMessage.getBooleanProperty(string); - } - - public byte getByteProperty(String string) throws JMSException { - return _realMessage.getByteProperty(string); - } - - public short getShortProperty(String string) throws JMSException { - return _realMessage.getShortProperty(string); - } - - public int getIntProperty(String string) throws JMSException { - return _realMessage.getIntProperty(string); - } - - public long getLongProperty(String string) throws JMSException { - return _realMessage.getLongProperty(string); - } - - public float getFloatProperty(String string) throws JMSException { - return _realMessage.getFloatProperty(string); - } - - public double getDoubleProperty(String string) throws JMSException { - return _realMessage.getDoubleProperty(string); - } - - public String getStringProperty(String string) throws JMSException { - return _realMessage.getStringProperty(string); - } - - public Object getObjectProperty(String string) throws JMSException { - return _realMessage.getObjectProperty(string); - } - - public Enumeration getPropertyNames() throws JMSException { - return _realMessage.getPropertyNames(); - } - - public void setBooleanProperty(String string, boolean b) throws JMSException { - _realMessage.setBooleanProperty(string,b); - } - - public void setByteProperty(String string, byte b) throws JMSException { - _realMessage.setByteProperty(string,b); - } - - public void setShortProperty(String string, short i) throws JMSException { - _realMessage.setShortProperty(string,i); - } - - public void setIntProperty(String string, int i) throws JMSException { - _realMessage.setIntProperty(string,i); - } - - public void setLongProperty(String string, long l) throws JMSException { - _realMessage.setLongProperty(string,l); - } - - public void setFloatProperty(String string, float v) throws JMSException { - _realMessage.setFloatProperty(string,v); - } - - public void setDoubleProperty(String string, double v) throws JMSException { - _realMessage.setDoubleProperty(string,v); - } - - public void setStringProperty(String string, String string1) throws JMSException { - _realMessage.setStringProperty(string,string1); - } - - public void setObjectProperty(String string, Object object) throws JMSException { - _realMessage.setObjectProperty(string,object); - } - - public void acknowledge() throws JMSException { - _realMessage.acknowledge(); - } - - public void clearBody() throws JMSException { - _realMessage.clearBody(); - } - - public void setObject(Serializable serializable) throws JMSException { - if (serializable instanceof String) - { - _contentString = (String)serializable; - } - } - - public Serializable getObject() throws JMSException { - return _contentString; } -} diff --git a/java/client/src/test/java/org/apache/qpid/client/message/TestMessageHelper.java b/java/client/src/test/java/org/apache/qpid/client/message/TestMessageHelper.java index 9b477c19e2..7ee991b63c 100644 --- a/java/client/src/test/java/org/apache/qpid/client/message/TestMessageHelper.java +++ b/java/client/src/test/java/org/apache/qpid/client/message/TestMessageHelper.java @@ -26,21 +26,21 @@ public class TestMessageHelper { public static JMSTextMessage newJMSTextMessage() throws JMSException { - return new JMSTextMessage(); + return new JMSTextMessage(AMQMessageDelegateFactory.FACTORY_0_8); } public static JMSBytesMessage newJMSBytesMessage() throws JMSException { - return new JMSBytesMessage(); + return new JMSBytesMessage(AMQMessageDelegateFactory.FACTORY_0_8); } public static JMSMapMessage newJMSMapMessage() throws JMSException { - return new JMSMapMessage(); + return new JMSMapMessage(AMQMessageDelegateFactory.FACTORY_0_8); } public static JMSStreamMessage newJMSStreamMessage() { - return new JMSStreamMessage(); + return new JMSStreamMessage(AMQMessageDelegateFactory.FACTORY_0_8); } } diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/ack/RecoverTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/ack/RecoverTest.java deleted file mode 100644 index 216bbedef3..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/ack/RecoverTest.java +++ /dev/null @@ -1,331 +0,0 @@ -/* - * 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.qpid.test.unit.ack; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.jms.Session; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.TextMessage; - -import java.util.concurrent.atomic.AtomicInteger; - -public class RecoverTest extends QpidTestCase -{ - private static final Logger _logger = LoggerFactory.getLogger(RecoverTest.class); - - private Exception _error; - private AtomicInteger count; - - protected void setUp() throws Exception - { - super.setUp(); - _error = null; - count = new AtomicInteger(); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - count = null; - } - - public void testRecoverResendsMsgs() throws Exception - { - AMQConnection con = (AMQConnection) getConnection("guest", "guest"); - - Session consumerSession = con.createSession(false, Session.CLIENT_ACKNOWLEDGE); - Queue queue = - new AMQQueue(consumerSession.getDefaultQueueExchangeName(), new AMQShortString("someQ"), - new AMQShortString("someQ"), false, true); - MessageConsumer consumer = consumerSession.createConsumer(queue); - // force synch to ensure the consumer has resulted in a bound queue - // ((AMQSession) consumerSession).declareExchangeSynch(ExchangeDefaults.DIRECT_EXCHANGE_NAME, ExchangeDefaults.DIRECT_EXCHANGE_CLASS); - // This is the default now - - AMQConnection con2 = (AMQConnection) getConnection("guest", "guest"); - Session producerSession = con2.createSession(false, Session.CLIENT_ACKNOWLEDGE); - MessageProducer producer = producerSession.createProducer(queue); - - _logger.info("Sending four messages"); - producer.send(producerSession.createTextMessage("msg1")); - producer.send(producerSession.createTextMessage("msg2")); - producer.send(producerSession.createTextMessage("msg3")); - producer.send(producerSession.createTextMessage("msg4")); - - con2.close(); - - _logger.info("Starting connection"); - con.start(); - TextMessage tm = (TextMessage) consumer.receive(); - tm.acknowledge(); - _logger.info("Received and acknowledged first message"); - consumer.receive(); - consumer.receive(); - consumer.receive(); - _logger.info("Received all four messages. Calling recover with three outstanding messages"); - // no ack for last three messages so when I call recover I expect to get three messages back - consumerSession.recover(); - tm = (TextMessage) consumer.receive(3000); - assertEquals("msg2", tm.getText()); - - tm = (TextMessage) consumer.receive(3000); - assertEquals("msg3", tm.getText()); - - tm = (TextMessage) consumer.receive(3000); - assertEquals("msg4", tm.getText()); - - _logger.info("Received redelivery of three messages. Acknowledging last message"); - tm.acknowledge(); - - _logger.info("Calling acknowledge with no outstanding messages"); - // all acked so no messages to be delivered - consumerSession.recover(); - - tm = (TextMessage) consumer.receiveNoWait(); - assertNull(tm); - _logger.info("No messages redelivered as is expected"); - - con.close(); - } - - public void testRecoverResendsMsgsAckOnEarlier() throws Exception - { - AMQConnection con = (AMQConnection) getConnection("guest", "guest"); - - Session consumerSession = con.createSession(false, Session.CLIENT_ACKNOWLEDGE); - Queue queue = - new AMQQueue(consumerSession.getDefaultQueueExchangeName(), new AMQShortString("someQ"), - new AMQShortString("someQ"), false, true); - MessageConsumer consumer = consumerSession.createConsumer(queue); - // force synch to ensure the consumer has resulted in a bound queue - // ((AMQSession) consumerSession).declareExchangeSynch(ExchangeDefaults.DIRECT_EXCHANGE_NAME, ExchangeDefaults.DIRECT_EXCHANGE_CLASS); - // This is the default now - - AMQConnection con2 = (AMQConnection) getConnection("guest", "guest"); - Session producerSession = con2.createSession(false, Session.CLIENT_ACKNOWLEDGE); - MessageProducer producer = producerSession.createProducer(queue); - - _logger.info("Sending four messages"); - producer.send(producerSession.createTextMessage("msg1")); - producer.send(producerSession.createTextMessage("msg2")); - producer.send(producerSession.createTextMessage("msg3")); - producer.send(producerSession.createTextMessage("msg4")); - - con2.close(); - - _logger.info("Starting connection"); - con.start(); - TextMessage tm = (TextMessage) consumer.receive(); - consumer.receive(); - tm.acknowledge(); - _logger.info("Received 2 messages, acknowledge() first message, should acknowledge both"); - - consumer.receive(); - consumer.receive(); - _logger.info("Received all four messages. Calling recover with two outstanding messages"); - // no ack for last three messages so when I call recover I expect to get three messages back - consumerSession.recover(); - TextMessage tm3 = (TextMessage) consumer.receive(3000); - assertEquals("msg3", tm3.getText()); - - TextMessage tm4 = (TextMessage) consumer.receive(3000); - assertEquals("msg4", tm4.getText()); - - _logger.info("Received redelivery of two messages. calling acknolwedgeThis() first of those message"); - ((org.apache.qpid.jms.Message) tm3).acknowledgeThis(); - - _logger.info("Calling recover"); - // all acked so no messages to be delivered - consumerSession.recover(); - - tm4 = (TextMessage) consumer.receive(3000); - assertEquals("msg4", tm4.getText()); - ((org.apache.qpid.jms.Message) tm4).acknowledgeThis(); - - _logger.info("Calling recover"); - // all acked so no messages to be delivered - consumerSession.recover(); - - tm = (TextMessage) consumer.receiveNoWait(); - assertNull(tm); - _logger.info("No messages redelivered as is expected"); - - con.close(); - } - - public void testAcknowledgePerConsumer() throws Exception - { - AMQConnection con = (AMQConnection) getConnection("guest", "guest"); - - Session consumerSession = con.createSession(false, Session.CLIENT_ACKNOWLEDGE); - Queue queue = - new AMQQueue(consumerSession.getDefaultQueueExchangeName(), new AMQShortString("Q1"), new AMQShortString("Q1"), - false, true); - Queue queue2 = - new AMQQueue(consumerSession.getDefaultQueueExchangeName(), new AMQShortString("Q2"), new AMQShortString("Q2"), - false, true); - MessageConsumer consumer = consumerSession.createConsumer(queue); - MessageConsumer consumer2 = consumerSession.createConsumer(queue2); - - AMQConnection con2 = (AMQConnection) getConnection("guest", "guest"); - Session producerSession = con2.createSession(false, Session.CLIENT_ACKNOWLEDGE); - MessageProducer producer = producerSession.createProducer(queue); - MessageProducer producer2 = producerSession.createProducer(queue2); - - producer.send(producerSession.createTextMessage("msg1")); - producer2.send(producerSession.createTextMessage("msg2")); - - con2.close(); - - _logger.info("Starting connection"); - con.start(); - - TextMessage tm2 = (TextMessage) consumer2.receive(2000); - assertNotNull(tm2); - assertEquals("msg2", tm2.getText()); - - tm2.acknowledge(); - - consumerSession.recover(); - - TextMessage tm1 = (TextMessage) consumer.receive(2000); - assertNotNull(tm1); - assertEquals("msg1", tm1.getText()); - - con.close(); - - } - - public void testRecoverInAutoAckListener() throws Exception - { - AMQConnection con = (AMQConnection) getConnection("guest", "guest"); - - final Session consumerSession = con.createSession(false, Session.AUTO_ACKNOWLEDGE); - Queue queue = - new AMQQueue(consumerSession.getDefaultQueueExchangeName(), new AMQShortString("Q3"), new AMQShortString("Q3"), - false, true); - MessageConsumer consumer = consumerSession.createConsumer(queue); - MessageProducer producer = consumerSession.createProducer(queue); - producer.send(consumerSession.createTextMessage("hello")); - - final Object lock = new Object(); - - consumer.setMessageListener(new MessageListener() - { - - public void onMessage(Message message) - { - try - { - count.incrementAndGet(); - if (count.get() == 1) - { - if (message.getJMSRedelivered()) - { - setError( - new Exception("Message marked as redilvered on what should be first delivery attempt")); - } - - consumerSession.recover(); - } - else if (count.get() == 2) - { - if (!message.getJMSRedelivered()) - { - setError( - new Exception( - "Message not marked as redilvered on what should be second delivery attempt")); - } - } - else - { - System.err.println(message); - fail("Message delivered too many times!: " + count); - } - } - catch (JMSException e) - { - _logger.error("Error recovering session: " + e, e); - setError(e); - } - - synchronized (lock) - { - lock.notify(); - } - } - }); - - con.start(); - - long waitTime = 30000L; - long waitUntilTime = System.currentTimeMillis() + waitTime; - - synchronized (lock) - { - while ((count.get() <= 1) && (waitTime > 0)) - { - lock.wait(waitTime); - if (count.get() <= 1) - { - waitTime = waitUntilTime - System.currentTimeMillis(); - } - } - } - - Thread.sleep(1000); - - if (count.get() != 2) - { - System.err.println("Count != 2 : " + count); - } - - assertTrue(count.get() == 2); - - con.close(); - - if (_error != null) - { - throw _error; - } - } - - private void setError(Exception e) - { - _error = e; - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(RecoverTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/BytesMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/BytesMessageTest.java deleted file mode 100644 index cf09566f30..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/BytesMessageTest.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * 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.qpid.test.unit.basic; - -import junit.framework.Assert; - -import org.apache.mina.common.ByteBuffer; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQDestination; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.message.JMSBytesMessage; -import org.apache.qpid.testutil.VMBrokerSetup; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.BytesMessage; -import javax.jms.Connection; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.MessageNotReadableException; -import javax.jms.MessageNotWriteableException; -import javax.jms.MessageProducer; -import javax.jms.Session; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -public class BytesMessageTest extends QpidTestCase implements MessageListener -{ - private static final Logger _logger = LoggerFactory.getLogger(BytesMessageTest.class); - - private Connection _connection; - private Destination _destination; - private Session _session; - private final List<JMSBytesMessage> received = new ArrayList<JMSBytesMessage>(); - private final List<byte[]> messages = new ArrayList<byte[]>(); - private int _count = 100; - public String _connectionString = "vm://:1"; - - protected void setUp() throws Exception - { - super.setUp(); - init((AMQConnection) getConnection("guest", "guest")); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - void init(AMQConnection connection) throws Exception - { - init(connection, new AMQQueue(connection, randomize("BytesMessageTest"), true)); - } - - void init(AMQConnection connection, AMQDestination destination) throws Exception - { - _connection = connection; - _destination = destination; - _session = connection.createSession(false, AMQSession.NO_ACKNOWLEDGE); - - // Set up a slow consumer. - _session.createConsumer(destination).setMessageListener(this); - connection.start(); - } - - public void test() throws Exception - { - try - { - send(_count); - waitFor(_count); - check(); - _logger.info("Completed without failure"); - } - finally - { - _connection.close(); - } - } - - void send(int count) throws JMSException - { - // create a publisher - MessageProducer producer = _session.createProducer(_destination); - for (int i = 0; i < count; i++) - { - BytesMessage msg = _session.createBytesMessage(); - - try - { - msg.readFloat(); - Assert.fail("Message should not be readable"); - } - catch (MessageNotReadableException mnwe) - { - // normal execution - } - - byte[] data = ("Message " + i).getBytes(); - msg.writeBytes(data); - messages.add(data); - producer.send(msg); - } - } - - void waitFor(int count) throws InterruptedException - { - synchronized (received) - { - while (received.size() < count) - { - received.wait(); - } - } - } - - void check() throws JMSException - { - List<byte[]> actual = new ArrayList<byte[]>(); - for (JMSBytesMessage m : received) - { - ByteBuffer buffer = m.getData(); - byte[] data = new byte[buffer.remaining()]; - buffer.get(data); - actual.add(data); - - // Check Body Write Status - try - { - m.writeBoolean(true); - Assert.fail("Message should not be writeable"); - } - catch (MessageNotWriteableException mnwe) - { - // normal execution - } - - m.clearBody(); - - try - { - m.writeBoolean(true); - } - catch (MessageNotWriteableException mnwe) - { - Assert.fail("Message should be writeable"); - } - - // Check property write status - try - { - m.setStringProperty("test", "test"); - Assert.fail("Message should not be writeable"); - } - catch (MessageNotWriteableException mnwe) - { - // normal execution - } - - m.clearProperties(); - - try - { - m.setStringProperty("test", "test"); - } - catch (MessageNotWriteableException mnwe) - { - Assert.fail("Message should be writeable"); - } - - } - - assertEqual(messages.iterator(), actual.iterator()); - } - - private static void assertEqual(Iterator expected, Iterator actual) - { - List<String> errors = new ArrayList<String>(); - while (expected.hasNext() && actual.hasNext()) - { - try - { - assertEquivalent((byte[]) expected.next(), (byte[]) actual.next()); - } - catch (Exception e) - { - errors.add(e.getMessage()); - } - } - while (expected.hasNext()) - { - errors.add("Expected " + expected.next() + " but no more actual values."); - } - while (actual.hasNext()) - { - errors.add("Found " + actual.next() + " but no more expected values."); - } - - if (!errors.isEmpty()) - { - throw new RuntimeException(errors.toString()); - } - } - - private static void assertEquivalent(byte[] expected, byte[] actual) - { - if (expected.length != actual.length) - { - throw new RuntimeException("Expected length " + expected.length + " got " + actual.length); - } - - for (int i = 0; i < expected.length; i++) - { - if (expected[i] != actual[i]) - { - throw new RuntimeException("Failed on byte " + i + " of " + expected.length); - } - } - } - - public void onMessage(Message message) - { - synchronized (received) - { - received.add((JMSBytesMessage) message); - received.notify(); - } - } - - private static String randomize(String in) - { - return in + System.currentTimeMillis(); - } - - public static void main(String[] argv) throws Exception - { - final String connectionString; - final int count; - if (argv.length == 0) - { - connectionString = "vm://:1"; - count = 100; - } - else - { - connectionString = argv[0]; - count = Integer.parseInt(argv[1]); - } - - System.out.println("connectionString = " + connectionString); - System.out.println("count = " + count); - - BytesMessageTest test = new BytesMessageTest(); - test._connectionString = connectionString; - test._count = count; - test.test(); - } - - public static junit.framework.Test suite() - { - return new VMBrokerSetup(new junit.framework.TestSuite(BytesMessageTest.class)); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableMessageTest.java deleted file mode 100644 index e8d3497bdb..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableMessageTest.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * - * 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.qpid.test.unit.basic; - -import org.apache.mina.common.ByteBuffer; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQDestination; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.message.JMSBytesMessage; -import org.apache.qpid.framing.AMQFrameDecodingException; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.FieldTableFactory; -import org.apache.qpid.testutil.VMBrokerSetup; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.BytesMessage; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -public class FieldTableMessageTest extends QpidTestCase implements MessageListener -{ - private static final Logger _logger = LoggerFactory.getLogger(FieldTableMessageTest.class); - - private AMQConnection _connection; - private AMQDestination _destination; - private AMQSession _session; - private final ArrayList<JMSBytesMessage> received = new ArrayList<JMSBytesMessage>(); - private FieldTable _expected; - private int _count = 10; - public String _connectionString = "vm://:1"; - private CountDownLatch _waitForCompletion; - - protected void setUp() throws Exception - { - super.setUp(); - init( (AMQConnection) getConnection("guest", "guest")); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - private void init(AMQConnection connection) throws Exception - { - init(connection, new AMQQueue(connection, randomize("FieldTableMessageTest"), true)); - } - - private void init(AMQConnection connection, AMQDestination destination) throws Exception - { - _connection = connection; - _destination = destination; - _session = (AMQSession) connection.createSession(false, AMQSession.NO_ACKNOWLEDGE); - - // set up a slow consumer - _session.createConsumer(destination).setMessageListener(this); - connection.start(); - - // _expected = new FieldTableTest().load("FieldTableTest2.properties"); - _expected = load(); - } - - private FieldTable load() throws IOException - { - FieldTable result = FieldTableFactory.newFieldTable(); - result.setLong("one", 1L); - result.setLong("two", 2L); - result.setLong("three", 3L); - result.setLong("four", 4L); - result.setLong("five", 5L); - - return result; - } - - public void test() throws Exception - { - int count = _count; - _waitForCompletion = new CountDownLatch(_count); - send(count); - _waitForCompletion.await(20, TimeUnit.SECONDS); - check(); - _logger.info("Completed without failure"); - _connection.close(); - } - - void send(int count) throws JMSException, IOException - { - // create a publisher - MessageProducer producer = _session.createProducer(_destination); - for (int i = 0; i < count; i++) - { - BytesMessage msg = _session.createBytesMessage(); - msg.writeBytes(_expected.getDataAsBytes()); - producer.send(msg); - } - } - - - void check() throws JMSException, AMQFrameDecodingException - { - for (Object m : received) - { - ByteBuffer buffer = ((JMSBytesMessage) m).getData(); - FieldTable actual = FieldTableFactory.newFieldTable(buffer, buffer.remaining()); - for (String key : _expected.keys()) - { - assertEquals("Values for " + key + " did not match", _expected.getObject(key), actual.getObject(key)); - } - } - } - - public void onMessage(Message message) - { - synchronized (received) - { - received.add((JMSBytesMessage) message); - _waitForCompletion.countDown(); - } - } - - private static String randomize(String in) - { - return in + System.currentTimeMillis(); - } - - public static void main(String[] argv) throws Exception - { - FieldTableMessageTest test = new FieldTableMessageTest(); - test._connectionString = (argv.length == 0) ? "vm://:1" : argv[0]; - test.setUp(); - test._count = (argv.length > 1) ? Integer.parseInt(argv[1]) : 5; - test.test(); - } - - public static junit.framework.Test suite() - { - return new VMBrokerSetup(new junit.framework.TestSuite(FieldTableMessageTest.class)); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/InvalidDestinationTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/InvalidDestinationTest.java deleted file mode 100644 index 1738db7239..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/InvalidDestinationTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * - * 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.qpid.test.unit.basic; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.testutil.QpidTestCase; - -import javax.jms.Session; -import javax.jms.QueueSession; -import javax.jms.Queue; -import javax.jms.QueueSender; -import javax.jms.TextMessage; -import javax.jms.InvalidDestinationException; - -public class InvalidDestinationTest extends QpidTestCase -{ - private AMQConnection _connection; - - protected void setUp() throws Exception - { - super.setUp(); - _connection = (AMQConnection) getConnection("guest", "guest"); - } - - protected void tearDown() throws Exception - { - _connection.close(); - super.tearDown(); - } - - - - public void testInvalidDestination() throws Exception - { - Queue invalidDestination = new AMQQueue("amq.direct","unknownQ"); - AMQQueue validDestination = new AMQQueue("amq.direct","knownQ"); - QueueSession queueSession = _connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); - - // This is the only easy way to create and bind a queue from the API :-( - queueSession.createConsumer(validDestination); - - QueueSender sender = queueSession.createSender(invalidDestination); - TextMessage msg = queueSession.createTextMessage("Hello"); - try - { - sender.send(msg); - fail("Expected InvalidDestinationException"); - } - catch (InvalidDestinationException ex) - { - // pass - } - sender.close(); - - sender = queueSession.createSender(null); - invalidDestination = new AMQQueue("amq.direct","unknownQ"); - - try - { - sender.send(invalidDestination,msg); - fail("Expected InvalidDestinationException"); - } - catch (InvalidDestinationException ex) - { - // pass - } - sender.send(validDestination,msg); - sender.close(); - validDestination = new AMQQueue("amq.direct","knownQ"); - sender = queueSession.createSender(validDestination); - sender.send(msg); - - - - - } - - - public static junit.framework.Test suite() - { - - return new junit.framework.TestSuite(InvalidDestinationTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/LargeMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/LargeMessageTest.java deleted file mode 100644 index 81171fa330..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/LargeMessageTest.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * 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.qpid.test.unit.basic; - - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Session; -import javax.jms.TextMessage; - -public class LargeMessageTest extends QpidTestCase -{ - private static final Logger _logger = LoggerFactory.getLogger(LargeMessageTest.class); - - private Destination _destination; - private AMQSession _session; - private AMQConnection _connection; - - protected void setUp() throws Exception - { - super.setUp(); - try - { - _connection = (AMQConnection) getConnection("guest", "guest"); - init( _connection ); - } - catch (Exception e) - { - fail("Unable to initialilse connection: " + e); - } - } - - protected void tearDown() throws Exception - { - _connection.close(); - super.tearDown(); - } - - private void init(AMQConnection connection) throws Exception - { - Destination destination = new AMQQueue(connection, "LargeMessageTest", true); - init(connection, destination); - } - - private void init(AMQConnection connection, Destination destination) throws Exception - { - _destination = destination; - _session = (AMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - connection.start(); - } - - // Test boundary of 1 packet to 2 packets - public void test64kminus1() - { - checkLargeMessage((64 * 1024) - 1); - } - - public void test64k() - { - checkLargeMessage(64 * 1024); - } - - public void test64kplus1() - { - checkLargeMessage((64 * 1024) + 1); - } - - // Test packet boundary of 3 packtes - public void test128kminus1() - { - checkLargeMessage((128 * 1024) - 1); - } - - public void test128k() - { - checkLargeMessage(128 * 1024); - } - - public void test128kplus1() - { - checkLargeMessage((128 * 1024) + 1); - } - - // Testing larger messages - - public void test256k() - { - checkLargeMessage(256 * 1024); - } - - public void test512k() - { - checkLargeMessage(512 * 1024); - } - - public void test1024k() - { - checkLargeMessage(1024 * 1024); - } - - protected void checkLargeMessage(int messageSize) - { - try - { - MessageConsumer consumer = _session.createConsumer(_destination); - MessageProducer producer = _session.createProducer(_destination); - _logger.info("Testing message of size:" + messageSize); - - String _messageText = buildLargeMessage(messageSize); - - _logger.debug("Message built"); - - producer.send(_session.createTextMessage(_messageText)); - - TextMessage result = (TextMessage) consumer.receive(1000); - - assertNotNull("Null message recevied", result); - assertEquals("Message Size", _messageText.length(), result.getText().length()); - assertEquals("Message content differes", _messageText, result.getText()); - } - catch (JMSException e) - { - e.printStackTrace(); - fail("Excpetion occured:" + e.getCause()); - } - } - - private String buildLargeMessage(int size) - { - StringBuilder builder = new StringBuilder(size); - - char ch = 'a'; - - for (int i = 1; i <= size; i++) - { - builder.append(ch); - - if ((i % 1000) == 0) - { - ch++; - if (ch == ('z' + 1)) - { - ch = 'a'; - } - } - } - - return builder.toString(); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(LargeMessageTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/MapMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/MapMessageTest.java deleted file mode 100644 index 2c4df682f6..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/MapMessageTest.java +++ /dev/null @@ -1,1271 +0,0 @@ -/* - * - * 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.qpid.test.unit.basic; - -import junit.framework.Assert; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.message.JMSMapMessage; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.MapMessage; -import javax.jms.Message; -import javax.jms.MessageFormatException; -import javax.jms.MessageListener; -import javax.jms.MessageNotWriteableException; -import javax.jms.MessageProducer; -import javax.jms.Session; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -public class MapMessageTest extends QpidTestCase implements MessageListener -{ - private static final Logger _logger = LoggerFactory.getLogger(MapMessageTest.class); - - private AMQConnection _connection; - private Destination _destination; - private AMQSession _session; - private final List<JMSMapMessage> received = new ArrayList<JMSMapMessage>(); - - private static final String MESSAGE = "Message "; - private int _count = 100; - public String _connectionString = "vm://:1"; - private byte[] _bytes = { 99, 98, 97, 96, 95 }; - private static final float _smallfloat = 100.0f; - - protected void setUp() throws Exception - { - super.setUp(); - try - { - init((AMQConnection) getConnection("guest", "guest")); - } - catch (Exception e) - { - fail("Unable to initialilse connection: " + e); - } - } - - protected void tearDown() throws Exception - { - _logger.info("Tearing Down unit.basic.MapMessageTest"); - super.tearDown(); - } - - private void init(AMQConnection connection) throws Exception - { - Destination destination = new AMQQueue(connection, randomize("MapMessageTest"), true); - init(connection, destination); - } - - private void init(AMQConnection connection, Destination destination) throws Exception - { - _connection = connection; - _destination = destination; - _session = (AMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - // set up a slow consumer - _session.createConsumer(destination).setMessageListener(this); - connection.start(); - } - - public void test() throws Exception - { - int count = _count; - send(count); - waitFor(count); - check(); - _connection.close(); - } - - void send(int count) throws JMSException - { - // create a publisher - MessageProducer producer = _session.createProducer(_destination); - for (int i = 0; i < count; i++) - { - MapMessage message = _session.createMapMessage(); - - setMapValues(message, i); - - producer.send(message); - } - } - - private void setMapValues(MapMessage message, int i) throws JMSException - { - message.setBoolean("odd", (i / 2) == 0); - message.setByte("byte",Byte.MAX_VALUE); - message.setBytes("bytes", _bytes); - message.setChar("char",'c'); - message.setDouble("double", Double.MAX_VALUE); - message.setFloat("float", Float.MAX_VALUE); - message.setFloat("smallfloat", 100); - message.setInt("messageNumber", i); - message.setInt("int", Integer.MAX_VALUE); - message.setLong("long", Long.MAX_VALUE); - message.setShort("short", Short.MAX_VALUE); - message.setString("message", MESSAGE + i); - - // Test Setting Object Values - message.setObject("object-bool", true); - message.setObject("object-byte", Byte.MAX_VALUE); - message.setObject("object-bytes", _bytes); - message.setObject("object-char", 'c'); - message.setObject("object-double", Double.MAX_VALUE); - message.setObject("object-float", Float.MAX_VALUE); - message.setObject("object-int", Integer.MAX_VALUE); - message.setObject("object-long", Long.MAX_VALUE); - message.setObject("object-short", Short.MAX_VALUE); - - // Set a null String value - message.setString("nullString", null); - // Highlight protocol problem - message.setString("emptyString", ""); - - } - - void waitFor(int count) throws Exception - { - long waitTime = 30000L; - long waitUntilTime = System.currentTimeMillis() + 30000L; - - synchronized (received) - { - while ((received.size() < count) && (waitTime > 0)) - { - if (received.size() < count) - { - received.wait(waitTime); - } - - if (received.size() < count) - { - waitTime = waitUntilTime - System.currentTimeMillis(); - } - } - - if (received.size() < count) - { - throw new Exception("Timed-out. Waiting for " + count + " only got " + received.size()); - } - } - } - - void check() throws JMSException - { - int count = 0; - for (JMSMapMessage m : received) - { - testMapValues(m, count); - - testCorrectExceptions(m); - - testMessageWriteStatus(m); - - testPropertyWriteStatus(m); - - count++; - } - } - - private void testCorrectExceptions(JMSMapMessage m) throws JMSException - { - testBoolean(m); - - testByte(m); - - testBytes(m); - - testChar(m); - - testDouble(m); - - testFloat(m); - - testInt(m); - - testLong(m); - - testShort(m); - - testString(m); - } - - private void testString(JMSMapMessage m) throws JMSException - { - - Assert.assertFalse(m.getBoolean("message")); - - try - { - m.getByte("message"); - fail("Exception Expected."); - } - catch (NumberFormatException nfe) - { - // normal execution - } - - try - { - m.getShort("message"); - fail("Exception Expected."); - } - catch (NumberFormatException nfe) - { - // normal execution - } - - // Try bad reads - try - { - m.getChar("message"); - fail("Exception Expected."); - } - catch (MessageFormatException npe) - { - // normal execution - } - - try - { - m.getInt("message"); - fail("Exception Expected."); - } - catch (NumberFormatException nfe) - { - // normal execution - } - - try - { - m.getLong("message"); - fail("Exception Expected."); - } - catch (NumberFormatException nfe) - { - // normal execution - } - - // Try bad reads - try - { - m.getFloat("message"); - fail("Exception Expected."); - } - catch (NumberFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getDouble("message"); - fail("Exception Expected."); - } - catch (NumberFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getBytes("message"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - Assert.assertEquals(MESSAGE + m.getInt("messageNumber"), m.getString("message")); - } - - private void testShort(JMSMapMessage m) throws JMSException - { - - // Try bad reads - try - { - m.getBoolean("short"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getByte("short"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - Assert.assertEquals(Short.MAX_VALUE, m.getShort("short")); - - // Try bad reads - try - { - m.getChar("short"); - fail("Exception Expected."); - } - catch (MessageFormatException npe) - { - // normal execution - } - - Assert.assertEquals(Short.MAX_VALUE, m.getInt("short")); - - Assert.assertEquals(Short.MAX_VALUE, m.getLong("short")); - - // Try bad reads - try - { - m.getFloat("short"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getDouble("short"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getBytes("short"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - Assert.assertEquals("" + Short.MAX_VALUE, m.getString("short")); - } - - private void testLong(JMSMapMessage m) throws JMSException - { - - // Try bad reads - try - { - m.getBoolean("long"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getByte("long"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getShort("long"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - // Try bad reads - try - { - m.getChar("long"); - fail("Exception Expected."); - } - catch (MessageFormatException npe) - { - // normal execution - } - - try - { - m.getInt("long"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - Assert.assertEquals(Long.MAX_VALUE, m.getLong("long")); - - // Try bad reads - try - { - m.getFloat("long"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getDouble("long"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getBytes("long"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - Assert.assertEquals("" + Long.MAX_VALUE, m.getString("long")); - } - - private void testDouble(JMSMapMessage m) throws JMSException - { - - // Try bad reads - try - { - m.getBoolean("double"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getByte("double"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getShort("double"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - // Try bad reads - try - { - m.getChar("double"); - fail("Exception Expected."); - } - catch (MessageFormatException npe) - { - // normal execution - } - - try - { - m.getInt("double"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getLong("double"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - // Try bad reads - try - { - m.getFloat("double"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - Assert.assertEquals(Double.MAX_VALUE, m.getDouble("double")); - - // Try bad reads - try - { - m.getBytes("double"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - Assert.assertEquals("" + Double.MAX_VALUE, m.getString("double")); - } - - private void testFloat(JMSMapMessage m) throws JMSException - { - - // Try bad reads - try - { - m.getBoolean("float"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getByte("float"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getShort("float"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - // Try bad reads - try - { - m.getChar("float"); - fail("Exception Expected."); - } - catch (MessageFormatException npe) - { - // normal execution - } - - try - { - m.getInt("float"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getLong("float"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - Assert.assertEquals(Float.MAX_VALUE, m.getFloat("float")); - - Assert.assertEquals(_smallfloat, (float) m.getDouble("smallfloat")); - - // Try bad reads - try - { - m.getBytes("float"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - Assert.assertEquals("" + Float.MAX_VALUE, m.getString("float")); - } - - private void testInt(JMSMapMessage m) throws JMSException - { - - // Try bad reads - try - { - m.getBoolean("int"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getByte("int"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getShort("int"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - // Try bad reads - try - { - m.getChar("int"); - fail("Exception Expected."); - } - catch (MessageFormatException npe) - { - // normal execution - } - - Assert.assertEquals(Integer.MAX_VALUE, m.getInt("int")); - - Assert.assertEquals(Integer.MAX_VALUE, (int) m.getLong("int")); - - // Try bad reads - try - { - m.getFloat("int"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getDouble("int"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getBytes("int"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - Assert.assertEquals("" + Integer.MAX_VALUE, m.getString("int")); - } - - private void testChar(JMSMapMessage m) throws JMSException - { - - // Try bad reads - try - { - m.getBoolean("char"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getByte("char"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getShort("char"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - Assert.assertEquals('c', m.getChar("char")); - - try - { - m.getInt("char"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getLong("char"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - // Try bad reads - try - { - m.getFloat("char"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getDouble("char"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getBytes("char"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - Assert.assertEquals("" + 'c', m.getString("char")); - } - - private void testBytes(JMSMapMessage m) throws JMSException - { - // Try bad reads - try - { - m.getBoolean("bytes"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getByte("bytes"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getShort("bytes"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - // Try bad reads - try - { - m.getChar("bytes"); - fail("Exception Expected."); - } - catch (MessageFormatException npe) - { - // normal execution - } - - try - { - m.getInt("bytes"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - try - { - m.getLong("bytes"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - // Try bad reads - try - { - m.getFloat("bytes"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getDouble("bytes"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - assertBytesEqual(_bytes, m.getBytes("bytes")); - - try - { - m.getString("bytes"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - } - - private void testByte(JMSMapMessage m) throws JMSException - { - // Try bad reads - try - { - m.getBoolean("byte"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - Assert.assertEquals(Byte.MAX_VALUE, m.getByte("byte")); - - Assert.assertEquals((short) Byte.MAX_VALUE, m.getShort("byte")); - - // Try bad reads - try - { - m.getChar("byte"); - fail("Exception Expected."); - } - catch (MessageFormatException npe) - { - // normal execution - } - - // Reading a byte as an int is ok - Assert.assertEquals((short) Byte.MAX_VALUE, m.getInt("byte")); - - Assert.assertEquals((short) Byte.MAX_VALUE, m.getLong("byte")); - - // Try bad reads - try - { - m.getFloat("byte"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getDouble("byte"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getBytes("byte"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - Assert.assertEquals("" + Byte.MAX_VALUE, m.getString("byte")); - - } - - private void testBoolean(JMSMapMessage m) throws JMSException - { - - Assert.assertEquals((m.getInt("messageNumber") / 2) == 0, m.getBoolean("odd")); - - // Try bad reads - try - { - m.getByte("odd"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - // Try bad reads - try - { - m.getShort("odd"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getChar("odd"); - fail("Exception Expected."); - } - catch (MessageFormatException npe) - { - // normal execution - } - // Try bad reads - try - { - m.getInt("odd"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getLong("odd"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getFloat("odd"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getDouble("odd"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - // Try bad reads - try - { - m.getBytes("odd"); - fail("Exception Expected."); - } - catch (MessageFormatException nfe) - { - // normal execution - } - - Assert.assertEquals("" + ((m.getInt("messageNumber") / 2) == 0), m.getString("odd")); - } - - private void testPropertyWriteStatus(JMSMapMessage m) throws JMSException - { - // Check property write status - try - { - m.setStringProperty("test", "test"); - Assert.fail("Message should not be writeable"); - } - catch (MessageNotWriteableException mnwe) - { - // normal execution - } - - m.clearProperties(); - - try - { - m.setStringProperty("test", "test"); - } - catch (MessageNotWriteableException mnwe) - { - Assert.fail("Message should be writeable"); - } - } - - private void testMessageWriteStatus(JMSMapMessage m) throws JMSException - { - try - { - m.setInt("testint", 3); - fail("Message should not be writeable"); - } - catch (MessageNotWriteableException mnwe) - { - // normal execution - } - - m.clearBody(); - - try - { - m.setInt("testint", 3); - } - catch (MessageNotWriteableException mnwe) - { - Assert.fail("Message should be writeable"); - } - } - - private void testMapValues(JMSMapMessage m, int count) throws JMSException - { - // Test get<Primiative> - - // Boolean - assertEqual((count / 2) == 0, m.getBoolean("odd")); - assertEqual("" + ((count / 2) == 0), m.getString("odd")); - - // Byte - assertEqual(Byte.MAX_VALUE, m.getByte("byte")); - assertEqual("" + Byte.MAX_VALUE, m.getString("byte")); - - // Bytes - assertBytesEqual(_bytes, m.getBytes("bytes")); - - // Char - assertEqual('c', m.getChar("char")); - - // Double - assertEqual(Double.MAX_VALUE, m.getDouble("double")); - assertEqual("" + Double.MAX_VALUE, m.getString("double")); - - // Float - assertEqual(Float.MAX_VALUE, m.getFloat("float")); - assertEqual(_smallfloat, (float) m.getDouble("smallfloat")); - assertEqual("" + Float.MAX_VALUE, m.getString("float")); - - // Integer - assertEqual(Integer.MAX_VALUE, m.getInt("int")); - assertEqual("" + Integer.MAX_VALUE, m.getString("int")); - assertEqual(count, m.getInt("messageNumber")); - - // long - assertEqual(Long.MAX_VALUE, m.getLong("long")); - assertEqual("" + Long.MAX_VALUE, m.getString("long")); - - // Short - assertEqual(Short.MAX_VALUE, m.getShort("short")); - assertEqual("" + Short.MAX_VALUE, m.getString("short")); - assertEqual((int) Short.MAX_VALUE, m.getInt("short")); - - // String - assertEqual(MESSAGE + count, m.getString("message")); - - // Test getObjects - assertEqual(true, m.getObject("object-bool")); - assertEqual(Byte.MAX_VALUE, m.getObject("object-byte")); - assertBytesEqual(_bytes, (byte[]) m.getObject("object-bytes")); - assertEqual('c', m.getObject("object-char")); - assertEqual(Double.MAX_VALUE, m.getObject("object-double")); - assertEqual(Float.MAX_VALUE, m.getObject("object-float")); - assertEqual(Integer.MAX_VALUE, m.getObject("object-int")); - assertEqual(Long.MAX_VALUE, m.getObject("object-long")); - assertEqual(Short.MAX_VALUE, m.getObject("object-short")); - - // Check Special values - assertTrue(m.getString("nullString") == null); - assertEqual("", m.getString("emptyString")); - } - - private void assertBytesEqual(byte[] expected, byte[] actual) - { - Assert.assertEquals(expected.length, actual.length); - - for (int index = 0; index < expected.length; index++) - { - Assert.assertEquals(expected[index], actual[index]); - } - } - - private static void assertEqual(Iterator expected, Iterator actual) - { - List<String> errors = new ArrayList<String>(); - while (expected.hasNext() && actual.hasNext()) - { - try - { - assertEqual(expected.next(), actual.next()); - } - catch (Exception e) - { - errors.add(e.getMessage()); - } - } - while (expected.hasNext()) - { - errors.add("Expected " + expected.next() + " but no more actual values."); - } - while (actual.hasNext()) - { - errors.add("Found " + actual.next() + " but no more expected values."); - } - - if (!errors.isEmpty()) - { - throw new RuntimeException(errors.toString()); - } - } - - private static void assertEqual(Object expected, Object actual) - { - if (!expected.equals(actual)) - { - throw new RuntimeException("Expected '" + expected + "' found '" + actual + "'"); - } - } - - public void onMessage(Message message) - { - synchronized (received) - { - _logger.info("****************** Recevied Messgage:" + message); - received.add((JMSMapMessage) message); - received.notify(); - } - } - - private static String randomize(String in) - { - return in + System.currentTimeMillis(); - } - - public static void main(String[] argv) throws Exception - { - MapMessageTest test = new MapMessageTest(); - test._connectionString = (argv.length == 0) ? "vm://:1" : argv[0]; - test.setUp(); - if (argv.length > 1) - { - test._count = Integer.parseInt(argv[1]); - } - - test.test(); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(MapMessageTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java deleted file mode 100644 index 4f3fc5501d..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * 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.qpid.test.unit.basic; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQDestination; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.exchange.ExchangeDefaults; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.Session; - -public class MultipleConnectionTest extends QpidTestCase -{ - private static final Logger _logger = LoggerFactory.getLogger(MultipleConnectionTest.class); - - public static final String _defaultBroker = "vm://:1"; - public String _connectionString = _defaultBroker; - - private class Receiver - { - private AMQConnection _connection; - private Session[] _sessions; - private MessageCounter[] _counters; - - Receiver(String broker, AMQDestination dest, int sessions) throws Exception - { - this((AMQConnection) getConnection("guest", "guest"), dest, sessions); - } - - Receiver(AMQConnection connection, AMQDestination dest, int sessions) throws Exception - { - _connection = connection; - _sessions = new AMQSession[sessions]; - _counters = new MessageCounter[sessions]; - for (int i = 0; i < sessions; i++) - { - _sessions[i] = _connection.createSession(false, AMQSession.NO_ACKNOWLEDGE); - _counters[i] = new MessageCounter(_sessions[i].toString()); - _sessions[i].createConsumer(dest).setMessageListener(_counters[i]); - } - - _connection.start(); - } - - void close() throws JMSException - { - _connection.close(); - } - } - - private class Publisher - { - private AMQConnection _connection; - private Session _session; - private MessageProducer _producer; - - Publisher(String broker, AMQDestination dest) throws Exception - { - this((AMQConnection) getConnection("guest", "guest"), dest); - } - - Publisher(AMQConnection connection, AMQDestination dest) throws Exception - { - _connection = connection; - _session = _connection.createSession(false, AMQSession.NO_ACKNOWLEDGE); - _producer = _session.createProducer(dest); - } - - void send(String msg) throws JMSException - { - _producer.send(_session.createTextMessage(msg)); - } - - void close() throws JMSException - { - _connection.close(); - } - } - - private static class MessageCounter implements MessageListener - { - private final String _name; - private int _count; - - MessageCounter(String name) - { - _name = name; - } - - public synchronized void onMessage(Message message) - { - _count++; - notify(); - } - - synchronized boolean waitUntil(int expected, long maxWait) throws InterruptedException - { - long start = System.currentTimeMillis(); - while (expected > _count) - { - long timeLeft = maxWait - timeSince(start); - if (timeLeft < 0) - { - break; - } - - wait(timeLeft); - } - - return expected <= _count; - } - - private long timeSince(long start) - { - return System.currentTimeMillis() - start; - } - - public synchronized String toString() - { - return _name + ": " + _count; - } - } - - protected void setUp() throws Exception - { - super.setUp(); - TransportConnection.createVMBroker(1); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - TransportConnection.killAllVMBrokers(); - } - - private static void waitForCompletion(int expected, long wait, Receiver[] receivers) throws InterruptedException - { - for (int i = 0; i < receivers.length; i++) - { - waitForCompletion(expected, wait, receivers[i]._counters); - } - } - - private static void waitForCompletion(int expected, long wait, MessageCounter[] counters) throws InterruptedException - { - for (int i = 0; i < counters.length; i++) - { - if (!counters[i].waitUntil(expected, wait)) - { - throw new RuntimeException("Expected: " + expected + " got " + counters[i]); - } - } - } - - private static String randomize(String in) - { - return in + System.currentTimeMillis(); - } - - public static void main(String[] argv) throws Exception - { - String broker = (argv.length > 0) ? argv[0] : _defaultBroker; - - MultipleConnectionTest test = new MultipleConnectionTest(); - test._connectionString = broker; - test.test(); - } - - public void test() throws Exception - { - String broker = _connectionString; - int messages = 10; - - AMQTopic topic = new AMQTopic(ExchangeDefaults.TOPIC_EXCHANGE_NAME, "amq.topic"); - - Receiver[] receivers = new Receiver[] { new Receiver(broker, topic, 2), new Receiver(broker, topic, 14) }; - - Publisher publisher = new Publisher(broker, topic); - for (int i = 0; i < messages; i++) - { - publisher.send("Message " + (i + 1)); - } - - try - { - waitForCompletion(messages, 5000, receivers); - _logger.info("All receivers received all expected messages"); - } - finally - { - publisher.close(); - for (int i = 0; i < receivers.length; i++) - { - receivers[i].close(); - } - } - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(MultipleConnectionTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/ObjectMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/ObjectMessageTest.java deleted file mode 100644 index a385c196b2..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/ObjectMessageTest.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * 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.qpid.test.unit.basic; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQDestination; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.message.JMSObjectMessage; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.MessageNotWriteableException; -import javax.jms.MessageProducer; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -public class ObjectMessageTest extends QpidTestCase implements MessageListener -{ - private static final Logger _logger = LoggerFactory.getLogger(ObjectMessageTest.class); - - private AMQConnection _connection; - private AMQDestination _destination; - private AMQSession _session; - private final List<JMSObjectMessage> received = new ArrayList<JMSObjectMessage>(); - private final List<Payload> messages = new ArrayList<Payload>(); - private int _count = 100; - public String _connectionString = "vm://:1"; - - protected void setUp() throws Exception - { - super.setUp(); - try - { - init( (AMQConnection) getConnection("guest", "guest")); - } - catch (Exception e) - { - fail("Uable to initialise: " + e); - } - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - private void init(AMQConnection connection) throws Exception - { - init(connection, new AMQQueue(connection, randomize("ObjectMessageTest"), true)); - } - - private void init(AMQConnection connection, AMQDestination destination) throws Exception - { - _connection = connection; - _destination = destination; - _session = (AMQSession) connection.createSession(false, AMQSession.NO_ACKNOWLEDGE); - - // set up a slow consumer - _session.createConsumer(destination).setMessageListener(this); - connection.start(); - } - - public void test() throws Exception - { - int count = _count; - send(count); - waitFor(count); - check(); - _logger.info("Completed without failure"); - _connection.close(); - } - - void send(int count) throws JMSException - { - // create a publisher - MessageProducer producer = _session.createProducer(_destination); - for (int i = 0; i < count; i++) - { - Payload payload = new Payload("Message " + i); - messages.add(payload); - producer.send(_session.createObjectMessage(payload)); - } - } - - void waitFor(int count) throws InterruptedException - { - synchronized (received) - { - while (received.size() < count) - { - received.wait(); - } - } - } - - void check() throws JMSException - { - List<Object> actual = new ArrayList<Object>(); - for (JMSObjectMessage m : received) - { - actual.add(m.getObject()); - - try - { - m.setObject("Test text"); - Assert.fail("Message should not be writeable"); - } - catch (MessageNotWriteableException mnwe) - { - // normal execution - } - - m.clearBody(); - - try - { - m.setObject("Test text"); - } - catch (MessageNotWriteableException mnwe) - { - Assert.fail("Message should be writeable"); - } - - // Check property write status - try - { - m.setStringProperty("test", "test"); - Assert.fail("Message should not be writeable"); - } - catch (MessageNotWriteableException mnwe) - { - // normal execution - } - - m.clearProperties(); - - try - { - m.setStringProperty("test", "test"); - } - catch (MessageNotWriteableException mnwe) - { - Assert.fail("Message should be writeable"); - } - - } - - assertEqual(messages.iterator(), actual.iterator()); - - } - - private static void assertEqual(Iterator expected, Iterator actual) - { - List<String> errors = new ArrayList<String>(); - while (expected.hasNext() && actual.hasNext()) - { - try - { - assertEqual(expected.next(), actual.next()); - } - catch (Exception e) - { - errors.add(e.getMessage()); - } - } - while (expected.hasNext()) - { - errors.add("Expected " + expected.next() + " but no more actual values."); - } - while (actual.hasNext()) - { - errors.add("Found " + actual.next() + " but no more expected values."); - } - - if (!errors.isEmpty()) - { - throw new RuntimeException(errors.toString()); - } - } - - private static void assertEqual(Object expected, Object actual) - { - if (!expected.equals(actual)) - { - throw new RuntimeException("Expected '" + expected + "' found '" + actual + "'"); - } - } - - public void onMessage(Message message) - { - synchronized (received) - { - received.add((JMSObjectMessage) message); - received.notify(); - } - } - - private static String randomize(String in) - { - return in + System.currentTimeMillis(); - } - - private static class Payload implements Serializable - { - private final String data; - - Payload(String data) - { - this.data = data; - } - - public int hashCode() - { - return data.hashCode(); - } - - public boolean equals(Object o) - { - return (o instanceof Payload) && ((Payload) o).data.equals(data); - } - - public String toString() - { - return "Payload[" + data + "]"; - } - } - - public static void main(String[] argv) throws Exception - { - ObjectMessageTest test = new ObjectMessageTest(); - test._connectionString = (argv.length == 0) ? "vm://:1" : argv[0]; - test.setUp(); - if (argv.length > 1) - { - test._count = Integer.parseInt(argv[1]); - } - - test.test(); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(ObjectMessageTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java deleted file mode 100644 index 0e7bb2208b..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java +++ /dev/null @@ -1,377 +0,0 @@ -/* - * - * 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.qpid.test.unit.basic; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.message.AMQMessage; -import org.apache.qpid.client.message.JMSTextMessage; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; - -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -public class PropertyValueTest extends QpidTestCase implements MessageListener -{ - private static final Logger _logger = LoggerFactory.getLogger(PropertyValueTest.class); - - private int count = 0; - private AMQConnection _connection; - private Destination _destination; - private AMQSession _session; - private final List<JMSTextMessage> received = new ArrayList<JMSTextMessage>(); - private final List<String> messages = new ArrayList<String>(); - private int _count = 1; - public String _connectionString = "vm://:1"; - private static final String USERNAME = "guest"; - - protected void setUp() throws Exception - { - super.setUp(); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - private void init(AMQConnection connection) throws Exception - { - Destination destination = new AMQQueue(connection, randomize("PropertyValueTest"), true); - init(connection, destination); - } - - private void init(AMQConnection connection, Destination destination) throws Exception - { - _connection = connection; - _destination = destination; - _session = (AMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - // set up a slow consumer - _session.createConsumer(destination).setMessageListener(this); - connection.start(); - } - - public void testOnce() - { - runBatch(1); - } - - public void test50() - { - runBatch(50); - } - - private void runBatch(int runSize) - { - try - { - int run = 0; - while (run < runSize) - { - _logger.error("Run Number:" + run++); - try - { - init( (AMQConnection) getConnection("guest", "guest")); - } - catch (Exception e) - { - _logger.error("exception:", e); - fail("Unable to initialilse connection: " + e); - } - - int count = _count; - send(count); - waitFor(count); - check(); - _logger.info("Completed without failure"); - - Thread.sleep(10); - _connection.close(); - - _logger.error("End Run Number:" + (run - 1)); - } - } - catch (Exception e) - { - _logger.error(e.getMessage(), e); - e.printStackTrace(); - } - } - - void send(int count) throws JMSException - { - // create a publisher - MessageProducer producer = _session.createProducer(_destination); - for (int i = 0; i < count; i++) - { - String text = "Message " + i; - messages.add(text); - Message m = _session.createTextMessage(text); - - m.setBooleanProperty("Bool", true); - - m.setByteProperty("Byte", (byte) Byte.MAX_VALUE); - m.setDoubleProperty("Double", (double) Double.MAX_VALUE); - m.setFloatProperty("Float", (float) Float.MAX_VALUE); - m.setIntProperty("Int", (int) Integer.MAX_VALUE); - - m.setJMSCorrelationID("Correlation"); - // fixme the m.setJMSMessage has no effect - producer.setPriority(8); - m.setJMSPriority(3); - - // Queue - Queue q; - - if ((i / 2) == 0) - { - q = _session.createTemporaryQueue(); - } - else - { - q = new AMQQueue(_connection, "TestReply"); - } - - m.setJMSReplyTo(q); - m.setStringProperty("TempQueue", q.toString()); - - _logger.debug("Message:" + m); - - Assert.assertEquals("Check temp queue has been set correctly", m.getJMSReplyTo().toString(), - m.getStringProperty("TempQueue")); - - m.setJMSType("Test"); - m.setLongProperty("UnsignedInt", (long) 4294967295L); - m.setLongProperty("Long", (long) Long.MAX_VALUE); - - m.setShortProperty("Short", (short) Short.MAX_VALUE); - m.setStringProperty("String", "Test"); - - // AMQP Specific values - - // Timestamp - long nano = System.nanoTime(); - m.setStringProperty("time-str", String.valueOf(nano)); - ((AMQMessage) m).setTimestampProperty(new AMQShortString("time"), nano); - - // Decimal - BigDecimal bd = new BigDecimal(Integer.MAX_VALUE); - ((AMQMessage) m).setDecimalProperty(new AMQShortString("decimal"), bd.setScale(Byte.MAX_VALUE)); - - bd = new BigDecimal((long) Integer.MAX_VALUE + 1L); - - try - { - ((AMQMessage) m).setDecimalProperty(new AMQShortString("decimal-bad-value"), bd.setScale(Byte.MAX_VALUE)); - fail("UnsupportedOperationException should be thrown as value can't be correctly transmitted"); - } - catch (UnsupportedOperationException uoe) - { - // normal path. - } - - try - { - ((AMQMessage) m).setDecimalProperty(new AMQShortString("decimal-bad-scale"), - bd.setScale(Byte.MAX_VALUE + 1)); - fail("UnsupportedOperationException should be thrown as scale can't be correctly transmitted"); - } - catch (UnsupportedOperationException uoe) - { - // normal path. - } - - // Void - ((AMQMessage) m).setVoidProperty(new AMQShortString("void")); - - _logger.debug("Sending Msg:" + m); - producer.send(m); - } - } - - void waitFor(int count) throws InterruptedException - { - synchronized (received) - { - while (received.size() < count) - { - received.wait(); - } - } - } - - void check() throws JMSException - { - List<String> actual = new ArrayList<String>(); - for (JMSTextMessage m : received) - { - actual.add(m.getText()); - - // Check Properties - - Assert.assertEquals("Check Boolean properties are correctly transported", true, m.getBooleanProperty("Bool")); - Assert.assertEquals("Check Byte properties are correctly transported", (byte) Byte.MAX_VALUE, - m.getByteProperty("Byte")); - Assert.assertEquals("Check Double properties are correctly transported", (double) Double.MAX_VALUE, - m.getDoubleProperty("Double")); - Assert.assertEquals("Check Float properties are correctly transported", (float) Float.MAX_VALUE, - m.getFloatProperty("Float")); - Assert.assertEquals("Check Int properties are correctly transported", (int) Integer.MAX_VALUE, - m.getIntProperty("Int")); - Assert.assertEquals("Check CorrelationID properties are correctly transported", "Correlation", - m.getJMSCorrelationID()); - Assert.assertEquals("Check Priority properties are correctly transported", 8, m.getJMSPriority()); - - // Queue - Assert.assertEquals("Check ReplyTo properties are correctly transported", m.getStringProperty("TempQueue"), - m.getJMSReplyTo().toString()); - - Assert.assertEquals("Check Type properties are correctly transported", "Test", m.getJMSType()); - - Assert.assertEquals("Check Short properties are correctly transported", (short) Short.MAX_VALUE, - m.getShortProperty("Short")); - Assert.assertEquals("Check UnsignedInt properties are correctly transported", (long) 4294967295L, - m.getLongProperty("UnsignedInt")); - Assert.assertEquals("Check Long properties are correctly transported", (long) Long.MAX_VALUE, - m.getLongProperty("Long")); - Assert.assertEquals("Check String properties are correctly transported", "Test", m.getStringProperty("String")); - - // AMQP Tests Specific values - - Assert.assertEquals("Check Timestamp properties are correctly transported", m.getStringProperty("time-str"), - ((AMQMessage) m).getTimestampProperty(new AMQShortString("time")).toString()); - - // Decimal - BigDecimal bd = new BigDecimal(Integer.MAX_VALUE); - - Assert.assertEquals("Check decimal properties are correctly transported", bd.setScale(Byte.MAX_VALUE), - ((AMQMessage) m).getDecimalProperty(new AMQShortString("decimal"))); - - // Void - ((AMQMessage) m).setVoidProperty(new AMQShortString("void")); - - Assert.assertTrue("Check void properties are correctly transported", - ((AMQMessage) m).getPropertyHeaders().containsKey("void")); - - //JMSXUserID - if (m.getStringProperty("JMSXUserID") != null) - { - Assert.assertEquals("Check 'JMSXUserID' is supported ", USERNAME, - m.getStringProperty("JMSXUserID")); - } - } - - received.clear(); - - assertEqual(messages.iterator(), actual.iterator()); - - messages.clear(); - } - - private static void assertEqual(Iterator expected, Iterator actual) - { - List<String> errors = new ArrayList<String>(); - while (expected.hasNext() && actual.hasNext()) - { - try - { - assertEqual(expected.next(), actual.next()); - } - catch (Exception e) - { - errors.add(e.getMessage()); - } - } - while (expected.hasNext()) - { - errors.add("Expected " + expected.next() + " but no more actual values."); - } - while (actual.hasNext()) - { - errors.add("Found " + actual.next() + " but no more expected values."); - } - - if (!errors.isEmpty()) - { - throw new RuntimeException(errors.toString()); - } - } - - private static void assertEqual(Object expected, Object actual) - { - if (!expected.equals(actual)) - { - throw new RuntimeException("Expected '" + expected + "' found '" + actual + "'"); - } - } - - public void onMessage(Message message) - { - synchronized (received) - { - received.add((JMSTextMessage) message); - received.notify(); - } - } - - private static String randomize(String in) - { - return in + System.currentTimeMillis(); - } - - public static void main(String[] argv) throws Exception - { - PropertyValueTest test = new PropertyValueTest(); - test._connectionString = (argv.length == 0) ? "vm://:1" : argv[0]; - test.setUp(); - if (argv.length > 1) - { - test._count = Integer.parseInt(argv[1]); - } - - test.testOnce(); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(PropertyValueTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/PubSubTwoConnectionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/PubSubTwoConnectionTest.java deleted file mode 100644 index 60c84f451d..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/PubSubTwoConnectionTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * - * 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.qpid.test.unit.basic; - -import javax.jms.Connection; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Session; -import javax.jms.TextMessage; -import javax.jms.Topic; - -import junit.framework.TestCase; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.testutil.QpidTestCase; - -/** - * @author Apache Software Foundation - */ -public class PubSubTwoConnectionTest extends QpidTestCase -{ - protected void setUp() throws Exception - { - super.setUp(); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - /** - * This tests that a consumer is set up synchronously - * @throws Exception - */ - public void testTwoConnections() throws Exception - { - - AMQConnection con1 = (AMQConnection) getConnection("guest", "guest"); - - Topic topic = new AMQTopic(con1, "MyTopic"); - - Session session1 = con1.createSession(false, AMQSession.NO_ACKNOWLEDGE); - MessageProducer producer = session1.createProducer(topic); - - Connection con2 = (AMQConnection) getConnection("guest", "guest") ; - Session session2 = con2.createSession(false, AMQSession.NO_ACKNOWLEDGE); - MessageConsumer consumer = session2.createConsumer(topic); - con2.start(); - producer.send(session1.createTextMessage("Hello")); - TextMessage tm1 = (TextMessage) consumer.receive(2000); - assertNotNull(tm1); - assertEquals("Hello", tm1.getText()); - con1.close(); - con2.close(); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/ReceiveTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/ReceiveTest.java deleted file mode 100644 index 5711d12b9e..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/ReceiveTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * - * 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.qpid.test.unit.basic; - -import javax.jms.MessageConsumer; -import javax.jms.Message; - -import junit.framework.TestCase; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQDestination; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; -import org.apache.qpid.testutil.QpidTestCase; - -public class ReceiveTest extends QpidTestCase -{ - private AMQConnection _connection; - private AMQDestination _destination; - private AMQSession _session; - private MessageConsumer _consumer; - - protected void setUp() throws Exception - { - super.setUp(); - init((AMQConnection) getConnection("guest", "guest")); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - private void init(AMQConnection connection) throws Exception - { - init(connection, new AMQQueue(connection,"ReceiveTest", true)); - } - - private void init(AMQConnection connection, AMQDestination destination) throws Exception - { - _connection = connection; - _destination = destination; - _session = (AMQSession) connection.createSession(true, AMQSession.NO_ACKNOWLEDGE); - _consumer = _session.createConsumer(_destination); - _connection.start(); - } - - public void test() throws Exception - { - Message m = _consumer.receive(5000); - assertNull("should not have received a message", m); - _connection.close(); - } - - - public static junit.framework.Test suite() - { - // TODO: note that this test doesn't use the VMBrokerSetup - // test helper class to create and tear down its - // VMBroker. This is because the main() above seems to - // indicate that it's also used outside of the surefire test - // framework. If it isn't, then this test should also be - // changed to use VMBrokerSetup here. - return new junit.framework.TestSuite(ReceiveTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/SelectorTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/SelectorTest.java deleted file mode 100644 index 987b30ce28..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/SelectorTest.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * - * 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.qpid.test.unit.basic; - -import junit.framework.TestCase; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQDestination; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.BasicMessageProducer; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.testutil.QpidTestCase; -import org.apache.qpid.url.URLSyntaxException; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Connection; -import javax.jms.DeliveryMode; -import javax.jms.InvalidSelectorException; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; - -public class SelectorTest extends QpidTestCase implements MessageListener -{ - private static final Logger _logger = LoggerFactory.getLogger(SelectorTest.class); - - private AMQConnection _connection; - private AMQDestination _destination; - private AMQSession _session; - private int count; - public String _connectionString = "vm://:1"; - private static final String INVALID_SELECTOR = "Cost LIKE 5"; - - protected void setUp() throws Exception - { - super.setUp(); - init((AMQConnection) getConnection("guest", "guest")); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - private void init(AMQConnection connection) throws JMSException - { - init(connection, new AMQQueue(connection, randomize("SessionStartTest"), true)); - } - - private void init(AMQConnection connection, AMQDestination destination) throws JMSException - { - _connection = connection; - _destination = destination; - connection.start(); - - String selector = null; - selector = "Cost = 2 AND \"property-with-hyphen\" = 'wibble'"; - // selector = "JMSType = Special AND Cost = 2 AND AMQMessageID > 0 AND JMSDeliveryMode=" + DeliveryMode.NON_PERSISTENT; - - _session = (AMQSession) connection.createSession(false, AMQSession.NO_ACKNOWLEDGE); - // _session.createConsumer(destination).setMessageListener(this); - _session.createConsumer(destination, selector).setMessageListener(this); - } - - public synchronized void test() throws Exception - { - try - { - - init((AMQConnection) getConnection("guest", "guest", randomize("Client"))); - - Message msg = _session.createTextMessage("Message"); - msg.setJMSPriority(1); - msg.setIntProperty("Cost", 2); - msg.setStringProperty("property-with-hyphen", "wibble"); - msg.setJMSType("Special"); - - _logger.info("Sending Message:" + msg); - - ((BasicMessageProducer) _session.createProducer(_destination)).send(msg, DeliveryMode.NON_PERSISTENT); - _logger.info("Message sent, waiting for response..."); - wait(1000); - - if (count > 0) - { - _logger.info("Got message"); - } - - if (count == 0) - { - fail("Did not get message!"); - // throw new RuntimeException("Did not get message!"); - } - } - catch (JMSException e) - { - _logger.debug("JMS:" + e.getClass().getSimpleName() + ":" + e.getMessage()); - if (!(e instanceof InvalidSelectorException)) - { - fail("Wrong exception:" + e.getMessage()); - } - else - { - System.out.println("SUCCESS!!"); - } - } - catch (InterruptedException e) - { - _logger.debug("IE :" + e.getClass().getSimpleName() + ":" + e.getMessage()); - } - catch (URLSyntaxException e) - { - _logger.debug("URL:" + e.getClass().getSimpleName() + ":" + e.getMessage()); - fail("Wrong exception"); - } - catch (AMQException e) - { - _logger.debug("AMQ:" + e.getClass().getSimpleName() + ":" + e.getMessage()); - fail("Wrong exception"); - } - - finally - { - if (_session != null) - { - _session.close(); - } - if (_connection != null) - { - _connection.close(); - } - } - } - - - public void testInvalidSelectors() throws Exception - { - Connection connection = null; - - try - { - connection = getConnection("guest", "guest", randomize("Client")); - _session = (AMQSession) connection.createSession(false, AMQSession.NO_ACKNOWLEDGE); - } - catch (JMSException e) - { - fail(e.getMessage()); - } - catch (AMQException e) - { - fail(e.getMessage()); - } - catch (URLSyntaxException e) - { - fail("Error:" + e.getMessage()); - } - - //Try Creating a Browser - try - { - _session.createBrowser(_session.createQueue("Ping"), INVALID_SELECTOR); - } - catch (JMSException e) - { - _logger.debug("JMS:" + e.getClass().getSimpleName() + ":" + e.getMessage()); - if (!(e instanceof InvalidSelectorException)) - { - fail("Wrong exception:" + e.getMessage()); - } - else - { - _logger.debug("SUCCESS!!"); - } - } - - //Try Creating a Consumer - try - { - _session.createConsumer(_session.createQueue("Ping"), INVALID_SELECTOR); - } - catch (JMSException e) - { - _logger.debug("JMS:" + e.getClass().getSimpleName() + ":" + e.getMessage()); - if (!(e instanceof InvalidSelectorException)) - { - fail("Wrong exception:" + e.getMessage()); - } - else - { - _logger.debug("SUCCESS!!"); - } - } - - //Try Creating a Receiever - try - { - _session.createReceiver(_session.createQueue("Ping"), INVALID_SELECTOR); - } - catch (JMSException e) - { - _logger.debug("JMS:" + e.getClass().getSimpleName() + ":" + e.getMessage()); - if (!(e instanceof InvalidSelectorException)) - { - fail("Wrong exception:" + e.getMessage()); - } - else - { - _logger.debug("SUCCESS!!"); - } - } - - finally - { - if (_session != null) - { - try - { - _session.close(); - } - catch (JMSException e) - { - fail("Error cleaning up:" + e.getMessage()); - } - } - if (_connection != null) - { - try - { - _connection.close(); - } - catch (JMSException e) - { - fail("Error cleaning up:" + e.getMessage()); - } - } - } - } - - public synchronized void onMessage(Message message) - { - count++; - _logger.info("Got Message:" + message); - notify(); - } - - private static String randomize(String in) - { - return in + System.currentTimeMillis(); - } - - public static void main(String[] argv) throws Exception - { - SelectorTest test = new SelectorTest(); - test._connectionString = (argv.length == 0) ? "localhost:3000" : argv[0]; - - try - { - while (true) - { - if (test._connectionString.contains("vm://:1")) - { - test.setUp(); - } - test.test(); - - if (test._connectionString.contains("vm://:1")) - { - test.tearDown(); - } - } - } - catch (Exception e) - { - System.err.println(e.getMessage()); - e.printStackTrace(); - } - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(SelectorTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/SessionStartTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/SessionStartTest.java deleted file mode 100644 index 7864feb069..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/SessionStartTest.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * - * 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.qpid.test.unit.basic; - -import junit.framework.TestCase; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQDestination; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.testutil.VMBrokerSetup; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; - -public class SessionStartTest extends QpidTestCase implements MessageListener -{ - private static final Logger _logger = LoggerFactory.getLogger(SessionStartTest.class); - - private AMQConnection _connection; - private AMQDestination _destination; - private AMQSession _session; - private int count; - public String _connectionString = "vm://:1"; - - protected void setUp() throws Exception - { - super.setUp(); - init((AMQConnection) getConnection("guest", "guest")); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - private void init(AMQConnection connection) throws Exception - { - init(connection, - new AMQQueue(connection.getDefaultQueueExchangeName(), new AMQShortString(randomize("SessionStartTest")), true)); - } - - private void init(AMQConnection connection, AMQDestination destination) throws Exception - { - _connection = connection; - _destination = destination; - connection.start(); - - _session = (AMQSession) connection.createSession(false, AMQSession.NO_ACKNOWLEDGE); - _session.createConsumer(destination).setMessageListener(this); - } - - public synchronized void test() throws JMSException, InterruptedException - { - try - { - _session.createProducer(_destination).send(_session.createTextMessage("Message")); - _logger.info("Message sent, waiting for response..."); - wait(1000); - if (count > 0) - { - _logger.info("Got message"); - } - else - { - throw new RuntimeException("Did not get message!"); - } - } - finally - { - _session.close(); - _connection.close(); - } - } - - public synchronized void onMessage(Message message) - { - count++; - notify(); - } - - private static String randomize(String in) - { - return in + System.currentTimeMillis(); - } - - public static void main(String[] argv) throws Exception - { - SessionStartTest test = new SessionStartTest(); - test._connectionString = (argv.length == 0) ? "localhost:5672" : argv[0]; - test.setUp(); - test.test(); - } - - public static junit.framework.Test suite() - { - return new VMBrokerSetup(new junit.framework.TestSuite(SessionStartTest.class)); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/TextMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/TextMessageTest.java deleted file mode 100644 index 1453e1b014..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/TextMessageTest.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * - * 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.qpid.test.unit.basic; - -import junit.framework.Assert; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.message.JMSTextMessage; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.MessageNotWriteableException; -import javax.jms.MessageProducer; -import javax.jms.Session; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -public class TextMessageTest extends QpidTestCase implements MessageListener -{ - private static final Logger _logger = LoggerFactory.getLogger(TextMessageTest.class); - - private AMQConnection _connection; - private Destination _destination; - private AMQSession _session; - private final List<JMSTextMessage> received = new ArrayList<JMSTextMessage>(); - private final List<String> messages = new ArrayList<String>(); - private int _count = 100; - public String _connectionString = "vm://:1"; - private CountDownLatch _waitForCompletion; - - protected void setUp() throws Exception - { - super.setUp(); - try - { - init((AMQConnection) getConnection("guest", "guest")); - } - catch (Exception e) - { - fail("Unable to initialilse connection: " + e); - } - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - private void init(AMQConnection connection) throws Exception - { - Destination destination = - new AMQQueue(connection.getDefaultQueueExchangeName(), new AMQShortString(randomize("TextMessageTest")), true); - init(connection, destination); - } - - private void init(AMQConnection connection, Destination destination) throws Exception - { - _connection = connection; - _destination = destination; - _session = (AMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - // set up a slow consumer - try - { - _session.createConsumer(destination).setMessageListener(this); - } - catch (Throwable e) - { - e.printStackTrace(); - } - connection.start(); - } - - public void test() throws Exception - { - int count = _count; - _waitForCompletion = new CountDownLatch(_count); - send(count); - _waitForCompletion.await(20, TimeUnit.SECONDS); - check(); - _logger.info("Completed without failure"); - _connection.close(); - } - - void send(int count) throws JMSException - { - // create a publisher - MessageProducer producer = _session.createProducer(_destination); - for (int i = 0; i < count; i++) - { - String text = "Message " + i; - messages.add(text); - Message m = _session.createTextMessage(text); - //m.setStringProperty("String", "hello"); - - _logger.info("Sending Msg:" + m); - producer.send(m); - } - _logger.info("sent " + count + " mesages"); - } - - - void check() throws JMSException - { - List<String> actual = new ArrayList<String>(); - for (JMSTextMessage m : received) - { - actual.add(m.getText()); - - // Check body write status - try - { - m.setText("Test text"); - Assert.fail("Message should not be writeable"); - } - catch (MessageNotWriteableException mnwe) - { - // normal execution - } - - m.clearBody(); - - try - { - m.setText("Test text"); - } - catch (MessageNotWriteableException mnwe) - { - Assert.fail("Message should be writeable"); - } - - // Check property write status - try - { - m.setStringProperty("test", "test"); - Assert.fail("Message should not be writeable"); - } - catch (MessageNotWriteableException mnwe) - { - // normal execution - } - - m.clearProperties(); - - try - { - m.setStringProperty("test", "test"); - } - catch (MessageNotWriteableException mnwe) - { - Assert.fail("Message should be writeable"); - } - - } - - assertEqual(messages.iterator(), actual.iterator()); - } - - private static void assertEqual(Iterator expected, Iterator actual) - { - List<String> errors = new ArrayList<String>(); - while (expected.hasNext() && actual.hasNext()) - { - try - { - assertEqual(expected.next(), actual.next()); - } - catch (Exception e) - { - errors.add(e.getMessage()); - } - } - while (expected.hasNext()) - { - errors.add("Expected " + expected.next() + " but no more actual values."); - } - while (actual.hasNext()) - { - errors.add("Found " + actual.next() + " but no more expected values."); - } - - if (!errors.isEmpty()) - { - throw new RuntimeException(errors.toString()); - } - } - - private static void assertEqual(Object expected, Object actual) - { - if (!expected.equals(actual)) - { - throw new RuntimeException("Expected '" + expected + "' found '" + actual + "'"); - } - } - - public void onMessage(Message message) - { - synchronized (received) - { - _logger.info("===== received one message"); - received.add((JMSTextMessage) message); - _waitForCompletion.countDown(); - } - } - - private static String randomize(String in) - { - return in + System.currentTimeMillis(); - } - - - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(TextMessageTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/close/CloseTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/close/CloseTest.java deleted file mode 100644 index 6f1ddebb0c..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/close/CloseTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.qpid.test.unit.basic.close; -import org.apache.qpid.AMQException; -import org.apache.qpid.testutil.QpidTestCase; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.url.AMQBindingURL; -import org.apache.qpid.url.URLSyntaxException; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.JMSException; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Session; - -public class CloseTest extends QpidTestCase -{ - private static final Logger _logger = LoggerFactory.getLogger(CloseTest.class); - - private static final String BROKER = "vm://:1"; - - protected void setUp() throws Exception - { - super.setUp(); - } - - protected void tearDown() throws Exception - { - super.setUp(); - } - - public void testCloseQueueReceiver() throws Exception - { - AMQConnection connection = (AMQConnection) getConnection("guest", "guest"); - - Session session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); - - AMQQueue queue = new AMQQueue(new AMQBindingURL("test-queue")); - MessageConsumer consumer = session.createConsumer(queue); - - MessageProducer producer_not_used_but_created_for_testing = session.createProducer(queue); - - connection.start(); - - _logger.info("About to close consumer"); - - consumer.close(); - - _logger.info("Closed Consumer"); - connection.close(); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java deleted file mode 100644 index 28782229a1..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * - * 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.qpid.test.unit.client; - -import javax.jms.JMSException; -import javax.jms.QueueSession; -import javax.jms.TopicSession; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.testutil.QpidTestCase; - -public class AMQConnectionTest extends QpidTestCase -{ - private static AMQConnection _connection; - private static AMQTopic _topic; - private static AMQQueue _queue; - private static QueueSession _queueSession; - private static TopicSession _topicSession; - - protected void setUp() throws Exception - { - super.setUp(); - _connection = (AMQConnection) getConnection("guest", "guest"); - _topic = new AMQTopic(_connection.getDefaultTopicExchangeName(), new AMQShortString("mytopic")); - _queue = new AMQQueue(_connection.getDefaultQueueExchangeName(), new AMQShortString("myqueue")); - } - - protected void tearDown() throws Exception - { - _connection.close(); - super.tearDown(); - } - - /** - * Simple tests to check we can create TopicSession and QueueSession ok - * And that they throw exceptions where appropriate as per JMS spec - */ - - public void testCreateQueueSession() throws JMSException - { - _queueSession = _connection.createQueueSession(false, AMQSession.NO_ACKNOWLEDGE); - } - - public void testCreateTopicSession() throws JMSException - { - _topicSession = _connection.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); - } - - public void testTopicSessionCreateBrowser() throws JMSException - { - try - { - _topicSession.createBrowser(_queue); - fail("expected exception did not occur"); - } - catch (javax.jms.IllegalStateException s) - { - // ok - } - catch (Exception e) - { - fail("expected javax.jms.IllegalStateException, got " + e); - } - } - - public void testTopicSessionCreateQueue() throws JMSException - { - try - { - _topicSession.createQueue("abc"); - fail("expected exception did not occur"); - } - catch (javax.jms.IllegalStateException s) - { - // ok - } - catch (Exception e) - { - fail("expected javax.jms.IllegalStateException, got " + e); - } - } - - public void testTopicSessionCreateTemporaryQueue() throws JMSException - { - try - { - _topicSession.createTemporaryQueue(); - fail("expected exception did not occur"); - } - catch (javax.jms.IllegalStateException s) - { - // ok - } - catch (Exception e) - { - fail("expected javax.jms.IllegalStateException, got " + e); - } - } - - public void testQueueSessionCreateTemporaryTopic() throws JMSException - { - try - { - _queueSession.createTemporaryTopic(); - fail("expected exception did not occur"); - } - catch (javax.jms.IllegalStateException s) - { - // ok - } - catch (Exception e) - { - fail("expected javax.jms.IllegalStateException, got " + e); - } - } - - public void testQueueSessionCreateTopic() throws JMSException - { - try - { - _queueSession.createTopic("abc"); - fail("expected exception did not occur"); - } - catch (javax.jms.IllegalStateException s) - { - // ok - } - catch (Exception e) - { - fail("expected javax.jms.IllegalStateException, got " + e); - } - } - - public void testQueueSessionDurableSubscriber() throws JMSException - { - try - { - _queueSession.createDurableSubscriber(_topic, "abc"); - fail("expected exception did not occur"); - } - catch (javax.jms.IllegalStateException s) - { - // ok - } - catch (Exception e) - { - fail("expected javax.jms.IllegalStateException, got " + e); - } - } - - public void testQueueSessionUnsubscribe() throws JMSException - { - try - { - _queueSession.unsubscribe("abc"); - fail("expected exception did not occur"); - } - catch (javax.jms.IllegalStateException s) - { - // ok - } - catch (Exception e) - { - fail("expected javax.jms.IllegalStateException, got " + e); - } - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(AMQConnectionTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/AMQSessionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/AMQSessionTest.java deleted file mode 100644 index 965c22af4a..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/AMQSessionTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * - * 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.qpid.test.unit.client; - -import javax.jms.JMSException; -import javax.jms.QueueReceiver; -import javax.jms.TopicSubscriber; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.testutil.VMBrokerSetup; -import org.apache.qpid.testutil.QpidTestCase; - -/** - * Tests for QueueReceiver and TopicSubscriber creation methods on AMQSession - */ -public class AMQSessionTest extends QpidTestCase -{ - - private static AMQSession _session; - private static AMQTopic _topic; - private static AMQQueue _queue; - private static AMQConnection _connection; - - protected void setUp() throws Exception - { - super.setUp(); - _connection = (AMQConnection) getConnection("guest", "guest"); - _topic = new AMQTopic(_connection,"mytopic"); - _queue = new AMQQueue(_connection,"myqueue"); - _session = (AMQSession) _connection.createSession(false, AMQSession.NO_ACKNOWLEDGE); - } - - protected void tearDown() throws Exception - { - try - { - _connection.close(); - } - catch (JMSException e) - { - //just close - } - super.tearDown(); - } - - public void testCreateSubscriber() throws JMSException - { - TopicSubscriber subscriber = _session.createSubscriber(_topic); - assertEquals("Topic names should match from TopicSubscriber", _topic.getTopicName(), subscriber.getTopic().getTopicName()); - - subscriber = _session.createSubscriber(_topic, "abc", false); - assertEquals("Topic names should match from TopicSubscriber with selector", _topic.getTopicName(), subscriber.getTopic().getTopicName()); - } - - public void testCreateDurableSubscriber() throws JMSException - { - TopicSubscriber subscriber = _session.createDurableSubscriber(_topic, "mysubname"); - assertEquals("Topic names should match from durable TopicSubscriber", _topic.getTopicName(), subscriber.getTopic().getTopicName()); - - subscriber = _session.createDurableSubscriber(_topic, "mysubname2", "abc", false); - assertEquals("Topic names should match from durable TopicSubscriber with selector", _topic.getTopicName(), subscriber.getTopic().getTopicName()); - } - - public void testCreateQueueReceiver() throws JMSException - { - QueueReceiver receiver = _session.createQueueReceiver(_queue); - assertEquals("Queue names should match from QueueReceiver", _queue.getQueueName(), receiver.getQueue().getQueueName()); - - receiver = _session.createQueueReceiver(_queue, "abc"); - assertEquals("Queue names should match from QueueReceiver with selector", _queue.getQueueName(), receiver.getQueue().getQueueName()); - } - - public void testCreateReceiver() throws JMSException - { - QueueReceiver receiver = _session.createReceiver(_queue); - assertEquals("Queue names should match from QueueReceiver", _queue.getQueueName(), receiver.getQueue().getQueueName()); - - receiver = _session.createReceiver(_queue, "abc"); - assertEquals("Queue names should match from QueueReceiver with selector", _queue.getQueueName(), receiver.getQueue().getQueueName()); - } - - public static void stopVmBrokers() - { - _queue = null; - _topic = null; - _session = null; - } - - public static junit.framework.Test suite() - { - return new VMBrokerSetup(new junit.framework.TestSuite(AMQSessionTest.class)); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseMethodHandlerNoCloseOk.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseMethodHandlerNoCloseOk.java index b6776a1a44..66f220643c 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseMethodHandlerNoCloseOk.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseMethodHandlerNoCloseOk.java @@ -27,12 +27,10 @@ import org.apache.qpid.AMQInvalidRoutingKeyException; import org.apache.qpid.client.AMQNoConsumersException; import org.apache.qpid.client.AMQNoRouteException; import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ChannelCloseBody; import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,12 +46,10 @@ public class ChannelCloseMethodHandlerNoCloseOk implements StateAwareMethodListe return _handler; } - public void methodReceived(AMQStateManager stateManager, ChannelCloseBody method, int channelId) + public void methodReceived(AMQProtocolSession session, ChannelCloseBody method, int channelId) throws AMQException { _logger.debug("ChannelClose method received"); - final AMQProtocolSession session = stateManager.getProtocolSession(); - AMQConstant errorCode = AMQConstant.getConstant(method.getReplyCode()); AMQShortString reason = method.getReplyText(); diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java deleted file mode 100644 index 74c0098d72..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * - * 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.qpid.test.unit.client.channelclose; - -import junit.textui.TestRunner; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Destination; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.Session; -import javax.jms.TextMessage; - -import java.util.ArrayList; -import java.util.List; - -/** - * Due to bizarre exception handling all sessions are closed if you get - * a channel close request and no exception listener is registered. - * <p/> - * JIRA issue IBTBLZ-10. - * <p/> - * Simulate by: - * <p/> - * 0. Create two sessions with no exception listener. - * 1. Publish message to queue/topic that does not exist (wrong routing key). - * 2. This will cause a channel close. - * 3. Since client does not have an exception listener, currently all sessions are - * closed. - */ -public class ChannelCloseOkTest extends QpidTestCase -{ - private AMQConnection _connection; - private Destination _destination1; - private Destination _destination2; - private Session _session1; - private Session _session2; - private final List<Message> _received1 = new ArrayList<Message>(); - private final List<Message> _received2 = new ArrayList<Message>(); - - private static final Logger _log = LoggerFactory.getLogger(ChannelCloseOkTest.class); - public String _connectionString = "vm://:1"; - - protected void setUp() throws Exception - { - super.setUp(); - - TransportConnection.createVMBroker(1); - _connection = (AMQConnection) getConnection("guest", "guest"); - - _destination1 = new AMQQueue(_connection, "q1", true); - _destination2 = new AMQQueue(_connection, "q2", true); - _session1 = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - _session1.createConsumer(_destination1).setMessageListener(new MessageListener() - { - public void onMessage(Message message) - { - _log.debug("consumer 1 got message [" + getTextMessage(message) + "]"); - synchronized (_received1) - { - _received1.add(message); - _received1.notify(); - } - } - }); - _session2 = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - _session2.createConsumer(_destination2).setMessageListener(new MessageListener() - { - public void onMessage(Message message) - { - _log.debug("consumer 2 got message [" + getTextMessage(message) + "]"); - synchronized (_received2) - { - _received2.add(message); - _received2.notify(); - } - } - }); - - _connection.start(); - } - - private String getTextMessage(Message message) - { - TextMessage tm = (TextMessage) message; - try - { - return tm.getText(); - } - catch (JMSException e) - { - return "oops " + e; - } - } - - protected void tearDown() throws Exception - { - closeConnection(); - super.tearDown(); - } - - public void closeConnection() throws JMSException - { - if (_connection != null) - { - _log.info(">>>>>>>>>>>>>>.. closing"); - _connection.close(); - } - } - - public void testWithoutExceptionListener() throws Exception - { - doTest(); - } - - public void testWithExceptionListener() throws Exception - { - _connection.setExceptionListener(new ExceptionListener() - { - public void onException(JMSException jmsException) - { - _log.warn("onException - " + jmsException.getMessage()); - } - }); - - doTest(); - } - - public void doTest() throws Exception - { - // Check both sessions are ok. - sendAndWait(_session1, _destination1, "first", _received1, 1); - sendAndWait(_session2, _destination2, "second", _received2, 1); - assertEquals(1, _received1.size()); - assertEquals(1, _received2.size()); - - // Now send message to incorrect destination on session 1. - Destination destination = new AMQQueue(_connection, "incorrect"); - send(_session1, destination, "third"); // no point waiting as message will never be received. - - // Ensure both sessions are still ok. - // Send a bunch of messages as this give time for the sessions to be erroneously closed. - final int num = 300; - for (int i = 0; i < num; ++i) - { - send(_session1, _destination1, "" + i); - send(_session2, _destination2, "" + i); - } - - waitFor(_received1, num + 1); - waitFor(_received2, num + 1); - - // Note that the third message is never received as it is sent to an incorrect destination. - assertEquals(num + 1, _received1.size()); - assertEquals(num + 1, _received2.size()); - } - - private void sendAndWait(Session session, Destination destination, String message, List<Message> received, int count) - throws JMSException, InterruptedException - { - send(session, destination, message); - waitFor(received, count); - } - - private void send(Session session, Destination destination, String message) throws JMSException - { - _log.debug("sending message " + message); - MessageProducer producer1 = session.createProducer(destination); - producer1.send(session.createTextMessage(message)); - } - - private void waitFor(List<Message> received, int count) throws InterruptedException - { - long timeout = 20000; - - synchronized (received) - { - long start = System.currentTimeMillis(); - while (received.size() < count) - { - if (System.currentTimeMillis() - start > timeout) - { - fail("timeout expired waiting for messages"); - } - try - { - received.wait(timeout); - } - catch (InterruptedException e) - { - _log.info("Interrupted: " + e); - throw e; - } - - } - } - } - - private static String randomize(String in) - { - return in + System.currentTimeMillis(); - } - - public static void main(String[] args) - { - TestRunner.run(ChannelCloseOkTest.class); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(ChannelCloseOkTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java deleted file mode 100644 index 45a9ca1dd6..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java +++ /dev/null @@ -1,450 +0,0 @@ -/* - * 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.qpid.test.unit.client.channelclose; - -import junit.framework.TestCase; - -import org.apache.qpid.AMQException; -import org.apache.qpid.AMQTimeoutException; -import org.apache.qpid.testutil.QpidTestCase; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.handler.ClientMethodDispatcherImpl; -import org.apache.qpid.client.failover.FailoverException; -import org.apache.qpid.client.protocol.AMQProtocolHandler; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.framing.*; -import org.apache.qpid.jms.ConnectionListener; -import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.url.URLSyntaxException; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Connection; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.TextMessage; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - -public class ChannelCloseTest extends QpidTestCase implements ExceptionListener, ConnectionListener -{ - private static final Logger _logger = LoggerFactory.getLogger(ChannelCloseTest.class); - - Connection _connection; - private String _brokerlist = "vm://:1"; - private Session _session; - private static final long SYNC_TIMEOUT = 500; - private int TEST = 0; - - protected void setUp() throws Exception - { - super.setUp(); - TransportConnection.createVMBroker(1); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - TransportConnection.killAllVMBrokers(); - } - - /* - close channel, use chanel with same id ensure error. - */ - public void testReusingChannelAfterFullClosure() throws Exception - { - // this is testing an 0.8 conneciton - if(isBroker08()) - { - _connection=newConnection(); - - // Create Producer - try - { - _connection.start(); - - createChannelAndTest(1); - - // Cause it to close - try - { - _logger.info("Testing invalid exchange"); - declareExchange(1, "", "name_that_will_lookup_to_null", false); - fail("Exchange name is empty so this should fail "); - } - catch (AMQException e) - { - assertEquals("Exchange should not be found", AMQConstant.NOT_FOUND, e.getErrorCode()); - } - - // Check that - try - { - _logger.info("Testing valid exchange should fail"); - declareExchange(1, "topic", "amq.topic", false); - fail("This should not succeed as the channel should be closed "); - } - catch (AMQException e) - { - if (_logger.isInfoEnabled()) - { - _logger.info("Exception occured was:" + e.getErrorCode()); - } - - assertEquals("Connection should be closed", AMQConstant.CHANNEL_ERROR, e.getErrorCode()); - - _connection=newConnection(); - } - - checkSendingMessage(); - - _session.close(); - _connection.close(); - - } - catch (JMSException e) - { - e.printStackTrace(); - fail(e.getMessage()); - } - } - } - - /* - close channel and send guff then send ok no errors - REMOVE TEST - The behaviour after server has sent close is undefined. - the server should be free to fail as it may wish to reclaim its resources - immediately after close. - */ - /*public void testSendingMethodsAfterClose() throws Exception - { - // this is testing an 0.8 connection - if(isBroker08()) - { - try - { - _connection=new AMQConnection("amqp://guest:guest@CCTTest/test?brokerlist='" + _brokerlist + "'"); - - ((AMQConnection) _connection).setConnectionListener(this); - - _connection.setExceptionListener(this); - - // Change the StateManager for one that doesn't respond with Close-OKs - AMQStateManager oldStateManager=((AMQConnection) _connection).getProtocolHandler().getStateManager(); - - _session=_connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); - - _connection.start(); - - // Test connection - checkSendingMessage(); - - // Set StateManager to manager that ignores Close-oks - AMQProtocolSession protocolSession= - ((AMQConnection) _connection).getProtocolHandler().getProtocolSession(); - - MethodDispatcher d = protocolSession.getMethodDispatcher(); - - MethodDispatcher wrappedDispatcher = (MethodDispatcher) - Proxy.newProxyInstance(d.getClass().getClassLoader(), - d.getClass().getInterfaces(), - new MethodDispatcherProxyHandler( - (ClientMethodDispatcherImpl) d)); - - protocolSession.setMethodDispatcher(wrappedDispatcher); - - - AMQStateManager newStateManager=new NoCloseOKStateManager(protocolSession); - newStateManager.changeState(oldStateManager.getCurrentState()); - - ((AMQConnection) _connection).getProtocolHandler().setStateManager(newStateManager); - - final int TEST_CHANNEL=1; - _logger.info("Testing Channel(" + TEST_CHANNEL + ") Creation"); - - createChannelAndTest(TEST_CHANNEL); - - // Cause it to close - try - { - _logger.info("Closing Channel - invalid exchange"); - declareExchange(TEST_CHANNEL, "", "name_that_will_lookup_to_null", false); - fail("Exchange name is empty so this should fail "); - } - catch (AMQException e) - { - assertEquals("Exchange should not be found", AMQConstant.NOT_FOUND, e.getErrorCode()); - } - - try - { - // Send other methods that should be ignored - // send them no wait as server will ignore them - _logger.info("Tested known exchange - should ignore"); - declareExchange(TEST_CHANNEL, "topic", "amq.topic", true); - - _logger.info("Tested known invalid exchange - should ignore"); - declareExchange(TEST_CHANNEL, "", "name_that_will_lookup_to_null", true); - - _logger.info("Tested known invalid exchange - should ignore"); - declareExchange(TEST_CHANNEL, "", "name_that_will_lookup_to_null", true); - - // Send sync .. server will igore and timy oue - _logger.info("Tested known invalid exchange - should ignore"); - declareExchange(TEST_CHANNEL, "", "name_that_will_lookup_to_null", false); - } - catch (AMQTimeoutException te) - { - assertEquals("Request should timeout", AMQConstant.REQUEST_TIMEOUT, te.getErrorCode()); - } - catch (AMQException e) - { - fail("This should not fail as all requests should be ignored"); - } - - _logger.info("Sending Close"); - // Send Close-ok - sendClose(TEST_CHANNEL); - - _logger.info("Re-opening channel"); - - createChannelAndTest(TEST_CHANNEL); - - // Test connection is still ok - - checkSendingMessage(); - - } - catch (JMSException e) - { - e.printStackTrace(); - fail(e.getMessage()); - } - catch (AMQException e) - { - fail(e.getMessage()); - - } - catch (URLSyntaxException e) - { - fail(e.getMessage()); - } - finally - { - try - { - _session.close(); - _connection.close(); - } - catch (JMSException e) - { - e.printStackTrace(); - fail(e.getMessage()); - } - } - } - } -*/ - private void createChannelAndTest(int channel) throws FailoverException - { - // Create A channel - try - { - createChannel(channel); - } - catch (AMQException e) - { - fail(e.getMessage()); - } - - // Test it is ok - try - { - declareExchange(channel, "topic", "amq.topic", false); - _logger.info("Tested known exchange"); - } - catch (AMQException e) - { - fail("This should not fail as this is the default exchange details"); - } - } - - private void sendClose(int channel) - { - ChannelCloseOkBody body = - ((AMQConnection) _connection).getProtocolHandler().getMethodRegistry().createChannelCloseOkBody(); - AMQFrame frame = body.generateFrame(channel); - - ((AMQConnection) _connection).getProtocolHandler().writeFrame(frame); - } - - private void checkSendingMessage() throws JMSException - { - TEST++; - _logger.info("Test creating producer which will use channel id 1"); - - Queue queue = _session.createQueue("CCT_test_validation_queue" + TEST); - - MessageConsumer consumer = _session.createConsumer(queue); - - MessageProducer producer = _session.createProducer(queue); - - final String MESSAGE = "CCT_Test_Message"; - producer.send(_session.createTextMessage(MESSAGE)); - - Message msg = consumer.receive(2000); - - assertNotNull("Received messages should not be null.", msg); - assertEquals("Message received not what we sent", MESSAGE, ((TextMessage) msg).getText()); - } - - private Connection newConnection() - { - AMQConnection connection = null; - try - { - connection = new AMQConnection("amqp://guest:guest@CCTTest/test?brokerlist='" + _brokerlist + "'"); - - connection.setConnectionListener(this); - - _session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); - - connection.start(); - - } - catch (JMSException e) - { - fail("Creating new connection when:" + e.getMessage()); - } - catch (AMQException e) - { - fail("Creating new connection when:" + e.getMessage()); - } - catch (URLSyntaxException e) - { - fail("Creating new connection when:" + e.getMessage()); - } - - return connection; - } - - private void declareExchange(int channelId, String _type, String _name, boolean nowait) - throws AMQException, FailoverException - { - ExchangeDeclareBody body = - ((AMQConnection) _connection).getProtocolHandler() - .getMethodRegistry() - .createExchangeDeclareBody(0, - new AMQShortString(_name), - new AMQShortString(_type), - true, - false, - false, - false, - nowait, - null); - AMQFrame exchangeDeclare = body.generateFrame(channelId); - AMQProtocolHandler protocolHandler = ((AMQConnection) _connection).getProtocolHandler(); - - - if (nowait) - { - protocolHandler.writeFrame(exchangeDeclare); - } - else - { - protocolHandler.syncWrite(exchangeDeclare, ExchangeDeclareOkBody.class, SYNC_TIMEOUT); - } - -// return null; -// } -// }, (AMQConnection)_connection).execute(); - - } - - private void createChannel(int channelId) throws AMQException, FailoverException - { - ChannelOpenBody body = - ((AMQConnection) _connection).getProtocolHandler().getMethodRegistry().createChannelOpenBody(null); - - ((AMQConnection) _connection).getProtocolHandler().syncWrite(body.generateFrame(channelId), // outOfBand - ChannelOpenOkBody.class); - - } - - public void onException(JMSException jmsException) - { - // _logger.info("CCT" + jmsException); - fail(jmsException.getMessage()); - } - - public void bytesSent(long count) - { } - - public void bytesReceived(long count) - { } - - public boolean preFailover(boolean redirect) - { - return false; - } - - public boolean preResubscribe() - { - return false; - } - - public void failoverComplete() - { } - - private static final class MethodDispatcherProxyHandler implements InvocationHandler - { - private final ClientMethodDispatcherImpl _underlyingDispatcher; - private final ChannelCloseMethodHandlerNoCloseOk _handler = ChannelCloseMethodHandlerNoCloseOk.getInstance(); - - - public MethodDispatcherProxyHandler(ClientMethodDispatcherImpl dispatcher) - { - _underlyingDispatcher = dispatcher; - } - - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable - { - if(method.getName().equals("dispatchChannelClose")) - { - _handler.methodReceived(_underlyingDispatcher.getStateManager(), - (ChannelCloseBody) args[0], (Integer)args[1]); - } - Method dispatcherMethod = _underlyingDispatcher.getClass().getMethod(method.getName(), method.getParameterTypes()); - return dispatcherMethod.invoke(_underlyingDispatcher, args); - - } - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/CloseWithBlockingReceiveTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/CloseWithBlockingReceiveTest.java deleted file mode 100644 index c3be691f2d..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/CloseWithBlockingReceiveTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * - * 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.qpid.test.unit.client.channelclose; - -import javax.jms.Connection; -import javax.jms.MessageConsumer; -import javax.jms.Session; - -import junit.framework.TestCase; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.testutil.QpidTestCase; - -/** - * @author Apache Software Foundation - */ -public class CloseWithBlockingReceiveTest extends QpidTestCase -{ - - - protected void setUp() throws Exception - { - super.setUp(); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - - public void testReceiveReturnsNull() throws Exception - { - final AMQConnection connection = (AMQConnection) getConnection("guest", "guest"); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageConsumer consumer = session.createConsumer(new AMQTopic(connection, "banana")); - connection.start(); - - Runnable r = new Runnable() - { - - public void run() - { - try - { - Thread.sleep(1000); - connection.close(); - } - catch (Exception e) - { - } - } - }; - long startTime = System.currentTimeMillis(); - new Thread(r).start(); - consumer.receive(10000); - assertTrue(System.currentTimeMillis() - startTime < 10000); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(CloseWithBlockingReceiveTest.class); - } - -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java deleted file mode 100644 index 3ab3b0410e..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * - * 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.qpid.test.unit.client.connection; - -import org.apache.qpid.testutil.QpidTestCase; -import org.apache.qpidity.transport.util.Logger; - -import java.util.HashMap; -import java.util.Map; - -import javax.jms.Connection; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.TextMessage; - -/** - * ConnectionCloseTest - * - */ - -public class ConnectionCloseTest extends QpidTestCase -{ - - private static final Logger log = Logger.get(ConnectionCloseTest.class); - - public void testSendReceiveClose() throws Exception - { - Map<Thread,StackTraceElement[]> before = Thread.getAllStackTraces(); - - for (int i = 0; i < 500; i++) - { - if ((i % 10) == 0) - { - log.warn("%d messages sent and received", i); - } - - Connection receiver = getConnection(); - receiver.start(); - Session rssn = receiver.createSession(false, Session.AUTO_ACKNOWLEDGE); - Queue queue = rssn.createQueue("connection-close-test-queue"); - MessageConsumer cons = rssn.createConsumer(queue); - - Connection sender = getConnection(); - sender.start(); - Session sssn = sender.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageProducer prod = sssn.createProducer(queue); - prod.send(sssn.createTextMessage("test")); - sender.close(); - - TextMessage m = (TextMessage) cons.receive(2000); - assertNotNull("message was lost", m); - assertEquals(m.getText(), "test"); - receiver.close(); - } - - // The finalizer is notifying connector thread waiting on a selector key. - // This should leave the finalizer enough time to notify those threads - synchronized (this) - { - this.wait(1000); - } - - Map<Thread,StackTraceElement[]> after = Thread.getAllStackTraces(); - - Map<Thread,StackTraceElement[]> delta = new HashMap<Thread,StackTraceElement[]>(after); - for (Thread t : before.keySet()) - { - delta.remove(t); - } - - dumpStacks(delta); - - assertTrue("Spurious thread creation exceeded threshold, " + - delta.size() + " threads created.", - delta.size() < 10); - } - - private void dumpStacks(Map<Thread,StackTraceElement[]> map) - { - for (Map.Entry<Thread,StackTraceElement[]> entry : map.entrySet()) - { - Throwable t = new Throwable(); - t.setStackTrace(entry.getValue()); - log.warn(t, entry.getKey().toString()); - } - } - -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionStartTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionStartTest.java deleted file mode 100644 index 3cef57f90d..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionStartTest.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * - * 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.qpid.test.unit.client.connection; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.Session; -import javax.jms.TextMessage; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.testutil.QpidTestCase; - -public class ConnectionStartTest extends QpidTestCase -{ - - String _broker = "vm://:1"; - - AMQConnection _connection; - private Session _consumerSess; - private MessageConsumer _consumer; - - protected void setUp() throws Exception - { - super.setUp(); - try - { - - - AMQConnection pubCon = (AMQConnection) getConnection("guest", "guest"); - - AMQQueue queue = new AMQQueue(pubCon,"ConnectionStartTest"); - - Session pubSess = pubCon.createSession(false, AMQSession.AUTO_ACKNOWLEDGE); - - MessageProducer pub = pubSess.createProducer(queue); - - _connection = (AMQConnection) getConnection("guest", "guest"); - - _consumerSess = _connection.createSession(false, AMQSession.AUTO_ACKNOWLEDGE); - - _consumer = _consumerSess.createConsumer(queue); - - //publish after queue is created to ensure it can be routed as expected - pub.send(pubSess.createTextMessage("Initial Message")); - - pubCon.close(); - - } - catch (Exception e) - { - e.printStackTrace(); - fail("Connection to " + _broker + " should succeed. Reason: " + e); - } - } - - protected void tearDown() throws Exception - { - _connection.close(); - super.tearDown(); - } - - public void testSimpleReceiveConnection() - { - try - { - assertTrue("Connection should not be started", !_connection.started()); - //Note that this next line will start the dispatcher in the session - // should really not be called before _connection start - //assertTrue("There should not be messages waiting for the consumer", _consumer.receiveNoWait() == null); - _connection.start(); - assertTrue("There should be messages waiting for the consumer", _consumer.receive(10*1000) != null); - assertTrue("Connection should be started", _connection.started()); - - } - catch (JMSException e) - { - fail("An error occured during test because:" + e); - } - - } - - public void testMessageListenerConnection() - { - final CountDownLatch _gotMessage = new CountDownLatch(1); - - try - { - assertTrue("Connection should not be started", !_connection.started()); - _consumer.setMessageListener(new MessageListener() - { - public void onMessage(Message message) - { - try - { - assertTrue("Connection should be started", _connection.started()); - assertEquals("Mesage Received", "Initial Message", ((TextMessage) message).getText()); - _gotMessage.countDown(); - } - catch (JMSException e) - { - fail("Couldn't get message text because:" + e.getCause()); - } - } - }); - - assertTrue("Connection should not be started", !_connection.started()); - _connection.start(); - assertTrue("Connection should be started", _connection.started()); - - try - { - assertTrue("Listener was never called", _gotMessage.await(10 * 1000, TimeUnit.MILLISECONDS)); - } - catch (InterruptedException e) - { - fail("Timed out awaiting message via onMessage"); - } - - } - catch (JMSException e) - { - fail("Failed because:" + e.getCause()); - } - - } - - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(ConnectionStartTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java deleted file mode 100644 index f856e8c20b..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * - * 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.qpid.test.unit.client.connection; - -import org.apache.qpid.AMQConnectionFailureException; -import org.apache.qpid.AMQException; -import org.apache.qpid.AMQUnresolvedAddressException; -import org.apache.qpid.client.AMQAuthenticationException; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.jms.Session; - -import junit.framework.TestCase; - -import javax.jms.Connection; -import javax.jms.JMSException; -import javax.jms.QueueSession; -import javax.jms.TopicSession; - -public class ConnectionTest extends TestCase -{ - - String _broker = "vm://:1"; - String _broker_NotRunning = "vm://:2"; - String _broker_BadDNS = "tcp://hg3sgaaw4lgihjs"; - - - protected void setUp() throws Exception - { - super.setUp(); - TransportConnection.createVMBroker(1); - } - - protected void tearDown() throws Exception - { - TransportConnection.killVMBroker(1); - } - - public void testSimpleConnection() throws Exception - { - AMQConnection conn = null; - try - { - conn = new AMQConnection(_broker, "guest", "guest", "fred", "test"); - } - catch (Exception e) - { - fail("Connection to " + _broker + " should succeed. Reason: " + e); - } - finally - { - conn.close(); - } - } - - - public void testDefaultExchanges() throws Exception - { - AMQConnection conn = null; - try - { - conn = new AMQConnection("amqp://guest:guest@clientid/test?brokerlist='" - + _broker - + "?retries='1''&defaultQueueExchange='test.direct'" - + "&defaultTopicExchange='test.topic'" - + "&temporaryQueueExchange='tmp.direct'" - + "&temporaryTopicExchange='tmp.topic'"); - - QueueSession queueSession = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); - - AMQQueue queue = (AMQQueue) queueSession.createQueue("MyQueue"); - - assertEquals(queue.getExchangeName().toString(), "test.direct"); - - AMQQueue tempQueue = (AMQQueue) queueSession.createTemporaryQueue(); - - assertEquals(tempQueue.getExchangeName().toString(), "tmp.direct"); - - - queueSession.close(); - - - TopicSession topicSession = conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - - AMQTopic topic = (AMQTopic) topicSession.createTopic("silly.topic"); - - assertEquals(topic.getExchangeName().toString(), "test.topic"); - - AMQTopic tempTopic = (AMQTopic) topicSession.createTemporaryTopic(); - - assertEquals(tempTopic.getExchangeName().toString(), "tmp.topic"); - - topicSession.close(); - - } - catch (Exception e) - { - fail("Connection to " + _broker + " should succeed. Reason: " + e); - } - finally - { - conn.close(); - } - } - - //See QPID-771 - public void testPasswordFailureConnection() throws Exception - { - AMQConnection conn = null; - try - { - conn = new AMQConnection("amqp://guest:rubbishpassword@clientid/test?brokerlist='" + _broker + "?retries='1''"); - fail("Connection should not be established password is wrong."); - } - catch (AMQException amqe) - { - if (amqe.getCause().getClass() == Exception.class) - { - System.err.println("QPID-594 : WARNING RACE CONDITION. Unable to determine cause of Connection Failure."); - return; - } - - assertEquals("Exception was wrong type", JMSException.class, amqe.getCause().getClass()); - Exception linked = ((JMSException) amqe.getCause()).getLinkedException(); - assertEquals("Exception was wrong type", AMQAuthenticationException.class, linked.getClass()); - } - finally - { - if (conn != null) - { - conn.close(); - } - } - } - - public void testConnectionFailure() throws Exception - { - AMQConnection conn = null; - try - { - conn = new AMQConnection("amqp://guest:guest@clientid/testpath?brokerlist='" + _broker_NotRunning + "?retries='0''"); - fail("Connection should not be established"); - } - catch (AMQException amqe) - { - if (!(amqe instanceof AMQConnectionFailureException)) - { - fail("Correct exception not thrown. Excpected 'AMQConnectionException' got: " + amqe); - } - } - finally - { - if (conn != null) - { - conn.close(); - } - } - - } - - public void testUnresolvedHostFailure() throws Exception - { - AMQConnection conn = null; - try - { - conn = new AMQConnection("amqp://guest:guest@clientid/testpath?brokerlist='" + _broker_BadDNS + "?retries='0''"); - fail("Connection should not be established"); - } - catch (AMQException amqe) - { - if (!(amqe instanceof AMQUnresolvedAddressException)) - { - fail("Correct exception not thrown. Excpected 'AMQUnresolvedAddressException' got: " + amqe); - } - } - finally - { - if (conn != null) - { - conn.close(); - } - } - - } - - public void testUnresolvedVirtualHostFailure() throws Exception - { - AMQConnection conn = null; - try - { - conn = new AMQConnection("amqp://guest:guest@clientid/rubbishhost?brokerlist='" + _broker + "?retries='0''"); - fail("Connection should not be established"); - } - catch (AMQException amqe) - { - if (!(amqe instanceof AMQConnectionFailureException)) - { - fail("Correct exception not thrown. Excpected 'AMQConnectionFailureException' got: " + amqe); - } - } - finally - { - if (conn != null) - { - conn.close(); - } - } - } - - public void testClientIdCannotBeChanged() throws Exception - { - Connection connection = new AMQConnection(_broker, "guest", "guest", - "fred", "test"); - try - { - connection.setClientID("someClientId"); - fail("No IllegalStateException thrown when resetting clientid"); - } - catch (javax.jms.IllegalStateException e) - { - // PASS - } - finally - { - if (connection != null) - { - connection.close(); - } - } - } - - public void testClientIdIsPopulatedAutomatically() throws Exception - { - Connection connection = new AMQConnection(_broker, "guest", "guest", - null, "test"); - try - { - assertNotNull(connection.getClientID()); - } - finally - { - connection.close(); - } - connection.close(); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(ConnectionTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ExceptionListenerTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ExceptionListenerTest.java deleted file mode 100644 index ccf16a0b6e..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ExceptionListenerTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * 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.qpid.test.unit.client.connection; - -import org.apache.qpid.testutil.QpidTestCase; - -import org.apache.qpid.util.concurrent.Condition; - -import javax.jms.Connection; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; - -/** - * ExceptionListenerTest - * - */ - -public class ExceptionListenerTest extends QpidTestCase -{ - - public void testBrokerDeath() throws Exception - { - Connection conn = getConnection("guest", "guest"); - - conn.start(); - - final Condition fired = new Condition(); - conn.setExceptionListener(new ExceptionListener() - { - public void onException(JMSException e) - { - fired.set(); - } - }); - - stopBroker(); - - if (!fired.get(3000)) - { - fail("exception listener was not fired"); - } - } - -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java index 27adc4dd77..6f4c26945c 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java @@ -33,11 +33,12 @@ public class ConnectionURLTest extends TestCase public void testFailoverURL() throws URLSyntaxException { - String url = "amqp://ritchiem:bob@/test?brokerlist='tcp://localhost:5672;tcp://fancyserver:3000/',failover='roundrobin'"; + String url = "amqp://ritchiem:bob@/test?brokerlist='tcp://localhost:5672;tcp://fancyserver:3000/',failover='roundrobin?cyclecount='100''"; ConnectionURL connectionurl = new AMQConnectionURL(url); assertTrue(connectionurl.getFailoverMethod().equals("roundrobin")); + assertEquals("100", connectionurl.getFailoverOption(ConnectionURL.OPTIONS_FAILOVER_CYCLE)); assertTrue(connectionurl.getUsername().equals("ritchiem")); assertTrue(connectionurl.getPassword().equals("bob")); assertTrue(connectionurl.getVirtualHost().equals("/test")); @@ -276,7 +277,7 @@ public class ConnectionURLTest extends TestCase public void testSingleTransportMultiOptionURL() throws URLSyntaxException { - String url = "amqp://guest:guest@/test?brokerlist='tcp://localhost:5672',routingkey='jim',timeout='200',immediatedelivery='true'"; + String url = "amqp://guest:guest@/test?brokerlist='tcp://localhost:5672?foo='jim'&bar='bob'&fred='jimmy'',routingkey='jim',timeout='200',immediatedelivery='true'"; ConnectionURL connectionurl = new AMQConnectionURL(url); @@ -493,8 +494,38 @@ public class ConnectionURLTest extends TestCase } } + public void testSingleTransportMultiOptionOnBrokerURL() throws URLSyntaxException + { + String url = "amqp://guest:guest@/test?brokerlist='tcp://localhost:5672?foo='jim'&bar='bob'&fred='jimmy'',routingkey='jim',timeout='200',immediatedelivery='true'"; + + ConnectionURL connectionurl = new AMQConnectionURL(url); + + assertTrue(connectionurl.getFailoverMethod() == null); + assertTrue(connectionurl.getUsername().equals("guest")); + assertTrue(connectionurl.getPassword().equals("guest")); + assertTrue(connectionurl.getVirtualHost().equals("/test")); + + assertTrue(connectionurl.getBrokerCount() == 1); + + BrokerDetails service = connectionurl.getBrokerDetails(0); + + assertTrue(service.getTransport().equals("tcp")); + + + assertTrue(service.getHost().equals("localhost")); + assertTrue(service.getPort() == 5672); + assertEquals("jim",service.getProperty("foo")); + assertEquals("bob",service.getProperty("bar")); + assertEquals("jimmy",service.getProperty("fred")); + + assertTrue(connectionurl.getOption("routingkey").equals("jim")); + assertTrue(connectionurl.getOption("timeout").equals("200")); + assertTrue(connectionurl.getOption("immediatedelivery").equals("true")); + } + public static junit.framework.Test suite() { return new junit.framework.TestSuite(ConnectionURLTest.class); } } + diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/destinationurl/DestinationURLTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/destinationurl/DestinationURLTest.java index 88dd212ab6..2a66b86985 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/destinationurl/DestinationURLTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/destinationurl/DestinationURLTest.java @@ -23,7 +23,6 @@ package org.apache.qpid.test.unit.client.destinationurl; import junit.framework.TestCase; import org.apache.qpid.exchange.ExchangeDefaults; -import org.apache.qpid.test.unit.basic.PropertyValueTest; import org.apache.qpid.url.AMQBindingURL; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/Client.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/Client.java deleted file mode 100644 index f43ccaf0ff..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/Client.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * - * 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.qpid.test.unit.client.forwardall; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; - -/** - * Declare a private temporary response queue, - * send a message to amq.direct with a well known routing key with the - * private response queue as the reply-to destination - * consume responses. - */ -public class Client implements MessageListener -{ - private static final Logger _logger = LoggerFactory.getLogger(Client.class); - - private final AMQConnection _connection; - private final AMQSession _session; - private final int _expected; - private int _count; - private static QpidTestCase _qct; - - Client(String broker, int expected) throws Exception - { - this(connect(broker), expected); - } - - public static void setQTC(QpidTestCase qtc) - { - _qct = qtc; - } - Client(AMQConnection connection, int expected) throws Exception - { - _connection = connection; - _expected = expected; - _session = (AMQSession) _connection.createSession(false, AMQSession.NO_ACKNOWLEDGE); - AMQQueue response = - new AMQQueue(_connection.getDefaultQueueExchangeName(), new AMQShortString("ResponseQueue"), true); - _session.createConsumer(response).setMessageListener(this); - _connection.start(); - // AMQQueue service = new SpecialQueue(_connection, "ServiceQueue"); - AMQQueue service = (AMQQueue) _session.createQueue("ServiceQueue") ; - Message request = _session.createTextMessage("Request!"); - request.setJMSReplyTo(response); - MessageProducer prod = _session.createProducer(service); - prod.send(request); - } - - void shutdownWhenComplete() throws Exception - { - waitUntilComplete(); - _connection.close(); - } - - public synchronized void onMessage(Message response) - { - - _logger.info("Received " + (++_count) + " of " + _expected + " responses."); - if (_count == _expected) - { - - notifyAll(); - } - - } - - synchronized void waitUntilComplete() throws Exception - { - - if (_count < _expected) - { - wait(60000); - } - - if (_count < _expected) - { - throw new Exception("Didn't receive all messages... got " + _count + " expected " + _expected); - } - } - - static AMQConnection connect(String broker) throws Exception - { - //return new AMQConnection(broker, "guest", "guest", "Client" + System.currentTimeMillis(), "test"); - return (AMQConnection) _qct.getConnection("guest", "guest") ; - } - - public static void main(String[] argv) throws Exception - { - final String connectionString; - final int expected; - if (argv.length == 0) - { - connectionString = "localhost:5672"; - expected = 100; - } - else - { - connectionString = argv[0]; - expected = Integer.parseInt(argv[1]); - } - - new Client(connect(connectionString), expected).shutdownWhenComplete(); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/CombinedTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/CombinedTest.java deleted file mode 100644 index 29d9e5de2c..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/CombinedTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * - * 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.qpid.test.unit.client.forwardall; - -import org.apache.qpid.testutil.VMBrokerSetup; -import org.apache.qpid.testutil.QpidTestCase; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Runs the Service's and Client parts of the test in the same process - * as the broker - */ -public class CombinedTest extends QpidTestCase -{ - private static final Logger _logger = LoggerFactory.getLogger(CombinedTest.class); - private int run = 0; - - protected void setUp() throws Exception - { - super.setUp(); - Service.setQTC(this); - Client.setQTC(this); - } - - protected void tearDown() throws Exception - { - ServiceCreator.closeAll(); - super.tearDown(); - } - - public void testForwardAll() throws Exception - { - while (run < 10) - { - int services =1; - ServiceCreator.start("vm://:1", services); - - _logger.info("Starting " + ++run + " client..."); - - new Client("vm://:1", services).shutdownWhenComplete(); - - - _logger.info("Completed " + run + " successfully!"); - } - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(CombinedTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/Service.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/Service.java deleted file mode 100644 index 3dc9a3ccfb..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/Service.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * - * 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.qpid.test.unit.client.forwardall; - -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.testutil.QpidTestCase; - -/** - * Declare a queue and bind it to amq.direct with a 'well known' routing key, - * register a consumer for this queue and send a response to every message received. - */ -public class Service implements MessageListener -{ - private final AMQConnection _connection; - private final AMQSession _session; - - private static QpidTestCase _qct; - - - public static void setQTC(QpidTestCase qtc) - { - _qct = qtc; - } - Service(String broker) throws Exception - { - this(connect(broker)); - } - - Service(AMQConnection connection) throws Exception - { - _connection = connection; - //AMQQueue queue = new SpecialQueue(connection, "ServiceQueue"); - _session = (AMQSession) _connection.createSession(false, AMQSession.NO_ACKNOWLEDGE); - AMQQueue queue = (AMQQueue) _session.createQueue("ServiceQueue") ; - _session.createConsumer(queue).setMessageListener(this); - _connection.start(); - } - - public void onMessage(Message request) - { - try - { - Message response = _session.createTextMessage("Response!"); - Destination replyTo = request.getJMSReplyTo(); - _session.createProducer(replyTo).send(response); - } - catch (Exception e) - { - e.printStackTrace(System.out); - } - } - - public void close() throws JMSException - { - _connection.close(); - } - - static AMQConnection connect(String broker) throws Exception - { - //return new AMQConnection(broker, "guest", "guest", "Client" + System.currentTimeMillis(), "test"); - return (AMQConnection) _qct.getConnection("guest", "guest") ; - } - -// public static void main(String[] argv) throws Exception -// { -// String broker = argv.length == 0? "localhost:5672" : argv[0]; -// new Service(broker); -// } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/ServiceCreator.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/ServiceCreator.java deleted file mode 100644 index be16f6b7ae..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/ServiceCreator.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * - * 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.qpid.test.unit.client.forwardall; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.JMSException; - -public class ServiceCreator implements Runnable -{ - private static final Logger _logger = LoggerFactory.getLogger(ServiceCreator.class); - - private static Thread[] threads; - private static ServiceCreator[] _services; - - private final String broker; - private Service service; - - ServiceCreator(String broker) - { - this.broker = broker; - } - - public void run() - { - try - { - service = new Service(broker); - } - catch (Exception e) - { - e.printStackTrace(System.out); - } - } - - public void closeSC() throws JMSException - { - service.close(); - } - - static void closeAll() - { - for (int i = 0; i < _services.length; i++) - { - try - { - _services[i].closeSC(); - } - catch (JMSException e) - { - // ignore - } - } - } - - static void start(String broker, int services) throws InterruptedException - { - threads = new Thread[services]; - _services = new ServiceCreator[services]; - ServiceCreator runner = new ServiceCreator(broker); - // start services - _logger.info("Starting " + services + " services..."); - for (int i = 0; i < services; i++) - { - threads[i] = new Thread(runner); - _services[i] = runner; - threads[i].start(); - } - - for (int i = 0; i < threads.length; i++) - { - threads[i].join(); - } - } - - public static void main(String[] argv) throws Exception - { - final String connectionString; - final int services; - if (argv.length == 0) - { - connectionString = "localhost:5672"; - services = 100; - } - else - { - connectionString = argv[0]; - services = Integer.parseInt(argv[1]); - } - - start(connectionString, services); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/SpecialQueue.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/SpecialQueue.java deleted file mode 100644 index 27371b0397..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/SpecialQueue.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * - * 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.qpid.test.unit.client.forwardall; - -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.framing.AMQShortString; - -/** - * Queue that allows several private queues to be registered and bound - * to an exchange with the same routing key. - * - */ -class SpecialQueue extends AMQQueue -{ - private final AMQShortString name; - - SpecialQueue(AMQConnection con, String name) - { - super(con, name, true); - this.name = new AMQShortString(name); - } - - public AMQShortString getRoutingKey() - { - return name; - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/message/ObjectMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/message/ObjectMessageTest.java deleted file mode 100644 index 7b3077a1c1..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/message/ObjectMessageTest.java +++ /dev/null @@ -1,341 +0,0 @@ -/* - * - * 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.qpid.test.unit.client.message; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQDestination; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.testutil.VMBrokerSetup; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.ObjectMessage; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; - -public class ObjectMessageTest extends QpidTestCase implements MessageListener -{ - private static final Logger _logger = LoggerFactory.getLogger(ObjectMessageTest.class); - - private AMQConnection connection; - private AMQDestination destination; - private AMQSession session; - private MessageProducer producer; - private Serializable[] data; - private volatile boolean waiting; - private int received; - private final ArrayList items = new ArrayList(); - - private String _broker = "vm://:1"; - - protected void setUp() throws Exception - { - super.setUp(); - connection = (AMQConnection) getConnection("guest", "guest"); - destination = new AMQQueue(connection, randomize("LatencyTest"), true); - session = (AMQSession) connection.createSession(false, AMQSession.NO_ACKNOWLEDGE); - - // set up a consumer - session.createConsumer(destination).setMessageListener(this); - connection.start(); - - // create a publisher - producer = session.createProducer(destination, false, false, true); - A a1 = new A(1, "A"); - A a2 = new A(2, "a"); - B b = new B(1, "B"); - C c = new C(); - c.put("A1", a1); - c.put("a2", a2); - c.put("B", b); - c.put("String", "String"); - - data = new Serializable[] { a1, a2, b, c, "Hello World!", new Integer(1001) }; - } - - protected void tearDown() throws Exception - { - close(); - super.tearDown(); - } - - public ObjectMessageTest() - { } - - ObjectMessageTest(String broker) throws Exception - { - _broker = broker; - } - - public void testSendAndReceive() throws Exception - { - try - { - send(); - waitUntilReceived(data.length); - check(); - _logger.info("All " + data.length + " items matched."); - } - catch (Exception e) - { - e.printStackTrace(); - fail("This Test should succeed but failed due to: " + e); - } - } - - public void testSetObjectPropertyForString() throws Exception - { - String testStringProperty = "TestStringProperty"; - ObjectMessage msg = session.createObjectMessage(data[0]); - msg.setObjectProperty("TestStringProperty", testStringProperty); - assertEquals(testStringProperty, msg.getObjectProperty("TestStringProperty")); - } - - public void testSetObjectPropertyForBoolean() throws Exception - { - ObjectMessage msg = session.createObjectMessage(data[0]); - msg.setObjectProperty("TestBooleanProperty", Boolean.TRUE); - assertEquals(Boolean.TRUE, msg.getObjectProperty("TestBooleanProperty")); - } - - public void testSetObjectPropertyForByte() throws Exception - { - ObjectMessage msg = session.createObjectMessage(data[0]); - msg.setObjectProperty("TestByteProperty", Byte.MAX_VALUE); - assertEquals(Byte.MAX_VALUE, msg.getObjectProperty("TestByteProperty")); - } - - public void testSetObjectPropertyForShort() throws Exception - { - ObjectMessage msg = session.createObjectMessage(data[0]); - msg.setObjectProperty("TestShortProperty", Short.MAX_VALUE); - assertEquals(Short.MAX_VALUE, msg.getObjectProperty("TestShortProperty")); - } - - public void testSetObjectPropertyForInteger() throws Exception - { - ObjectMessage msg = session.createObjectMessage(data[0]); - msg.setObjectProperty("TestIntegerProperty", Integer.MAX_VALUE); - assertEquals(Integer.MAX_VALUE, msg.getObjectProperty("TestIntegerProperty")); - } - - public void testSetObjectPropertyForDouble() throws Exception - { - ObjectMessage msg = session.createObjectMessage(data[0]); - msg.setObjectProperty("TestDoubleProperty", Double.MAX_VALUE); - assertEquals(Double.MAX_VALUE, msg.getObjectProperty("TestDoubleProperty")); - } - - public void testSetObjectPropertyForFloat() throws Exception - { - ObjectMessage msg = session.createObjectMessage(data[0]); - msg.setObjectProperty("TestFloatProperty", Float.MAX_VALUE); - assertEquals(Float.MAX_VALUE, msg.getObjectProperty("TestFloatProperty")); - } - - public void testSetObjectPropertyForByteArray() throws Exception - { - byte[] array = { 1, 2, 3, 4, 5 }; - ObjectMessage msg = session.createObjectMessage(data[0]); - msg.setObjectProperty("TestByteArrayProperty", array); - assertTrue(Arrays.equals(array, (byte[]) msg.getObjectProperty("TestByteArrayProperty"))); - } - - public void testSetObjectForNull() throws Exception - { - ObjectMessage msg = session.createObjectMessage(); - msg.setObject(null); - assertNull(msg.getObject()); - } - - private void send() throws Exception - { - for (int i = 0; i < data.length; i++) - { - ObjectMessage msg; - if ((i % 2) == 0) - { - msg = session.createObjectMessage(data[i]); - } - else - { - msg = session.createObjectMessage(); - msg.setObject(data[i]); - } - - producer.send(msg); - } - } - - public void check() throws Exception - { - Object[] actual = (Object[]) items.toArray(); - if (actual.length != data.length) - { - throw new Exception("Expected " + data.length + " objects, got " + actual.length); - } - - for (int i = 0; i < data.length; i++) - { - if (actual[i] instanceof Exception) - { - throw new Exception("Error on receive of " + data[i], ((Exception) actual[i])); - } - - if (actual[i] == null) - { - throw new Exception("Expected " + data[i] + " got null"); - } - - if (!data[i].equals(actual[i])) - { - throw new Exception("Expected " + data[i] + " got " + actual[i]); - } - } - } - - private void close() throws Exception - { - session.close(); - connection.close(); - } - - private synchronized void waitUntilReceived(int count) throws InterruptedException - { - waiting = true; - while (received < count) - { - wait(); - } - - waiting = false; - } - - public void onMessage(Message message) - { - - try - { - if (message instanceof ObjectMessage) - { - items.add(((ObjectMessage) message).getObject()); - } - else - { - _logger.error("ERROR: Got " + message.getClass().getName() + " not ObjectMessage"); - items.add(message); - } - } - catch (JMSException e) - { - e.printStackTrace(); - items.add(e); - } - - synchronized (this) - { - received++; - notify(); - } - } - - public static void main(String[] argv) throws Exception - { - String broker = (argv.length > 0) ? argv[0] : "vm://:1"; - if ("-help".equals(broker)) - { - System.out.println("Usage: <broker>"); - } - - new ObjectMessageTest(broker).testSendAndReceive(); - } - - private static class A implements Serializable - { - private String sValue; - private int iValue; - - A(int i, String s) - { - sValue = s; - iValue = i; - } - - public int hashCode() - { - return iValue; - } - - public boolean equals(Object o) - { - return (o instanceof A) && equals((A) o); - } - - protected boolean equals(A a) - { - return areEqual(a.sValue, sValue) && (a.iValue == iValue); - } - } - - private static class B extends A - { - private long time; - - B(int i, String s) - { - super(i, s); - time = System.currentTimeMillis(); - } - - protected boolean equals(A a) - { - return super.equals(a) && (a instanceof B) && (time == ((B) a).time); - } - } - - private static class C extends HashMap implements Serializable - { } - - private static boolean areEqual(Object a, Object b) - { - return (a == null) ? (b == null) : a.equals(b); - } - - private static String randomize(String in) - { - return in + System.currentTimeMillis(); - } - - public static junit.framework.Test suite() - { - return new VMBrokerSetup(new junit.framework.TestSuite(ObjectMessageTest.class)); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java deleted file mode 100644 index 4cdd7dd7e8..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * - * 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.qpid.test.unit.client.protocol; - -import junit.framework.TestCase; - -import org.apache.mina.common.IoSession; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.protocol.AMQProtocolHandler; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.testutil.QpidTestCase; - -public class AMQProtocolSessionTest extends QpidTestCase -{ - private static class AMQProtSession extends AMQProtocolSession - { - - public AMQProtSession(AMQProtocolHandler protocolHandler, IoSession protocolSession, AMQConnection connection) - { - super(protocolHandler,protocolSession,connection); - } - - public TestIoSession getMinaProtocolSession() - { - return (TestIoSession) _minaProtocolSession; - } - - public AMQShortString genQueueName() - { - return generateQueueName(); - } - } - - //private Strings for test values and expected results - private String _brokenAddress = "tcp://myAddress;:";; - private String _generatedAddress; - private String _emptyAddress; - private String _generatedAddress_2; - private String _validAddress; - private String _generatedAddress_3; - private int _port; - private AMQProtSession _testSession; - - protected void setUp() throws Exception - { - super.setUp(); - - //don't care about the values set here apart from the dummy IoSession - _testSession = new AMQProtSession(null,new TestIoSession(), (AMQConnection) getConnection("guest", "guest")); - - //initialise addresses for test and expected results - _port = 123; - _brokenAddress = "tcp://myAddress;:"; - _generatedAddress = "tmp_tcpmyAddress123_1"; - _emptyAddress = ""; - _generatedAddress_2 = "tmp_localhost127.0.0.1123_2"; - _validAddress = "abc"; - _generatedAddress_3 = "tmp_abc123_3"; - } - - public void testGenerateQueueName() - { - AMQShortString testAddress; - - //test address with / and ; chars which generateQueueName should removeKey - _testSession.getMinaProtocolSession().setStringLocalAddress(_brokenAddress); - _testSession.getMinaProtocolSession().setLocalPort(_port); - - testAddress = _testSession.genQueueName(); - assertEquals("Failure when generating a queue exchange from an address with special chars",_generatedAddress,testAddress.toString()); - - //test empty address - _testSession.getMinaProtocolSession().setStringLocalAddress(_emptyAddress); - - testAddress = _testSession.genQueueName(); - assertEquals("Failure when generating a queue exchange from an empty address",_generatedAddress_2,testAddress.toString()); - - //test address with no special chars - _testSession.getMinaProtocolSession().setStringLocalAddress(_validAddress); - - testAddress = _testSession.genQueueName(); - assertEquals("Failure when generating a queue exchange from an address with no special chars",_generatedAddress_3,testAddress.toString()); - - } - - protected void tearDown() throws Exception - { - _testSession = null; - _brokenAddress = null; - _generatedAddress = null; - _emptyAddress = null; - _generatedAddress_2 = null; - _validAddress = null; - _generatedAddress_3 = null; - super.tearDown(); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(AMQProtocolSessionTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/protocol/TestIoSession.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/protocol/TestIoSession.java deleted file mode 100644 index d14e0b771f..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/protocol/TestIoSession.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * - * 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.qpid.test.unit.client.protocol; - -import java.net.InetSocketAddress; -import java.net.SocketAddress; - -import org.apache.mina.common.IoFilterChain; -import org.apache.mina.common.IoHandler; -import org.apache.mina.common.IoService; -import org.apache.mina.common.IoServiceConfig; -import org.apache.mina.common.IoSessionConfig; -import org.apache.mina.common.TransportType; -import org.apache.mina.common.support.BaseIoSession; - -public class TestIoSession extends BaseIoSession { - - private String _stringLocalAddress; - private int _localPort; - - public SocketAddress getLocalAddress() - { - //create a new address for testing purposes using member variables - return new InetSocketAddress(_stringLocalAddress,_localPort); - } - - protected void updateTrafficMask() { - //dummy - } - - public IoService getService() { - return null; - } - - public IoServiceConfig getServiceConfig() { - return null; - } - - public IoHandler getHandler() { - return null; - } - - public IoSessionConfig getConfig() { - return null; - } - - public IoFilterChain getFilterChain() { - return null; - } - - public TransportType getTransportType() { - return null; - } - - public SocketAddress getRemoteAddress() { - return null; - } - - public SocketAddress getServiceAddress() { - return null; - } - - public int getScheduledWriteRequests() { - return 0; - } - - public int getScheduledWriteBytes() { - return 0; - } - - public String getStringLocalAddress() { - return _stringLocalAddress; - } - - public void setStringLocalAddress(String _stringLocalAddress) { - this._stringLocalAddress = _stringLocalAddress; - } - - public int getLocalPort() { - return _localPort; - } - - public void setLocalPort(int _localPort) { - this._localPort = _localPort; - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/temporaryqueue/TemporaryQueueTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/temporaryqueue/TemporaryQueueTest.java deleted file mode 100644 index 46b99fac8d..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/temporaryqueue/TemporaryQueueTest.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * - * 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.qpid.test.unit.client.temporaryqueue; - -import javax.jms.Connection; -import javax.jms.JMSException; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Session; -import javax.jms.TemporaryQueue; -import javax.jms.TextMessage; -import junit.framework.Assert; - -import org.apache.qpid.testutil.QpidTestCase; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.transport.TransportConnection; - -import java.util.List; -import java.util.LinkedList; - -public class TemporaryQueueTest extends QpidTestCase -{ - protected void setUp() throws Exception - { - super.setUp(); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - protected Connection createConnection() throws Exception - { - return getConnection("guest", "guest"); - } - - public void testTempoaryQueue() throws Exception - { - Connection conn = createConnection(); - Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - TemporaryQueue queue = session.createTemporaryQueue(); - assertNotNull(queue); - MessageProducer producer = session.createProducer(queue); - MessageConsumer consumer = session.createConsumer(queue); - conn.start(); - producer.send(session.createTextMessage("hello")); - TextMessage tm = (TextMessage) consumer.receive(2000); - assertNotNull(tm); - assertEquals("hello", tm.getText()); - - try - { - queue.delete(); - fail("Expected JMSException : should not be able to delete while there are active consumers"); - } - catch (JMSException je) - { - ; //pass - } - - consumer.close(); - - try - { - queue.delete(); - } - catch (JMSException je) - { - fail("Unexpected Exception: " + je.getMessage()); - } - - conn.close(); - } - - public void tUniqueness() throws Exception - { - int numProcs = Runtime.getRuntime().availableProcessors(); - final int threadsProc = 5; - - runUniqueness(1, 10); - runUniqueness(numProcs * threadsProc, 10); - runUniqueness(numProcs * threadsProc, 100); - runUniqueness(numProcs * threadsProc, 500); - } - - void runUniqueness(int makers, int queues) throws Exception - { - Connection connection = createConnection(); - - Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); - - List<TempQueueMaker> tqList = new LinkedList<TempQueueMaker>(); - - //Create Makers - for (int m = 0; m < makers; m++) - { - tqList.add(new TempQueueMaker(session, queues)); - } - - - List<Thread> threadList = new LinkedList<Thread>(); - - //Create Makers - for (TempQueueMaker maker : tqList) - { - threadList.add(new Thread(maker)); - } - - //Start threads - for (Thread thread : threadList) - { - thread.start(); - } - - // Join Threads - for (Thread thread : threadList) - { - try - { - thread.join(); - } - catch (InterruptedException e) - { - fail("Couldn't correctly join threads"); - } - } - - - List<AMQQueue> list = new LinkedList<AMQQueue>(); - - // Test values - for (TempQueueMaker maker : tqList) - { - check(maker, list); - } - - Assert.assertEquals("Not enough queues made.", makers * queues, list.size()); - - connection.close(); - } - - private void check(TempQueueMaker tq, List<AMQQueue> list) - { - for (AMQQueue q : tq.getList()) - { - if (list.contains(q)) - { - fail(q + " already exists."); - } - else - { - list.add(q); - } - } - } - - - class TempQueueMaker implements Runnable - { - List<AMQQueue> _queues; - Session _session; - private int _count; - - - TempQueueMaker(Session session, int queues) throws JMSException - { - _queues = new LinkedList<AMQQueue>(); - - _count = queues; - - _session = session; - } - - public void run() - { - int i = 0; - try - { - for (; i < _count; i++) - { - _queues.add((AMQQueue) _session.createTemporaryQueue()); - } - } - catch (JMSException jmse) - { - //stop - } - } - - List<AMQQueue> getList() - { - return _queues; - } - } - - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(TemporaryQueueTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/close/CloseBeforeAckTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/close/CloseBeforeAckTest.java deleted file mode 100644 index 54b2ee95f4..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/close/CloseBeforeAckTest.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * - * 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.qpid.test.unit.close; - -import junit.framework.Assert; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.apache.qpid.junit.concurrency.TestRunnable; -import org.apache.qpid.junit.concurrency.ThreadTestCoordinator; - -import javax.jms.Connection; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.Session; - -/** - * This test forces the situation where a session is closed whilst a message consumer is still in its onMessage method. - * Running in AUTO_ACK mode, the close call ought to wait until the onMessage method completes, and the ack is sent - * before closing the connection. - * - * <p><table id="crc"><caption>CRC Card</caption> <tr><th> Responsibilities <th> Collaborations <tr><td> Check that - * closing a connection whilst handling a message, blocks till completion of the handler. </table> - */ -public class CloseBeforeAckTest extends QpidTestCase -{ - private static final Logger log = LoggerFactory.getLogger(CloseBeforeAckTest.class); - - Connection connection; - Session session; - public static final String TEST_QUEUE_NAME = "TestQueue"; - private int TEST_COUNT = 25; - - class TestThread1 extends TestRunnable implements MessageListener - { - public void runWithExceptions() throws Exception - { - // Set this up to listen for message on the test session. - session.createConsumer(session.createQueue(TEST_QUEUE_NAME)).setMessageListener(this); - } - - public void onMessage(Message message) - { - // Give thread 2 permission to close the session. - allow(new int[] { 1 }); - - // Wait until thread 2 has closed the connection, or is blocked waiting for this to complete. - waitFor(new int[] { 1 }, true); - } - } - - TestThread1 testThread1 = new TestThread1(); - - TestRunnable testThread2 = - new TestRunnable() - { - public void runWithExceptions() throws Exception - { - // Send a message to be picked up by thread 1. - session.createProducer(null).send(session.createQueue(TEST_QUEUE_NAME), - session.createTextMessage("Hi there thread 1!")); - - // Wait for thread 1 to pick up the message and give permission to continue. - waitFor(new int[] { 0 }, false); - - // Close the connection. - session.close(); - - // Allow thread 1 to continue to completion, if it is erronously still waiting. - allow(new int[] { 1 }); - } - }; - - public void testCloseBeforeAutoAck_QPID_397() throws Exception - { - // Create a session in auto acknowledge mode. This problem shows up in auto acknowledge if the client acks - // message at the end of the onMessage method, after a close has been sent. - session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - ThreadTestCoordinator tt = new ThreadTestCoordinator(2); - - tt.addTestThread(testThread1, 0); - tt.addTestThread(testThread2, 1); - tt.setDeadlockTimeout(500); - tt.run(); - - String errorMessage = tt.joinAndRetrieveMessages(); - - // Print any error messages or exceptions. - log.debug(errorMessage); - - if (!tt.getExceptions().isEmpty()) - { - for (Exception e : tt.getExceptions()) - { - log.debug("Exception thrown during test thread: ", e); - } - } - - Assert.assertTrue(errorMessage, "".equals(errorMessage)); - } - - public void closeBeforeAutoAckManyTimes() throws Exception - { - for (int i = 0; i < TEST_COUNT; i++) - { - testCloseBeforeAutoAck_QPID_397(); - } - } - - protected void setUp() throws Exception - { - super.setUp(); - connection = getConnection("guest", "guest"); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java deleted file mode 100644 index 5ebde71d6c..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java +++ /dev/null @@ -1,374 +0,0 @@ -/* - * 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.qpid.test.unit.close; - -import org.apache.qpid.AMQException; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.message.AbstractJMSMessage; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.testutil.QpidClientConnection; -import org.apache.qpid.testutil.QpidTestCase; -import org.apache.qpid.url.URLSyntaxException; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Connection; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.Queue; -import javax.jms.Session; - -import java.util.concurrent.atomic.AtomicInteger; - -public class MessageRequeueTest extends QpidTestCase -{ - private static final Logger _logger = LoggerFactory.getLogger(MessageRequeueTest.class); - - protected static AtomicInteger consumerIds = new AtomicInteger(0); - protected final Integer numTestMessages = 150; - - protected final int consumeTimeout = 3000; - - protected final String queue = "direct://amq.direct//message-requeue-test-queue"; - protected String payload = "Message:"; - - protected final String BROKER = "vm://:1"; - private boolean testReception = true; - - private long[] receieved = new long[numTestMessages + 1]; - private boolean passed = false; - QpidClientConnection conn; - - - protected void setUp() throws Exception - { - super.setUp(); - - conn = new QpidClientConnection(BROKER); - - conn.connect(); - // clear queue - conn.consume(queue, consumeTimeout); - // load test data - _logger.info("creating test data, " + numTestMessages + " messages"); - conn.put(queue, payload, numTestMessages); - // close this connection - conn.disconnect(); - } - - protected void tearDown() throws Exception - { - - if (!passed) // clean up - { - QpidClientConnection conn = new QpidClientConnection(BROKER); - - conn.connect(); - // clear queue - conn.consume(queue, consumeTimeout); - - conn.disconnect(); - } - - super.tearDown(); - } - - /** - * multiple consumers - * - * @throws javax.jms.JMSException if a JMS problem occurs - * @throws InterruptedException on timeout - */ - public void testDrain() throws Exception - { - QpidClientConnection conn = new QpidClientConnection(BROKER); - - conn.connect(); - - _logger.info("consuming queue " + queue); - Queue q = conn.getSession().createQueue(queue); - - final MessageConsumer consumer = conn.getSession().createConsumer(q); - int messagesReceived = 0; - - long[] messageLog = new long[numTestMessages + 1]; - - _logger.info("consuming..."); - Message msg = consumer.receive(1000); - while (msg != null) - { - messagesReceived++; - - long dt = ((AbstractJMSMessage) msg).getDeliveryTag(); - - int msgindex = msg.getIntProperty("index"); - if (messageLog[msgindex] != 0) - { - _logger.error("Received Message(" + msgindex + ":" + ((AbstractJMSMessage) msg).getDeliveryTag() - + ") more than once."); - } - - if (_logger.isInfoEnabled()) - { - _logger.info("Received Message(" + System.identityHashCode(msgindex) + ") " + "DT:" + dt + "IN:" + msgindex); - } - - if (dt == 0) - { - _logger.error("DT is zero for msg:" + msgindex); - } - - messageLog[msgindex] = dt; - - // get Next message - msg = consumer.receive(1000); - } - - _logger.info("consuming done."); - conn.getSession().commit(); - consumer.close(); - - int index = 0; - StringBuilder list = new StringBuilder(); - list.append("Failed to receive:"); - int failed = 0; - - _logger.info("consumed: " + messagesReceived); - - assertEquals("number of consumed messages does not match initial data", (int) numTestMessages, messagesReceived); - // wit 0_10 we can have a delivery tag of 0 - if (conn.isBroker08()) - { - for (long b : messageLog) - { - if ((b == 0) && (index != 0)) // delivery tag of zero shouldn't exist - { - _logger.error("Index: " + index + " was not received."); - list.append(" "); - list.append(index); - list.append(":"); - list.append(b); - failed++; - } - - index++; - } - - assertEquals(list.toString(), 0, failed); - } - - conn.disconnect(); - passed = true; - } - - /** multiple consumers - * Based on code subbmitted by client FT-304 - */ - public void testTwoCompetingConsumers() - { - Consumer c1 = new Consumer(); - Consumer c2 = new Consumer(); - Consumer c3 = new Consumer(); - Consumer c4 = new Consumer(); - - Thread t1 = new Thread(c1); - Thread t2 = new Thread(c2); - Thread t3 = new Thread(c3); - Thread t4 = new Thread(c4); - - t1.start(); - t2.start(); - t3.start(); - // t4.start(); - - try - { - t1.join(); - t2.join(); - t3.join(); - t4.join(); - } - catch (InterruptedException e) - { - fail("Unable to join to Consumer theads"); - } - - _logger.info("consumer 1 count is " + c1.getCount()); - _logger.info("consumer 2 count is " + c2.getCount()); - _logger.info("consumer 3 count is " + c3.getCount()); - _logger.info("consumer 4 count is " + c4.getCount()); - - Integer totalConsumed = c1.getCount() + c2.getCount() + c3.getCount() + c4.getCount(); - - // Check all messages were correctly delivered - int index = 0; - StringBuilder list = new StringBuilder(); - list.append("Failed to receive:"); - int failed = 0; - if (conn.isBroker08()) - { - for (long b : receieved) - { - if ((b == 0) && (index != 0)) // delivery tag of zero shouldn't exist (and we don't have msg 0) - { - _logger.error("Index: " + index + " was not received."); - list.append(" "); - list.append(index); - list.append(":"); - list.append(b); - failed++; - } - - index++; - } - - assertEquals(list.toString() + "-" + numTestMessages + "-" + totalConsumed, 0, failed); - } - assertEquals("number of consumed messages does not match initial data", numTestMessages, totalConsumed); - passed = true; - } - - class Consumer implements Runnable - { - private Integer count = 0; - private Integer id; - - public Consumer() - { - id = consumerIds.addAndGet(1); - } - - public void run() - { - try - { - _logger.info("consumer-" + id + ": starting"); - QpidClientConnection conn = new QpidClientConnection(BROKER); - - conn.connect(); - - _logger.info("consumer-" + id + ": connected, consuming..."); - Message result; - do - { - result = conn.getNextMessage(queue, consumeTimeout); - if (result != null) - { - - long dt = ((AbstractJMSMessage) result).getDeliveryTag(); - - if (testReception) - { - int msgindex = result.getIntProperty("index"); - if (receieved[msgindex] != 0) - { - _logger.error("Received Message(" + msgindex + ":" - + ((AbstractJMSMessage) result).getDeliveryTag() + ") more than once."); - } - - if (_logger.isInfoEnabled()) - { - _logger.info("Received Message(" + System.identityHashCode(msgindex) + ") " + "DT:" + dt - + "IN:" + msgindex); - } - - if (dt == 0) - { - _logger.error("DT is zero for msg:" + msgindex); - } - - receieved[msgindex] = dt; - } - - count++; - if ((count % 100) == 0) - { - _logger.info("consumer-" + id + ": got " + result + ", new count is " + count); - } - } - } - while (result != null); - - _logger.info("consumer-" + id + ": complete"); - conn.disconnect(); - - } - catch (Exception e) - { - e.printStackTrace(); - } - } - - public Integer getCount() - { - return count; - } - - public Integer getId() - { - return id; - } - } - - public void testRequeue() throws JMSException, AMQException, URLSyntaxException - { - int run = 0; - // while (run < 10) - { - run++; - - if (_logger.isInfoEnabled()) - { - _logger.info("testRequeue run " + run); - } - - String virtualHost = "/test"; - String brokerlist = BROKER; - String brokerUrl = "amqp://guest:guest@" + virtualHost + "?brokerlist='" + brokerlist + "'"; - QpidClientConnection qpc = new QpidClientConnection(BROKER); - qpc.connect(); - Connection conn = qpc. getConnection(); - - Session session = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE); - Queue q = session.createQueue(queue); - - _logger.debug("Create Consumer"); - MessageConsumer consumer = session.createConsumer(q); - - conn.start(); - - _logger.debug("Receiving msg"); - Message msg = consumer.receive(2000); - - assertNotNull("Message should not be null", msg); - - // As we have not ack'd message will be requeued. - _logger.debug("Close Consumer"); - consumer.close(); - - _logger.debug("Close Connection"); - conn.close(); - } - } - -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/close/TopicPublisherCloseTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/close/TopicPublisherCloseTest.java deleted file mode 100644 index 4957d700e6..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/close/TopicPublisherCloseTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * - * 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.qpid.test.unit.close; - -import javax.jms.Session; -import javax.jms.Topic; -import javax.jms.TopicPublisher; -import javax.jms.TopicSession; - -import junit.framework.TestCase; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.testutil.QpidTestCase; - -/** - * @author Apache Software Foundation - */ -public class TopicPublisherCloseTest extends QpidTestCase -{ - - protected void setUp() throws Exception - { - super.setUp(); - } - - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - public void testAllMethodsThrowAfterConnectionClose() throws Exception - { - // give external brokers a chance to start up - Thread.sleep(3000); - - AMQConnection connection = (AMQConnection) getConnection("guest", "guest"); - - Topic destination1 = new AMQTopic(connection, "t1"); - TopicSession session1 = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - TopicPublisher pub = session1.createPublisher(destination1); - connection.close(); - try - { - pub.getDeliveryMode(); - fail("Expected exception not thrown"); - } - catch (javax.jms.IllegalStateException e) - { - // PASS - } - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/ct/DurableSubscriberTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/ct/DurableSubscriberTest.java deleted file mode 100644 index 9caba63fe4..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/ct/DurableSubscriberTest.java +++ /dev/null @@ -1,167 +0,0 @@ -/* 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.qpid.test.unit.ct; - -import javax.jms.*; - -import org.apache.qpid.testutil.QpidTestCase; - -/** - * Crash Recovery tests for durable subscription - * - */ -public class DurableSubscriberTest extends QpidTestCase -{ - private final String _topicName = "durableSubscriberTopic"; - - /** - * test strategy: - * create and register a durable subscriber then close it - * create a publisher and send a persistant message followed by a non persistant message - * crash and restart the broker - * recreate the durable subscriber and check that only the first message is received - */ - public void testDurSubRestoredAfterNonPersistentMessageSent() throws Exception - { - if (!isBroker08()) - { - TopicConnectionFactory factory = getConnectionFactory(); - Topic topic = (Topic) getInitialContext().lookup(_topicName); - //create and register a durable subscriber then close it - TopicConnection durConnection = factory.createTopicConnection("guest", "guest"); - TopicSession durSession = durConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - TopicSubscriber durSub1 = durSession.createDurableSubscriber(topic, "dursub"); - durConnection.start(); - durSub1.close(); - durSession.close(); - durConnection.stop(); - - //create a publisher and send a persistant message followed by a non persistant message - TopicConnection pubConnection = factory.createTopicConnection("guest", "guest"); - TopicSession pubSession = pubConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - TopicPublisher publisher = pubSession.createPublisher(topic); - Message message = pubSession.createMessage(); - message.setIntProperty("count", 1); - publisher.publish(message, javax.jms.DeliveryMode.PERSISTENT, javax.jms.Message.DEFAULT_PRIORITY, - javax.jms.Message.DEFAULT_TIME_TO_LIVE); - message.setIntProperty("count", 2); - publisher.publish(message, javax.jms.DeliveryMode.NON_PERSISTENT, javax.jms.Message.DEFAULT_PRIORITY, - javax.jms.Message.DEFAULT_TIME_TO_LIVE); - publisher.close(); - pubSession.close(); - //now stop the server - try - { - shutdownServer(); - } - catch (Exception e) - { - System.out.println("problems shutting down arjuna-ms"); - throw e; - } - //now recreate the durable subscriber and check the received messages - factory = getConnectionFactory(); - topic = (Topic) getInitialContext().lookup(_topicName); - TopicConnection durConnection2 = factory.createTopicConnection("guest", "guest"); - TopicSession durSession2 = durConnection2.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - TopicSubscriber durSub2 = durSession2.createDurableSubscriber(topic, "dursub"); - durConnection2.start(); - Message m1 = durSub2.receive(1000); - if (m1 == null) - { - assertTrue("testDurSubRestoredAfterNonPersistentMessageSent test failed. no message was returned", - false); - } - assertTrue("testDurSubRestoredAfterNonPersistentMessageSent test failed. Wrong message was returned.", - m1.getIntProperty("count") == 1); - durSession2.unsubscribe("dursub"); - durConnection2.close(); - } - } - - /** - * create and register a durable subscriber with a message selector and then close it - * crash the broker - * create a publisher and send 5 right messages and 5 wrong messages - * recreate the durable subscriber and check the received the 5 expected messages - */ - public void testDurSubRestoresMessageSelector() throws Exception - { - if (!isBroker08()) - { - TopicConnectionFactory factory = getConnectionFactory(); - Topic topic = (Topic) getInitialContext().lookup(_topicName); - //create and register a durable subscriber with a message selector and then close it - TopicConnection durConnection = factory.createTopicConnection("guest", "guest"); - TopicSession durSession = durConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - TopicSubscriber durSub1 = durSession.createDurableSubscriber(topic, "dursub", "testprop='true'", false); - durConnection.start(); - durSub1.close(); - durSession.close(); - durConnection.stop(); - //now stop the server - try - { - shutdownServer(); - } - catch (Exception e) - { - System.out.println("problems shutting down arjuna-ms"); - throw e; - } - topic = (Topic) getInitialContext().lookup(_topicName); - factory = getConnectionFactory(); - TopicConnection pubConnection = factory.createTopicConnection("guest", "guest"); - TopicSession pubSession = pubConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - TopicPublisher publisher = pubSession.createPublisher(topic); - for (int i = 0; i < 5; i++) - { - Message message = pubSession.createMessage(); - message.setStringProperty("testprop", "true"); - publisher.publish(message); - message = pubSession.createMessage(); - message.setStringProperty("testprop", "false"); - publisher.publish(message); - } - publisher.close(); - pubSession.close(); - - //now recreate the durable subscriber and check the received messages - TopicConnection durConnection2 = factory.createTopicConnection("guest", "guest"); - TopicSession durSession2 = durConnection2.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - TopicSubscriber durSub2 = durSession2.createDurableSubscriber(topic, "dursub"); - durConnection2.start(); - for (int i = 0; i < 5; i++) - { - Message message = durSub2.receive(1000); - if (message == null) - { - assertTrue("testDurSubRestoresMessageSelector test failed. no message was returned", false); - } - else - { - assertTrue("testDurSubRestoresMessageSelector test failed. message selector not reset", - message.getStringProperty("testprop").equals("true")); - } - } - durSession2.unsubscribe("dursub"); - durConnection2.close(); - } - } -} - diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/message/JMSDestinationTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/message/JMSDestinationTest.java deleted file mode 100644 index 131cbd5f68..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/message/JMSDestinationTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - * 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.qpid.test.unit.message; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Connection; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.TextMessage; - -/** - * @author Apache Software Foundation - */ -public class JMSDestinationTest extends QpidTestCase -{ - private static final Logger _logger = LoggerFactory.getLogger(JMSDestinationTest.class); - - - protected void setUp() throws Exception - { - super.setUp(); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - public void testJMSDestination() throws Exception - { - AMQConnection con = (AMQConnection) getConnection("guest", "guest"); - AMQSession consumerSession = (AMQSession) con.createSession(false, Session.CLIENT_ACKNOWLEDGE); - Queue queue = - new AMQQueue(con.getDefaultQueueExchangeName(), new AMQShortString("someQ"), new AMQShortString("someQ"), false, - true); - MessageConsumer consumer = consumerSession.createConsumer(queue); - - Connection con2 = (AMQConnection) getConnection("guest", "guest"); - Session producerSession = con2.createSession(false, Session.CLIENT_ACKNOWLEDGE); - MessageProducer producer = producerSession.createProducer(queue); - - TextMessage sentMsg = producerSession.createTextMessage("hello"); - assertNull(sentMsg.getJMSDestination()); - - producer.send(sentMsg); - - assertEquals(sentMsg.getJMSDestination(), queue); - - con2.close(); - - con.start(); - - TextMessage rm = (TextMessage) consumer.receive(); - assertNotNull(rm); - - assertEquals(rm.getJMSDestination(), queue); - con.close(); - } - -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/message/JMSPropertiesTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/message/JMSPropertiesTest.java deleted file mode 100644 index 6883a09f1b..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/message/JMSPropertiesTest.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * - * 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.qpid.test.unit.message; - -import junit.framework.TestCase; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.message.NonQpidObjectMessage; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Destination; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.ObjectMessage; -import javax.jms.Queue; -import javax.jms.Session; -import java.util.Enumeration; - -/** - * @author Apache Software Foundation - */ -public class JMSPropertiesTest extends QpidTestCase -{ - - private static final Logger _logger = LoggerFactory.getLogger(JMSPropertiesTest.class); - - public String _connectionString = "vm://:1"; - - public static final String JMS_CORR_ID = "QPIDID_01"; - public static final int JMS_DELIV_MODE = 1; - public static final String JMS_TYPE = "test.jms.type"; - - protected void setUp() throws Exception - { - super.setUp(); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - public void testJMSProperties() throws Exception - { - AMQConnection con = (AMQConnection) getConnection("guest", "guest"); - AMQSession consumerSession = (AMQSession) con.createSession(false, Session.CLIENT_ACKNOWLEDGE); - Queue queue = - new AMQQueue(con.getDefaultQueueExchangeName(), new AMQShortString("someQ"), new AMQShortString("someQ"), false, - true); - MessageConsumer consumer = consumerSession.createConsumer(queue); - - AMQConnection con2 = (AMQConnection) getConnection("guest", "guest"); - Session producerSession = con2.createSession(false, Session.CLIENT_ACKNOWLEDGE); - MessageProducer producer = producerSession.createProducer(queue); - Destination JMS_REPLY_TO = new AMQQueue(con2, "my.replyto"); - // create a test message to send - ObjectMessage sentMsg = new NonQpidObjectMessage(); - sentMsg.setJMSCorrelationID(JMS_CORR_ID); - sentMsg.setJMSDeliveryMode(JMS_DELIV_MODE); - sentMsg.setJMSType(JMS_TYPE); - sentMsg.setJMSReplyTo(JMS_REPLY_TO); - - String JMSXGroupID_VALUE = "group"; - sentMsg.setStringProperty("JMSXGroupID", JMSXGroupID_VALUE); - - int JMSXGroupSeq_VALUE = 1; - sentMsg.setIntProperty("JMSXGroupSeq", JMSXGroupSeq_VALUE); - - // send it - producer.send(sentMsg); - - con2.close(); - - con.start(); - - // get message and check JMS properties - ObjectMessage rm = (ObjectMessage) consumer.receive(2000); - assertNotNull(rm); - - assertEquals("JMS Correlation ID mismatch", sentMsg.getJMSCorrelationID(), rm.getJMSCorrelationID()); - // TODO: Commented out as always overwritten by send delivery mode value - prob should not set in conversion - // assertEquals("JMS Delivery Mode mismatch",sentMsg.getJMSDeliveryMode(),rm.getJMSDeliveryMode()); - assertEquals("JMS Type mismatch", sentMsg.getJMSType(), rm.getJMSType()); - assertEquals("JMS Reply To mismatch", sentMsg.getJMSReplyTo(), rm.getJMSReplyTo()); - assertTrue("JMSMessageID Does not start ID:", rm.getJMSMessageID().startsWith("ID:")); - - //Validate that the JMSX values are correct - assertEquals("JMSXGroupID is not as expected:", JMSXGroupID_VALUE, rm.getStringProperty("JMSXGroupID")); - assertEquals("JMSXGroupSeq is not as expected:", JMSXGroupSeq_VALUE, rm.getIntProperty("JMSXGroupSeq")); - - boolean JMSXGroupID_Available = false; - boolean JMSXGroupSeq_Available = false; - Enumeration props = con.getMetaData().getJMSXPropertyNames(); - while (props.hasMoreElements()) - { - String name = (String) props.nextElement(); - if (name.equals("JMSXGroupID")) - { - JMSXGroupID_Available = true; - } - if (name.equals("JMSXGroupSeq")) - { - JMSXGroupSeq_Available = true; - } - } - - assertTrue("JMSXGroupID not available.",JMSXGroupID_Available); - assertTrue("JMSXGroupSeq not available.",JMSXGroupSeq_Available); - - con.close(); - } - -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/message/MessageConverterTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/message/MessageConverterTest.java index fd425b9930..b5e7ae82b5 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/message/MessageConverterTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/message/MessageConverterTest.java @@ -20,20 +20,20 @@ */ package org.apache.qpid.test.unit.message; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.MapMessage; -import javax.jms.Message; -import javax.jms.TextMessage; +import javax.jms.*; import junit.framework.TestCase; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.message.AbstractJMSMessage; -import org.apache.qpid.client.message.JMSMapMessage; -import org.apache.qpid.client.message.JMSTextMessage; -import org.apache.qpid.client.message.MessageConverter; +import org.apache.qpid.client.*; +import org.apache.qpid.client.protocol.AMQProtocolHandler; +import org.apache.qpid.client.failover.FailoverException; +import org.apache.qpid.client.message.*; import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.AMQException; + +import java.util.Map; public class MessageConverterTest extends TestCase @@ -47,36 +47,38 @@ public class MessageConverterTest extends TestCase protected JMSTextMessage testTextMessage; protected JMSMapMessage testMapMessage; + private AMQSession _session = new TestAMQSession(); + protected void setUp() throws Exception { super.setUp(); - testTextMessage = new JMSTextMessage(); + testTextMessage = new JMSTextMessage(AMQMessageDelegateFactory.FACTORY_0_8); //Set Message Text testTextMessage.setText("testTextMessage text"); setMessageProperties(testTextMessage); - testMapMessage = new JMSMapMessage(); + testMapMessage = new JMSMapMessage(AMQMessageDelegateFactory.FACTORY_0_8); testMapMessage.setString("testMapString", "testMapStringValue"); testMapMessage.setDouble("testMapDouble", Double.MAX_VALUE); } public void testSetProperties() throws Exception { - AbstractJMSMessage newMessage = new MessageConverter((TextMessage) testTextMessage).getConvertedMessage(); + AbstractJMSMessage newMessage = new MessageConverter(_session, (TextMessage) testTextMessage).getConvertedMessage(); mesagePropertiesTest(testTextMessage, newMessage); } public void testJMSTextMessageConversion() throws Exception { - AbstractJMSMessage newMessage = new MessageConverter((TextMessage) testTextMessage).getConvertedMessage(); + AbstractJMSMessage newMessage = new MessageConverter(_session, (TextMessage) testTextMessage).getConvertedMessage(); assertEquals("Converted message text mismatch", ((JMSTextMessage) newMessage).getText(), testTextMessage.getText()); } public void testJMSMapMessageConversion() throws Exception { - AbstractJMSMessage newMessage = new MessageConverter((MapMessage) testMapMessage).getConvertedMessage(); + AbstractJMSMessage newMessage = new MessageConverter(_session, (MapMessage) testMapMessage).getConvertedMessage(); assertEquals("Converted map message String mismatch", ((JMSMapMessage) newMessage).getString("testMapString"), testMapMessage.getString("testMapString")); assertEquals("Converted map message Double mismatch", ((JMSMapMessage) newMessage).getDouble("testMapDouble"), diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/message/StreamMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/message/StreamMessageTest.java deleted file mode 100644 index d9d078a01d..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/message/StreamMessageTest.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * - * 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.qpid.test.unit.message; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQHeadersExchange; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.exchange.ExchangeDefaults; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.url.AMQBindingURL; -import org.apache.qpid.url.BindingURL; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Connection; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageEOFException; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.Session; -import javax.jms.StreamMessage; - -/** - * @author Apache Software Foundation - */ -public class StreamMessageTest extends QpidTestCase -{ - - private static final Logger _logger = LoggerFactory.getLogger(StreamMessageTest.class); - - public String _connectionString = "vm://:1"; - - protected void setUp() throws Exception - { - super.setUp(); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - public void testStreamMessageEOF() throws Exception - { - Connection con = (AMQConnection) getConnection("guest", "guest"); - AMQSession consumerSession = (AMQSession) con.createSession(false, Session.CLIENT_ACKNOWLEDGE); - - AMQHeadersExchange queue = - new AMQHeadersExchange(new AMQBindingURL( - ExchangeDefaults.HEADERS_EXCHANGE_CLASS + "://" + ExchangeDefaults.HEADERS_EXCHANGE_NAME - + "/test/queue1?" + BindingURL.OPTION_ROUTING_KEY + "='F0000=1'")); - FieldTable ft = new FieldTable(); - ft.setString("F1000", "1"); - MessageConsumer consumer = - consumerSession.createConsumer(queue, AMQSession.DEFAULT_PREFETCH_LOW_MARK, - AMQSession.DEFAULT_PREFETCH_HIGH_MARK, false, false, (String) null, ft); - - // force synch to ensure the consumer has resulted in a bound queue - // ((AMQSession) consumerSession).declareExchangeSynch(ExchangeDefaults.HEADERS_EXCHANGE_NAME, ExchangeDefaults.HEADERS_EXCHANGE_CLASS); - // This is the default now - - Connection con2 = (AMQConnection) getConnection("guest", "guest"); - - AMQSession producerSession = (AMQSession) con2.createSession(false, Session.CLIENT_ACKNOWLEDGE); - - // Need to start the "producer" connection in order to receive bounced messages - _logger.info("Starting producer connection"); - con2.start(); - - MessageProducer mandatoryProducer = producerSession.createProducer(queue); - - // Third test - should be routed - _logger.info("Sending isBound message"); - StreamMessage msg = producerSession.createStreamMessage(); - - msg.setStringProperty("F1000", "1"); - - msg.writeByte((byte) 42); - - mandatoryProducer.send(msg); - - _logger.info("Starting consumer connection"); - con.start(); - - StreamMessage msg2 = (StreamMessage) consumer.receive(); - - msg2.readByte(); - try - { - msg2.readByte(); - } - catch (Exception e) - { - assertTrue("Expected MessageEOFException: " + e, e instanceof MessageEOFException); - } - con.close(); - con2.close(); - } - - public void testModifyReceivedMessageExpandsBuffer() throws Exception - { - AMQConnection con = (AMQConnection) getConnection("guest", "guest"); - AMQSession consumerSession = (AMQSession) con.createSession(false, Session.CLIENT_ACKNOWLEDGE); - AMQQueue queue = new AMQQueue(con.getDefaultQueueExchangeName(), new AMQShortString("testQ")); - MessageConsumer consumer = consumerSession.createConsumer(queue); - consumer.setMessageListener(new MessageListener() - { - - public void onMessage(Message message) - { - StreamMessage sm = (StreamMessage) message; - try - { - sm.clearBody(); - sm.writeString("dfgjshfslfjshflsjfdlsjfhdsljkfhdsljkfhsd"); - } - catch (JMSException e) - { - _logger.error("Error when writing large string to received msg: " + e, e); - fail("Error when writing large string to received msg" + e); - } - } - }); - - Connection con2 = (AMQConnection) getConnection("guest", "guest"); - AMQSession producerSession = (AMQSession) con2.createSession(false, Session.CLIENT_ACKNOWLEDGE); - MessageProducer mandatoryProducer = producerSession.createProducer(queue); - con.start(); - StreamMessage sm = producerSession.createStreamMessage(); - sm.writeInt(42); - mandatoryProducer.send(sm); - Thread.sleep(2000); - con.close(); - con2.close(); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java b/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java new file mode 100644 index 0000000000..a881f6a822 --- /dev/null +++ b/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java @@ -0,0 +1,171 @@ +/* + * + * 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.qpid.test.unit.message; + +import org.apache.qpid.client.*; +import org.apache.qpid.client.message.AMQMessageDelegateFactory; +import org.apache.qpid.client.protocol.AMQProtocolHandler; +import org.apache.qpid.client.failover.FailoverException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.AMQException; + +import javax.jms.*; +import java.util.Map; + +public class TestAMQSession extends AMQSession<BasicMessageConsumer_0_8, BasicMessageProducer_0_8> +{ + + public TestAMQSession() + { + super(null, 0, false, AUTO_ACKNOWLEDGE, null, 0, 0); + } + + public void acknowledgeMessage(long deliveryTag, boolean multiple) + { + + } + + public void sendQueueBind(AMQShortString queueName, AMQShortString routingKey, FieldTable arguments, AMQShortString exchangeName, AMQDestination destination) throws AMQException, FailoverException + { + + } + + public void sendClose(long timeout) throws AMQException, FailoverException + { + + } + + public void sendCommit() throws AMQException, FailoverException + { + + } + + public TopicSubscriber createDurableSubscriber(Topic topic, String name) throws JMSException + { + return null; + } + + public void sendCreateQueue(AMQShortString name, boolean autoDelete, boolean durable, boolean exclusive, Map<String, Object> arguments) throws AMQException, FailoverException + { + + } + + public TemporaryQueue createTemporaryQueue() throws JMSException + { + return null; + } + + protected void sendRecover() throws AMQException, FailoverException + { + + } + + public void rejectMessage(long deliveryTag, boolean requeue) + { + + } + + public void releaseForRollback() + { + + } + + public void sendRollback() throws AMQException, FailoverException + { + + } + + public BasicMessageConsumer_0_8 createMessageConsumer(AMQDestination destination, int prefetchHigh, int prefetchLow, boolean noLocal, boolean exclusive, String selector, FieldTable arguments, boolean noConsume, boolean autoClose) throws JMSException + { + return null; + } + + public boolean isQueueBound(AMQShortString exchangeName, AMQShortString queueName, AMQShortString routingKey) throws JMSException + { + return false; + } + + public boolean isQueueBound(AMQDestination destination) throws JMSException + { + return false; + } + + public void sendConsume(BasicMessageConsumer_0_8 consumer, AMQShortString queueName, AMQProtocolHandler protocolHandler, boolean nowait, String messageSelector, int tag) throws AMQException, FailoverException + { + + } + + public BasicMessageProducer_0_8 createMessageProducer(Destination destination, boolean mandatory, boolean immediate, boolean waitUntilSent, long producerId) + { + return null; + } + + protected Long requestQueueDepth(AMQDestination amqd) throws AMQException, FailoverException + { + return null; + } + + public void sendExchangeDeclare(AMQShortString name, AMQShortString type, AMQProtocolHandler protocolHandler, boolean nowait) throws AMQException, FailoverException + { + + } + + public void sendQueueDeclare(AMQDestination amqd, AMQProtocolHandler protocolHandler) throws AMQException, FailoverException + { + + } + + public void sendQueueDelete(AMQShortString queueName) throws AMQException, FailoverException + { + + } + + public void sendSuspendChannel(boolean suspend) throws AMQException, FailoverException + { + + } + + protected boolean tagLE(long tag1, long tag2) + { + return false; + } + + protected boolean updateRollbackMark(long current, long deliveryTag) + { + return false; + } + + public AMQMessageDelegateFactory getMessageDelegateFactory() + { + return AMQMessageDelegateFactory.FACTORY_0_8; + } + + protected Object getFailoverMutex() + { + return this; + } + + public void checkNotClosed() + { + + } +} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java deleted file mode 100644 index 6856ad34fb..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java +++ /dev/null @@ -1,353 +0,0 @@ -/* - * - * 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.qpid.test.unit.topic; - -import junit.framework.TestCase; - -import org.apache.qpid.AMQException; -import org.apache.qpid.testutil.QpidTestCase; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.url.URLSyntaxException; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Connection; -import javax.jms.InvalidDestinationException; -import javax.jms.InvalidSelectorException; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Session; -import javax.jms.TextMessage; -import javax.jms.TopicSubscriber; - -/** - * @todo Code to check that a consumer gets only one particular method could be factored into a re-usable method (as - * a static on a base test helper class, e.g. TestUtils. - * - * @todo Code to create test end-points using session per connection, or all sessions on one connection, to be factored - * out to make creating this test variation simpler. Want to make this variation available through LocalCircuit, - * driven by the test model. - */ -public class DurableSubscriptionTest extends QpidTestCase -{ - private static final Logger _logger = LoggerFactory.getLogger(DurableSubscriptionTest.class); - - protected void setUp() throws Exception - { - super.setUp(); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - public void testUnsubscribe() throws Exception - { - AMQConnection con = (AMQConnection) getConnection("guest", "guest"); - AMQTopic topic = new AMQTopic(con, "MyDurableSubscriptionTestTopic"); - _logger.info("Create Session 1"); - Session session1 = con.createSession(false, AMQSession.NO_ACKNOWLEDGE); - _logger.info("Create Consumer on Session 1"); - MessageConsumer consumer1 = session1.createConsumer(topic); - _logger.info("Create Producer on Session 1"); - MessageProducer producer = session1.createProducer(topic); - - _logger.info("Create Session 2"); - Session session2 = con.createSession(false, AMQSession.NO_ACKNOWLEDGE); - _logger.info("Create Durable Subscriber on Session 2"); - TopicSubscriber consumer2 = session2.createDurableSubscriber(topic, "MySubscription"); - - _logger.info("Starting connection"); - con.start(); - - _logger.info("Producer sending message A"); - producer.send(session1.createTextMessage("A")); - - Message msg; - _logger.info("Receive message on consumer 1:expecting A"); - msg = consumer1.receive(); - assertEquals("A", ((TextMessage) msg).getText()); - _logger.info("Receive message on consumer 1 :expecting null"); - msg = consumer1.receive(1000); - assertEquals(null, msg); - - _logger.info("Receive message on consumer 1:expecting A"); - msg = consumer2.receive(); - assertEquals("A", ((TextMessage) msg).getText()); - msg = consumer2.receive(1000); - _logger.info("Receive message on consumer 1 :expecting null"); - assertEquals(null, msg); - - _logger.info("Unsubscribe session2/consumer2"); - session2.unsubscribe("MySubscription"); - - _logger.info("Producer sending message B"); - producer.send(session1.createTextMessage("B")); - - _logger.info("Receive message on consumer 1 :expecting B"); - msg = consumer1.receive(); - assertEquals("B", ((TextMessage) msg).getText()); - _logger.info("Receive message on consumer 1 :expecting null"); - msg = consumer1.receive(1000); - assertEquals(null, msg); - - _logger.info("Receive message on consumer 2 :expecting null"); - msg = consumer2.receive(1000); - assertEquals(null, msg); - - _logger.info("Close connection"); - con.close(); - } - - public void testDurabilityAUTOACK() throws Exception - { - durabilityImpl(Session.AUTO_ACKNOWLEDGE); - } - - public void testDurabilityNOACKSessionPerConnection() throws Exception - { - durabilityImplSessionPerConnection(AMQSession.NO_ACKNOWLEDGE); - } - - public void testDurabilityAUTOACKSessionPerConnection() throws Exception - { - durabilityImplSessionPerConnection(Session.AUTO_ACKNOWLEDGE); - } - - private void durabilityImpl(int ackMode) throws Exception - { - AMQConnection con = (AMQConnection) getConnection("guest", "guest"); - AMQTopic topic = new AMQTopic(con, "MyTopic"); - Session session1 = con.createSession(false, ackMode); - MessageConsumer consumer1 = session1.createConsumer(topic); - - Session sessionProd = con.createSession(false, AMQSession.NO_ACKNOWLEDGE); - MessageProducer producer = sessionProd.createProducer(topic); - - Session session2 = con.createSession(false, AMQSession.NO_ACKNOWLEDGE); - TopicSubscriber consumer2 = session2.createDurableSubscriber(topic, "MySubscription"); - - con.start(); - - producer.send(session1.createTextMessage("A")); - - Message msg; - msg = consumer1.receive(); - assertEquals("A", ((TextMessage) msg).getText()); - msg = consumer1.receive(1000); - assertEquals(null, msg); - - msg = consumer2.receive(); - assertEquals("A", ((TextMessage) msg).getText()); - msg = consumer2.receive(1000); - assertEquals(null, msg); - - consumer2.close(); - - producer.send(session1.createTextMessage("B")); - - _logger.info("Receive message on consumer 1 :expecting B"); - msg = consumer1.receive(500); - assertNotNull("Consumer 1 should get message 'B'.", msg); - assertEquals("Incorrect Message recevied on consumer1.", "B", ((TextMessage) msg).getText()); - _logger.info("Receive message on consumer 1 :expecting null"); - msg = consumer1.receive(500); - assertNull("There should be no more messages for consumption on consumer1.", msg); - - Session session3 = con.createSession(false, ackMode); - MessageConsumer consumer3 = session3.createDurableSubscriber(topic, "MySubscription"); - - _logger.info("Receive message on consumer 3 :expecting B"); - msg = consumer3.receive(500); - assertNotNull("Consumer 3 should get message 'B'.", msg); - assertEquals("Incorrect Message recevied on consumer4.", "B", ((TextMessage) msg).getText()); - _logger.info("Receive message on consumer 3 :expecting null"); - msg = consumer3.receive(500); - assertNull("There should be no more messages for consumption on consumer3.", msg); - - consumer1.close(); - consumer3.close(); - - con.close(); - } - - private void durabilityImplSessionPerConnection(int ackMode) throws Exception - { - Message msg; - // Create producer. - AMQConnection con0 = (AMQConnection) getConnection("guest", "guest"); - con0.start(); - Session session0 = con0.createSession(false, ackMode); - - AMQTopic topic = new AMQTopic(con0, "MyTopic"); - - Session sessionProd = con0.createSession(false, ackMode); - MessageProducer producer = sessionProd.createProducer(topic); - - // Create consumer 1. - AMQConnection con1 = (AMQConnection) getConnection("guest", "guest"); - con1.start(); - Session session1 = con1.createSession(false, ackMode); - - MessageConsumer consumer1 = session0.createConsumer(topic); - - // Create consumer 2. - AMQConnection con2 = (AMQConnection) getConnection("guest", "guest"); - con2.start(); - Session session2 = con2.createSession(false, ackMode); - - TopicSubscriber consumer2 = session2.createDurableSubscriber(topic, "MySubscription"); - - // Send message and check that both consumers get it and only it. - producer.send(session0.createTextMessage("A")); - - msg = consumer1.receive(500); - assertNotNull("Message should be available", msg); - assertEquals("Message Text doesn't match", "A", ((TextMessage) msg).getText()); - msg = consumer1.receive(500); - assertNull("There should be no more messages for consumption on consumer1.", msg); - - msg = consumer2.receive(); - assertNotNull(msg); - assertEquals("Consumer 2 should also received the first msg.", "A", ((TextMessage) msg).getText()); - msg = consumer2.receive(500); - assertNull("There should be no more messages for consumption on consumer2.", msg); - - // Detach the durable subscriber. - consumer2.close(); - session2.close(); - con2.close(); - - // Send message and receive on open consumer. - producer.send(session0.createTextMessage("B")); - - _logger.info("Receive message on consumer 1 :expecting B"); - msg = consumer1.receive(1000); - assertEquals("B", ((TextMessage) msg).getText()); - _logger.info("Receive message on consumer 1 :expecting null"); - msg = consumer1.receive(1000); - assertEquals(null, msg); - - // Re-attach a new consumer to the durable subscription, and check that it gets the message that it missed. - AMQConnection con3 = (AMQConnection) getConnection("guest", "guest"); - con3.start(); - Session session3 = con3.createSession(false, ackMode); - - TopicSubscriber consumer3 = session3.createDurableSubscriber(topic, "MySubscription"); - - _logger.info("Receive message on consumer 3 :expecting B"); - msg = consumer3.receive(500); - assertNotNull("Consumer 3 should get message 'B'.", msg); - assertEquals("Incorrect Message recevied on consumer4.", "B", ((TextMessage) msg).getText()); - _logger.info("Receive message on consumer 3 :expecting null"); - msg = consumer3.receive(500); - assertNull("There should be no more messages for consumption on consumer3.", msg); - - consumer1.close(); - consumer3.close(); - - con0.close(); - con1.close(); - con3.close(); - } - - /*** - * This tests the fix for QPID-1085 - * Creates a durable subscriber with an invalid selector, checks that the - * exception is thrown correctly and that the subscription is not created. - * @throws Exception - */ - public void testDurableWithInvalidSelector() throws Exception - { - Connection conn = getConnection(); - conn.start(); - Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - AMQTopic topic = new AMQTopic((AMQConnection) conn, "MyTestDurableWithInvalidSelectorTopic"); - MessageProducer producer = session.createProducer(topic); - producer.send(session.createTextMessage("testDurableWithInvalidSelector1")); - try - { - TopicSubscriber deadSubscriber = session.createDurableSubscriber(topic, "testDurableWithInvalidSelectorSub", - "=TEST 'test", true); - assertNull("Subscriber should not have been created", deadSubscriber); - } - catch (InvalidSelectorException e) - { - // This was expected - } - - TopicSubscriber liveSubscriber = session.createDurableSubscriber(topic, "testDurableWithInvalidSelectorSub"); - assertNotNull("Subscriber should have been created", liveSubscriber); - - producer.send(session.createTextMessage("testDurableWithInvalidSelector2")); - - Message msg = liveSubscriber.receive(); - assertNotNull ("Message should have been received", msg); - assertEquals ("testDurableWithInvalidSelector2", ((TextMessage) msg).getText()); - assertNull("Should not receive subsequent message", liveSubscriber.receive(200)); - } - - /*** - * This tests the fix for QPID-1085 - * Creates a durable subscriber with an invalid destination, checks that the - * exception is thrown correctly and that the subscription is not created. - * @throws Exception - */ - public void testDurableWithInvalidDestination() throws Exception - { - Connection conn = getConnection(); - conn.start(); - Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - AMQTopic topic = new AMQTopic((AMQConnection) conn, "testDurableWithInvalidDestinationTopic"); - try - { - TopicSubscriber deadSubscriber = session.createDurableSubscriber(null, "testDurableWithInvalidDestinationsub"); - assertNull("Subscriber should not have been created", deadSubscriber); - } - catch (InvalidDestinationException e) - { - // This was expected - } - MessageProducer producer = session.createProducer(topic); - producer.send(session.createTextMessage("testDurableWithInvalidSelector1")); - - TopicSubscriber liveSubscriber = session.createDurableSubscriber(topic, "testDurableWithInvalidDestinationsub"); - assertNotNull("Subscriber should have been created", liveSubscriber); - - producer.send(session.createTextMessage("testDurableWithInvalidSelector2")); - Message msg = liveSubscriber.receive(); - assertNotNull ("Message should have been received", msg); - assertEquals ("testDurableWithInvalidSelector2", ((TextMessage) msg).getText()); - assertNull("Should not receive subsequent message", liveSubscriber.receive(200)); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(DurableSubscriptionTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/topic/TopicPublisherTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/topic/TopicPublisherTest.java deleted file mode 100644 index 4f0f0dbaa9..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/topic/TopicPublisherTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * - * 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.qpid.test.unit.topic; - -import javax.jms.MessageConsumer; -import javax.jms.TextMessage; -import javax.jms.TopicPublisher; -import javax.jms.TopicSession; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.testutil.QpidTestCase; - -/** - * @author Apache Software Foundation - */ -public class TopicPublisherTest extends QpidTestCase -{ - protected void setUp() throws Exception - { - super.setUp(); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - public void testUnidentifiedProducer() throws Exception - { - - AMQConnection con = (AMQConnection) getConnection("guest", "guest"); - AMQTopic topic = new AMQTopic(con,"MyTopic"); - TopicSession session1 = con.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); - TopicPublisher publisher = session1.createPublisher(null); - MessageConsumer consumer1 = session1.createConsumer(topic); - con.start(); - publisher.publish(topic, session1.createTextMessage("Hello")); - TextMessage m = (TextMessage) consumer1.receive(2000); - assertNotNull(m); - try - { - publisher.publish(session1.createTextMessage("Goodbye")); - fail("Did not throw UnsupportedOperationException"); - } - catch (UnsupportedOperationException e) - { - // PASS - } - con.close(); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(TopicPublisherTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/topic/TopicSessionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/topic/TopicSessionTest.java deleted file mode 100644 index 0ff3455624..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/topic/TopicSessionTest.java +++ /dev/null @@ -1,373 +0,0 @@ -/* - * - * 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.qpid.test.unit.topic; - -import javax.jms.InvalidDestinationException; -import javax.jms.JMSException; -import javax.jms.MessageConsumer; -import javax.jms.Session; -import javax.jms.TemporaryTopic; -import javax.jms.TextMessage; -import javax.jms.TopicPublisher; -import javax.jms.TopicSession; -import javax.jms.TopicSubscriber; - -import junit.framework.TestCase; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.testutil.QpidTestCase; - - -/** @author Apache Software Foundation */ -public class TopicSessionTest extends QpidTestCase -{ - - protected void setUp() throws Exception - { - super.setUp(); - } - - protected void tearDown() throws Exception - { - super.tearDown(); - } - - - public void testTopicSubscriptionUnsubscription() throws Exception - { - - AMQConnection con = (AMQConnection) getConnection("guest", "guest"); - AMQTopic topic = new AMQTopic(con.getDefaultTopicExchangeName(), "MyTopic"); - TopicSession session1 = con.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); - TopicSubscriber sub = session1.createDurableSubscriber(topic, "subscription0"); - TopicPublisher publisher = session1.createPublisher(topic); - - con.start(); - - TextMessage tm = session1.createTextMessage("Hello"); - publisher.publish(tm); - - tm = (TextMessage) sub.receive(2000); - assertNotNull(tm); - - session1.unsubscribe("subscription0"); - - try - { - session1.unsubscribe("not a subscription"); - fail("expected InvalidDestinationException when unsubscribing from unknown subscription"); - } - catch (InvalidDestinationException e) - { - ; // PASS - } - catch (Exception e) - { - fail("expected InvalidDestinationException when unsubscribing from unknown subscription, got: " + e); - } - - con.close(); - } - - public void testSubscriptionNameReuseForDifferentTopicSingleConnection() throws Exception - { - subscriptionNameReuseForDifferentTopic(false); - } - - public void testSubscriptionNameReuseForDifferentTopicTwoConnections() throws Exception - { - subscriptionNameReuseForDifferentTopic(true); - } - - private void subscriptionNameReuseForDifferentTopic(boolean shutdown) throws Exception - { - AMQConnection con = (AMQConnection) getConnection("guest", "guest"); - AMQTopic topic = new AMQTopic(con, "MyTopic1" + String.valueOf(shutdown)); - AMQTopic topic2 = new AMQTopic(con, "MyOtherTopic1" + String.valueOf(shutdown)); - - TopicSession session1 = con.createTopicSession(false, AMQSession.AUTO_ACKNOWLEDGE); - TopicSubscriber sub = session1.createDurableSubscriber(topic, "subscription0"); - TopicPublisher publisher = session1.createPublisher(null); - - con.start(); - - publisher.publish(topic, session1.createTextMessage("hello")); - TextMessage m = (TextMessage) sub.receive(2000); - assertNotNull(m); - - if (shutdown) - { - session1.close(); - con.close(); - con = (AMQConnection) getConnection("guest", "guest"); - con.start(); - session1 = con.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); - publisher = session1.createPublisher(null); - } - TopicSubscriber sub2 = session1.createDurableSubscriber(topic2, "subscription0"); - publisher.publish(topic, session1.createTextMessage("hello")); - if (!shutdown) - { - m = (TextMessage) sub.receive(2000); - assertNull(m); - } - publisher.publish(topic2, session1.createTextMessage("goodbye")); - m = (TextMessage) sub2.receive(2000); - assertNotNull(m); - assertEquals("goodbye", m.getText()); - con.close(); - } - - public void testUnsubscriptionAfterConnectionClose() throws Exception - { - AMQConnection con1 = (AMQConnection) getConnection("guest", "guest"); - AMQTopic topic = new AMQTopic(con1, "MyTopic3"); - - TopicSession session1 = con1.createTopicSession(false, AMQSession.AUTO_ACKNOWLEDGE); - TopicPublisher publisher = session1.createPublisher(topic); - - AMQConnection con2 = (AMQConnection) getConnection("guest", "guest"); - TopicSession session2 = con2.createTopicSession(false, AMQSession.AUTO_ACKNOWLEDGE); - TopicSubscriber sub = session2.createDurableSubscriber(topic, "subscription0"); - - con2.start(); - - publisher.publish(session1.createTextMessage("Hello")); - TextMessage tm = (TextMessage) sub.receive(2000); - assertNotNull(tm); - con2.close(); - publisher.publish(session1.createTextMessage("Hello2")); - con2 = (AMQConnection) getConnection("guest", "guest"); - session2 = con2.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); - sub = session2.createDurableSubscriber(topic, "subscription0"); - con2.start(); - tm = (TextMessage) sub.receive(2000); - assertNotNull(tm); - assertEquals("Hello2", tm.getText()); - con1.close(); - con2.close(); - } - - public void testTextMessageCreation() throws Exception - { - - AMQConnection con = (AMQConnection) getConnection("guest", "guest"); - AMQTopic topic = new AMQTopic(con, "MyTopic4"); - TopicSession session1 = con.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); - TopicPublisher publisher = session1.createPublisher(topic); - MessageConsumer consumer1 = session1.createConsumer(topic); - con.start(); - TextMessage tm = session1.createTextMessage("Hello"); - publisher.publish(tm); - tm = (TextMessage) consumer1.receive(10000L); - assertNotNull(tm); - String msgText = tm.getText(); - assertEquals("Hello", msgText); - tm = session1.createTextMessage(); - msgText = tm.getText(); - assertNull(msgText); - publisher.publish(tm); - tm = (TextMessage) consumer1.receive(10000L); - assertNotNull(tm); - msgText = tm.getText(); - assertNull(msgText); - tm.clearBody(); - tm.setText("Now we are not null"); - publisher.publish(tm); - tm = (TextMessage) consumer1.receive(2000); - assertNotNull(tm); - msgText = tm.getText(); - assertEquals("Now we are not null", msgText); - - tm = session1.createTextMessage(""); - msgText = tm.getText(); - assertEquals("Empty string not returned", "", msgText); - publisher.publish(tm); - tm = (TextMessage) consumer1.receive(2000); - assertNotNull(tm); - assertEquals("Empty string not returned", "", msgText); - con.close(); - } - - public void testSendingSameMessage() throws Exception - { - AMQConnection conn = (AMQConnection) getConnection("guest", "guest"); - TopicSession session = conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - TemporaryTopic topic = session.createTemporaryTopic(); - assertNotNull(topic); - TopicPublisher producer = session.createPublisher(topic); - MessageConsumer consumer = session.createConsumer(topic); - conn.start(); - TextMessage sentMessage = session.createTextMessage("Test Message"); - producer.send(sentMessage); - TextMessage receivedMessage = (TextMessage) consumer.receive(2000); - assertNotNull(receivedMessage); - assertEquals(sentMessage.getText(), receivedMessage.getText()); - producer.send(sentMessage); - receivedMessage = (TextMessage) consumer.receive(2000); - assertNotNull(receivedMessage); - assertEquals(sentMessage.getText(), receivedMessage.getText()); - - conn.close(); - - } - - public void testTemporaryTopic() throws Exception - { - AMQConnection conn = (AMQConnection) getConnection("guest", "guest"); - TopicSession session = conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - TemporaryTopic topic = session.createTemporaryTopic(); - assertNotNull(topic); - TopicPublisher producer = session.createPublisher(topic); - MessageConsumer consumer = session.createConsumer(topic); - conn.start(); - producer.send(session.createTextMessage("hello")); - TextMessage tm = (TextMessage) consumer.receive(2000); - assertNotNull(tm); - assertEquals("hello", tm.getText()); - - try - { - topic.delete(); - fail("Expected JMSException : should not be able to delete while there are active consumers"); - } - catch (JMSException je) - { - ; //pass - } - - consumer.close(); - - try - { - topic.delete(); - } - catch (JMSException je) - { - fail("Unexpected Exception: " + je.getMessage()); - } - - TopicSession session2 = conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - try - { - session2.createConsumer(topic); - fail("Expected a JMSException when subscribing to a temporary topic created on adifferent session"); - } - catch (JMSException je) - { - ; // pass - } - - - conn.close(); - } - - - public void testNoLocal() throws Exception - { - - AMQConnection con = (AMQConnection) getConnection("guest", "guest"); - - AMQTopic topic = new AMQTopic(con, "testNoLocal"); - - TopicSession session1 = con.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); - TopicSubscriber noLocal = session1.createSubscriber(topic, "", true); - TopicSubscriber select = session1.createSubscriber(topic, "Selector = 'select'", false); - TopicSubscriber normal = session1.createSubscriber(topic); - - TopicPublisher publisher = session1.createPublisher(topic); - - con.start(); - TextMessage m; - TextMessage message; - - //send message to all consumers - publisher.publish(session1.createTextMessage("hello-new2")); - - //test normal subscriber gets message - m = (TextMessage) normal.receive(1000); - assertNotNull(m); - - //test selector subscriber doesn't message - m = (TextMessage) select.receive(1000); - assertNull(m); - - //test nolocal subscriber doesn't message - m = (TextMessage) noLocal.receive(1000); - if (m != null) - { - System.out.println("Message:" + m.getText()); - } - assertNull(m); - - //send message to all consumers - message = session1.createTextMessage("hello2"); - message.setStringProperty("Selector", "select"); - - publisher.publish(message); - - //test normal subscriber gets message - m = (TextMessage) normal.receive(1000); - assertNotNull(m); - - //test selector subscriber does get message - m = (TextMessage) select.receive(1000); - assertNotNull(m); - - //test nolocal subscriber doesn't message - m = (TextMessage) noLocal.receive(100); - assertNull(m); - - AMQConnection con2 = (AMQConnection) getConnection("guest", "guest", "foo"); - TopicSession session2 = con2.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); - TopicPublisher publisher2 = session2.createPublisher(topic); - - - message = session2.createTextMessage("hello2"); - message.setStringProperty("Selector", "select"); - - publisher2.publish(message); - - //test normal subscriber gets message - m = (TextMessage) normal.receive(1000); - assertNotNull(m); - - //test selector subscriber does get message - m = (TextMessage) select.receive(1000); - assertNotNull(m); - - //test nolocal subscriber does message - m = (TextMessage) noLocal.receive(100); - assertNotNull(m); - - - con.close(); - con2.close(); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(TopicSessionTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java deleted file mode 100644 index f2f35644c6..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java +++ /dev/null @@ -1,506 +0,0 @@ -/* - * 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.qpid.test.unit.transacted; - -import org.apache.qpid.testutil.QpidTestCase; -import org.apache.qpid.client.AMQConnection; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.TextMessage; - -/** - * This class tests a number of commits and roll back scenarios - * - * Assumptions; - Assumes empty Queue - */ -public class CommitRollbackTest extends QpidTestCase -{ - protected AMQConnection conn; - protected String queue = "direct://amq.direct//Qpid.Client.Transacted.CommitRollback.queue"; - protected static int testMethod = 0; - protected String payload = "xyzzy"; - private Session _session; - private MessageProducer _publisher; - private Session _pubSession; - private MessageConsumer _consumer; - Queue _jmsQueue; - - private static final Logger _logger = LoggerFactory.getLogger(CommitRollbackTest.class); - private boolean _gotone = false; - private boolean _gottwo = false; - private boolean _gottwoRedelivered = false; - - protected void setUp() throws Exception - { - super.setUp(); - testMethod++; - queue += testMethod; - newConnection(); - } - - private void newConnection() throws Exception - { - conn = (AMQConnection) getConnection("guest", "guest"); - - _session = conn.createSession(true, Session.CLIENT_ACKNOWLEDGE); - - _jmsQueue = _session.createQueue(queue); - _consumer = _session.createConsumer(_jmsQueue); - - _pubSession = conn.createSession(true, Session.CLIENT_ACKNOWLEDGE); - - _publisher = _pubSession.createProducer(_pubSession.createQueue(queue)); - - conn.start(); - } - - protected void tearDown() throws Exception - { - conn.close(); - super.tearDown(); - } - - /** - * PUT a text message, disconnect before commit, confirm it is gone. - * - * @throws Exception On error - */ - public void testPutThenDisconnect() throws Exception - { - assertTrue("session is not transacted", _session.getTransacted()); - assertTrue("session is not transacted", _pubSession.getTransacted()); - - _logger.info("sending test message"); - String MESSAGE_TEXT = "testPutThenDisconnect"; - _publisher.send(_pubSession.createTextMessage(MESSAGE_TEXT)); - - _logger.info("reconnecting without commit"); - conn.close(); - - newConnection(); - - _logger.info("receiving result"); - Message result = _consumer.receive(1000); - - // commit to ensure message is removed from queue - _session.commit(); - - assertNull("test message was put and disconnected before commit, but is still present", result); - } - - /** - * PUT a text message, disconnect before commit, confirm it is gone. - * - * @throws Exception On error - */ - public void testPutThenCloseDisconnect() throws Exception - { - assertTrue("session is not transacted", _session.getTransacted()); - assertTrue("session is not transacted", _pubSession.getTransacted()); - - _logger.info("sending test message"); - String MESSAGE_TEXT = "testPutThenDisconnect"; - _publisher.send(_pubSession.createTextMessage(MESSAGE_TEXT)); - - _logger.info("closing publisher without commit"); - _publisher.close(); - - _logger.info("reconnecting without commit"); - conn.close(); - - newConnection(); - - _logger.info("receiving result"); - Message result = _consumer.receive(1000); - - // commit to ensure message is removed from queue - _session.commit(); - - assertNull("test message was put and disconnected before commit, but is still present", result); - } - - /** - * PUT a text message, rollback, confirm message is gone. The consumer is on the same connection but different - * session as producer - * - * @throws Exception On error - */ - public void testPutThenRollback() throws Exception - { - assertTrue("session is not transacted", _session.getTransacted()); - assertTrue("session is not transacted", _pubSession.getTransacted()); - - _logger.info("sending test message"); - String MESSAGE_TEXT = "testPutThenRollback"; - _publisher.send(_pubSession.createTextMessage(MESSAGE_TEXT)); - - _logger.info("rolling back"); - _pubSession.rollback(); - - _logger.info("receiving result"); - Message result = _consumer.receive(1000); - - assertNull("test message was put and rolled back, but is still present", result); - } - - /** - * GET a text message, disconnect before commit, confirm it is still there. The consumer is on a new connection - * - * @throws Exception On error - */ - public void testGetThenDisconnect() throws Exception - { - assertTrue("session is not transacted", _session.getTransacted()); - assertTrue("session is not transacted", _pubSession.getTransacted()); - - _logger.info("sending test message"); - String MESSAGE_TEXT = "testGetThenDisconnect"; - _publisher.send(_pubSession.createTextMessage(MESSAGE_TEXT)); - - _pubSession.commit(); - - _logger.info("getting test message"); - - Message msg = _consumer.receive(1000); - assertNotNull("retrieved message is null", msg); - - _logger.info("closing connection"); - conn.close(); - - newConnection(); - - _logger.info("receiving result"); - Message result = _consumer.receive(1000); - - _session.commit(); - - assertNotNull("test message was consumed and disconnected before commit, but is gone", result); - assertEquals("test message was correct message", MESSAGE_TEXT, ((TextMessage) result).getText()); - } - - /** - * GET a text message, close consumer, disconnect before commit, confirm it is still there. The consumer is on the - * same connection but different session as producer - * - * @throws Exception On error - */ - public void testGetThenCloseDisconnect() throws Exception - { - assertTrue("session is not transacted", _session.getTransacted()); - assertTrue("session is not transacted", _pubSession.getTransacted()); - - _logger.info("sending test message"); - String MESSAGE_TEXT = "testGetThenCloseDisconnect"; - _publisher.send(_pubSession.createTextMessage(MESSAGE_TEXT)); - - _pubSession.commit(); - - _logger.info("getting test message"); - - Message msg = _consumer.receive(1000); - assertNotNull("retrieved message is null", msg); - assertEquals("test message was correct message", MESSAGE_TEXT, ((TextMessage) msg).getText()); - - _logger.info("reconnecting without commit"); - _consumer.close(); - conn.close(); - - newConnection(); - - _logger.info("receiving result"); - Message result = _consumer.receive(1000); - - _session.commit(); - - assertNotNull("test message was consumed and disconnected before commit, but is gone", result); - assertEquals("test message was correct message", MESSAGE_TEXT, ((TextMessage) result).getText()); - } - - /** - * GET a text message, rollback, confirm it is still there. The consumer is on the same connection but differnt - * session to the producer - * - * @throws Exception On error - */ - public void testGetThenRollback() throws Exception - { - assertTrue("session is not transacted", _session.getTransacted()); - assertTrue("session is not transacted", _pubSession.getTransacted()); - - _logger.info("sending test message"); - String MESSAGE_TEXT = "testGetThenRollback"; - _publisher.send(_pubSession.createTextMessage(MESSAGE_TEXT)); - - _pubSession.commit(); - - _logger.info("getting test message"); - - Message msg = _consumer.receive(1000); - - assertNotNull("retrieved message is null", msg); - assertEquals("test message was correct message", MESSAGE_TEXT, ((TextMessage) msg).getText()); - - _logger.info("rolling back"); - - _session.rollback(); - - _logger.info("receiving result"); - - Message result = _consumer.receive(1000); - - _session.commit(); - assertNotNull("test message was consumed and rolled back, but is gone", result); - assertEquals("test message was correct message", MESSAGE_TEXT, ((TextMessage) result).getText()); - assertTrue("Message is not marked as redelivered", result.getJMSRedelivered()); - } - - /** - * GET a text message, close message producer, rollback, confirm it is still there. The consumer is on the same - * connection but different session as producer - * - * @throws Exception On error - */ - public void testGetThenCloseRollback() throws Exception - { - assertTrue("session is not transacted", _session.getTransacted()); - assertTrue("session is not transacted", _pubSession.getTransacted()); - - _logger.info("sending test message"); - String MESSAGE_TEXT = "testGetThenCloseRollback"; - _publisher.send(_pubSession.createTextMessage(MESSAGE_TEXT)); - - _pubSession.commit(); - - _logger.info("getting test message"); - - Message msg = _consumer.receive(1000); - - assertNotNull("retrieved message is null", msg); - assertEquals("test message was correct message", MESSAGE_TEXT, ((TextMessage) msg).getText()); - - _logger.info("Closing consumer"); - _consumer.close(); - - _logger.info("rolling back"); - _session.rollback(); - - _logger.info("receiving result"); - - _consumer = _session.createConsumer(_jmsQueue); - - Message result = _consumer.receive(1000); - - _session.commit(); - assertNotNull("test message was consumed and rolled back, but is gone", result); - assertEquals("test message was correct message", MESSAGE_TEXT, ((TextMessage) result).getText()); - assertTrue("Message is not marked as redelivered", result.getJMSRedelivered()); - } - - /** - * Test that rolling back a session purges the dispatcher queue, and the messages arrive in the correct order - * - * @throws Exception On error - */ - public void testSend2ThenRollback() throws Exception - { - int run = 0; - while (run < 10) - { - run++; - _logger.info("Run:" + run); - assertTrue("session is not transacted", _session.getTransacted()); - assertTrue("session is not transacted", _pubSession.getTransacted()); - - _logger.info("sending two test messages"); - _publisher.send(_pubSession.createTextMessage("1")); - _publisher.send(_pubSession.createTextMessage("2")); - _pubSession.commit(); - - _logger.info("getting test message"); - assertEquals("1", ((TextMessage) _consumer.receive(1000)).getText()); - - _logger.info("rolling back"); - _session.rollback(); - - _logger.info("receiving result"); - Message result = _consumer.receive(1000); - - assertNotNull("test message was consumed and rolled back, but is gone", result); - - // Message Order is: - - // Send 1 , 2 - // Retrieve 1 and then rollback - // Receieve 1 (redelivered) , 2 (may or may not be redelivered??) - - verifyMessages(result); - - // Occassionally get message 2 first! -// assertEquals("Should get message one first", "1", ((TextMessage) result).getText()); -// assertTrue("Message is not marked as redelivered", result.getJMSRedelivered()); -// -// result = _consumer.receive(1000); -// assertEquals("Second message should be message 2", "2", ((TextMessage) result).getText()); -// assertTrue("Message is not marked as redelivered", result.getJMSRedelivered()); -// -// result = _consumer.receive(1000); -// assertNull("There should be no more messages", result); - - _session.commit(); - } - } - - private void verifyMessages(Message result) throws JMSException - { - - if (result == null) - { - assertTrue("Didn't receive redelivered message one", _gotone); - assertTrue("Didn't receive message two at all", _gottwo | _gottwoRedelivered); - _gotone = false; - _gottwo = false; - _gottwoRedelivered = false; - return; - } - - if (((TextMessage) result).getText().equals("1")) - { - _logger.info("Got 1 redelivered"); - assertTrue("Message is not marked as redelivered", result.getJMSRedelivered()); - assertFalse("Already received message one", _gotone); - _gotone = true; - - } - else - { - assertEquals("2", ((TextMessage) result).getText()); - - if (result.getJMSRedelivered()) - { - _logger.info("Got 2 redelivered, message was prefetched"); - assertFalse("Already received message redelivered two", _gottwoRedelivered); - - _gottwoRedelivered = true; - } - else - { - _logger.warn("Got 2, message prefetched wasn't cleared or messages was in transit when rollback occured"); - assertFalse("Already received message two", _gottwo); - assertFalse("Already received message redelivered two", _gottwoRedelivered); - _gottwo = true; - } - } - - verifyMessages(_consumer.receive(1000)); - } - - /** - * This test sends two messages receives on of them but doesn't ack it. - * The consumer is then closed - * the first message should be returned as redelivered. - * the second message should be delivered normally. - * @throws Exception - */ - public void testSend2ThenCloseAfter1andTryAgain() throws Exception - { - assertTrue("session is not transacted", _session.getTransacted()); - assertTrue("session is not transacted", _pubSession.getTransacted()); - - _logger.info("sending two test messages"); - _publisher.send(_pubSession.createTextMessage("1")); - _publisher.send(_pubSession.createTextMessage("2")); - _pubSession.commit(); - - _logger.info("getting test message"); - Message result = _consumer.receive(5000); - - assertNotNull("Message received should not be null", result); - assertEquals("1", ((TextMessage) result).getText()); - assertTrue("Messasge is marked as redelivered" + result, !result.getJMSRedelivered()); - - _logger.info("Closing Consumer"); - - _consumer.close(); - - _logger.info("Creating New consumer"); - _consumer = _session.createConsumer(_jmsQueue); - - _logger.info("receiving result"); - - - // Message 2 may be marked as redelivered if it was prefetched. - result = _consumer.receive(5000); - assertNotNull("Second message was not consumed, but is gone", result); - - // The first message back will be 2, message 1 has been received but not committed - // Closing the consumer does not commit the session. - - // if this is message 1 then it should be marked as redelivered - if("1".equals(((TextMessage) result).getText())) - { - fail("First message was recieved again"); - } - - result = _consumer.receive(1000); - assertNull("test message should be null:" + result, result); - - _session.commit(); - } - - public void testPutThenRollbackThenGet() throws Exception - { - assertTrue("session is not transacted", _session.getTransacted()); - assertTrue("session is not transacted", _pubSession.getTransacted()); - - _logger.info("sending test message"); - String MESSAGE_TEXT = "testPutThenRollbackThenGet"; - - _publisher.send(_pubSession.createTextMessage(MESSAGE_TEXT)); - _pubSession.commit(); - - assertNotNull(_consumer.receive(100)); - - _publisher.send(_pubSession.createTextMessage(MESSAGE_TEXT)); - - _logger.info("rolling back"); - _pubSession.rollback(); - - _logger.info("receiving result"); - Message result = _consumer.receive(1000); - assertNull("test message was put and rolled back, but is still present", result); - - _publisher.send(_pubSession.createTextMessage(MESSAGE_TEXT)); - - _pubSession.commit(); - - assertNotNull(_consumer.receive(100)); - - _session.commit(); - } - -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/transacted/TransactedTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/transacted/TransactedTest.java deleted file mode 100644 index d96e8546e2..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/transacted/TransactedTest.java +++ /dev/null @@ -1,348 +0,0 @@ -/* - * - * 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.qpid.test.unit.transacted; - - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.jms.Session; -import org.apache.qpid.testutil.QpidTestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.TextMessage; - -public class TransactedTest extends QpidTestCase -{ - private AMQQueue queue1; - - private AMQConnection con; - private Session session; - private MessageConsumer consumer1; - private MessageProducer producer2; - - private AMQConnection prepCon; - private Session prepSession; - private MessageProducer prepProducer1; - - private AMQConnection testCon; - private Session testSession; - private MessageConsumer testConsumer1; - private MessageConsumer testConsumer2; - private static final Logger _logger = LoggerFactory.getLogger(TransactedTest.class); - - protected void setUp() throws Exception - { - try - { - super.setUp(); - _logger.info("Create Connection"); - con = (AMQConnection) getConnection("guest", "guest"); - _logger.info("Create Session"); - session = con.createSession(true, Session.SESSION_TRANSACTED); - _logger.info("Create Q1"); - queue1 = new AMQQueue(session.getDefaultQueueExchangeName(), new AMQShortString("Q1"), - new AMQShortString("Q1"), false, true); - _logger.info("Create Q2"); - AMQQueue queue2 = new AMQQueue(session.getDefaultQueueExchangeName(), new AMQShortString("Q2"), false); - - _logger.info("Create Consumer of Q1"); - consumer1 = session.createConsumer(queue1); - // Dummy just to create the queue. - _logger.info("Create Consumer of Q2"); - MessageConsumer consumer2 = session.createConsumer(queue2); - _logger.info("Close Consumer of Q2"); - consumer2.close(); - - _logger.info("Create producer to Q2"); - producer2 = session.createProducer(queue2); - - _logger.info("Start Connection"); - con.start(); - - _logger.info("Create prep connection"); - prepCon = (AMQConnection) getConnection("guest", "guest"); - - _logger.info("Create prep session"); - prepSession = prepCon.createSession(false, AMQSession.AUTO_ACKNOWLEDGE); - - _logger.info("Create prep producer to Q1"); - prepProducer1 = prepSession.createProducer(queue1); - - _logger.info("Create prep connection start"); - prepCon.start(); - - _logger.info("Create test connection"); - testCon = (AMQConnection) getConnection("guest", "guest"); - _logger.info("Create test session"); - testSession = testCon.createSession(false, AMQSession.AUTO_ACKNOWLEDGE); - _logger.info("Create test consumer of q2"); - testConsumer2 = testSession.createConsumer(queue2); - } - catch (Exception e) - { - e.printStackTrace(); - stopBroker(); - throw e; - } - } - - protected void tearDown() throws Exception - { - try - { - _logger.info("Close connection"); - con.close(); - _logger.info("Close test connection"); - testCon.close(); - _logger.info("Close prep connection"); - prepCon.close(); - } - catch (Exception e) - { - e.printStackTrace(); - } - finally - { - super.tearDown(); - } - } - - public void testCommit() throws Exception - { - try - { -// add some messages - _logger.info("Send prep A"); - prepProducer1.send(prepSession.createTextMessage("A")); - _logger.info("Send prep B"); - prepProducer1.send(prepSession.createTextMessage("B")); - _logger.info("Send prep C"); - prepProducer1.send(prepSession.createTextMessage("C")); - - // send and receive some messages - _logger.info("Send X to Q2"); - producer2.send(session.createTextMessage("X")); - _logger.info("Send Y to Q2"); - producer2.send(session.createTextMessage("Y")); - _logger.info("Send Z to Q2"); - producer2.send(session.createTextMessage("Z")); - - _logger.info("Read A from Q1"); - expect("A", consumer1.receive(1000)); - _logger.info("Read B from Q1"); - expect("B", consumer1.receive(1000)); - _logger.info("Read C from Q1"); - expect("C", consumer1.receive(1000)); - - // commit - _logger.info("session commit"); - session.commit(); - _logger.info("Start test Connection"); - testCon.start(); - - // ensure sent messages can be received and received messages are gone - _logger.info("Read X from Q2"); - expect("X", testConsumer2.receive(1000)); - _logger.info("Read Y from Q2"); - expect("Y", testConsumer2.receive(1000)); - _logger.info("Read Z from Q2"); - expect("Z", testConsumer2.receive(1000)); - - _logger.info("create test session on Q1"); - testConsumer1 = testSession.createConsumer(queue1); - _logger.info("Read null from Q1"); - assertTrue(null == testConsumer1.receive(1000)); - _logger.info("Read null from Q2"); - assertTrue(null == testConsumer2.receive(1000)); - } - catch (Throwable e) - { - e.printStackTrace(); - fail(e.getMessage()); - } - } - - public void testRollback() throws Exception - { - try - { -// add some messages - _logger.info("Send prep RB_A"); - prepProducer1.send(prepSession.createTextMessage("RB_A")); - _logger.info("Send prep RB_B"); - prepProducer1.send(prepSession.createTextMessage("RB_B")); - _logger.info("Send prep RB_C"); - prepProducer1.send(prepSession.createTextMessage("RB_C")); - - _logger.info("Sending RB_X RB_Y RB_Z"); - producer2.send(session.createTextMessage("RB_X")); - producer2.send(session.createTextMessage("RB_Y")); - producer2.send(session.createTextMessage("RB_Z")); - _logger.info("Receiving RB_A RB_B"); - expect("RB_A", consumer1.receive(1000)); - expect("RB_B", consumer1.receive(1000)); - // Don't consume 'RB_C' leave it in the prefetch cache to ensure rollback removes it. - // Quick sleep to ensure 'RB_C' gets pre-fetched - Thread.sleep(500); - - // rollback - _logger.info("rollback"); - session.rollback(); - - _logger.info("Receiving RB_A RB_B RB_C"); - // ensure sent messages are not visible and received messages are requeued - expect("RB_A", consumer1.receive(1000), true); - expect("RB_B", consumer1.receive(1000), true); - expect("RB_C", consumer1.receive(1000), true); - _logger.info("Starting new connection"); - testCon.start(); - testConsumer1 = testSession.createConsumer(queue1); - _logger.info("Testing we have no messages left"); - assertTrue(null == testConsumer1.receive(1000)); - assertTrue(null == testConsumer2.receive(1000)); - - session.commit(); - - _logger.info("Testing we have no messages left after commit"); - assertTrue(null == testConsumer1.receive(1000)); - assertTrue(null == testConsumer2.receive(1000)); - } - catch (Throwable e) - { - e.printStackTrace(); - fail(e.getMessage()); - } - } - - public void testResendsMsgsAfterSessionClose() throws Exception - { - try - { - AMQConnection con = (AMQConnection) getConnection("guest", "guest"); - - Session consumerSession = con.createSession(true, Session.SESSION_TRANSACTED); - AMQQueue queue3 = new AMQQueue(consumerSession.getDefaultQueueExchangeName(), new AMQShortString("Q3"), false); - MessageConsumer consumer = consumerSession.createConsumer(queue3); - - AMQConnection con2 = (AMQConnection) getConnection("guest", "guest"); - Session producerSession = con2.createSession(true, Session.SESSION_TRANSACTED); - MessageProducer producer = producerSession.createProducer(queue3); - - _logger.info("Sending four messages"); - producer.send(producerSession.createTextMessage("msg1")); - producer.send(producerSession.createTextMessage("msg2")); - producer.send(producerSession.createTextMessage("msg3")); - producer.send(producerSession.createTextMessage("msg4")); - - producerSession.commit(); - - _logger.info("Starting connection"); - con.start(); - TextMessage tm = (TextMessage) consumer.receive(); - assertNotNull(tm); - assertEquals("msg1", tm.getText()); - - consumerSession.commit(); - - _logger.info("Received and committed first message"); - tm = (TextMessage) consumer.receive(1000); - assertNotNull(tm); - assertEquals("msg2", tm.getText()); - - tm = (TextMessage) consumer.receive(1000); - assertNotNull(tm); - assertEquals("msg3", tm.getText()); - - tm = (TextMessage) consumer.receive(1000); - assertNotNull(tm); - assertEquals("msg4", tm.getText()); - - _logger.info("Received all four messages. Closing connection with three outstanding messages"); - - consumerSession.close(); - - consumerSession = con.createSession(true, Session.SESSION_TRANSACTED); - - consumer = consumerSession.createConsumer(queue3); - - // no ack for last three messages so when I call recover I expect to get three messages back - tm = (TextMessage) consumer.receive(3000); - assertNotNull(tm); - assertEquals("msg2", tm.getText()); - assertTrue("Message is not redelivered", tm.getJMSRedelivered()); - - tm = (TextMessage) consumer.receive(3000); - assertNotNull(tm); - assertEquals("msg3", tm.getText()); - assertTrue("Message is not redelivered", tm.getJMSRedelivered()); - - tm = (TextMessage) consumer.receive(3000); - assertNotNull(tm); - assertEquals("msg4", tm.getText()); - assertTrue("Message is not redelivered", tm.getJMSRedelivered()); - - _logger.info("Received redelivery of three messages. Committing"); - - consumerSession.commit(); - - _logger.info("Called commit"); - - tm = (TextMessage) consumer.receive(1000); - assertNull(tm); - - _logger.info("No messages redelivered as is expected"); - - con.close(); - con2.close(); - } - catch (Throwable e) - { - e.printStackTrace(); - fail(e.getMessage()); - } - } - - private void expect(String text, Message msg) throws JMSException - { - expect(text, msg, false); - } - - private void expect(String text, Message msg, boolean requeued) throws JMSException - { - assertNotNull("Message should not be null", msg); - assertTrue("Message should be a text message", msg instanceof TextMessage); - assertEquals("Message content does not match expected", text, ((TextMessage) msg).getText()); - assertEquals("Message should " + (requeued ? "" : "not") + " be requeued", requeued, msg.getJMSRedelivered()); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(TransactedTest.class); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/xa/AbstractXATestCase.java b/java/client/src/test/java/org/apache/qpid/test/unit/xa/AbstractXATestCase.java deleted file mode 100644 index 18cdb645c6..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/xa/AbstractXATestCase.java +++ /dev/null @@ -1,132 +0,0 @@ -/* 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.qpid.test.unit.xa; - -import org.apache.qpidity.dtx.XidImpl; -import org.apache.qpid.testutil.QpidTestCase; - -import javax.transaction.xa.Xid; -import javax.transaction.xa.XAResource; -import javax.jms.*; -import java.util.Random; - -/** - * - * - */ -public abstract class AbstractXATestCase extends QpidTestCase -{ - protected static final String _sequenceNumberPropertyName = "seqNumber"; - - /** - * the xaResource associated with the standard session - */ - protected static XAResource _xaResource = null; - - /** - * producer registered with the standard session - */ - protected static MessageProducer _producer = null; - - /** - * consumer registered with the standard session - */ - protected static MessageConsumer _consumer = null; - - /** - * a standard message - */ - protected static TextMessage _message = null; - - /** - * xid counter - */ - private static int _xidCounter = (new Random()).nextInt(1000000); - - - protected void setUp() throws Exception - { - super.setUp(); - init(); - } - - public abstract void init() throws Exception; - - - - /** - * construct a new Xid - * - * @return a new Xid - */ - protected Xid getNewXid() - { - byte[] branchQualifier; - byte[] globalTransactionID; - int format = _xidCounter; - String branchQualifierSt = "branchQualifier" + _xidCounter; - String globalTransactionIDSt = "globalTransactionID" + _xidCounter; - branchQualifier = branchQualifierSt.getBytes(); - globalTransactionID = globalTransactionIDSt.getBytes(); - _xidCounter++; - return new XidImpl(branchQualifier, format, globalTransactionID); - } - - public void init(XASession session, Destination destination) - { - // get the xaResource - try - { - _xaResource = session.getXAResource(); - } - catch (Exception e) - { - fail("cannot access the xa resource: " + e.getMessage()); - } - // create standard producer - try - { - _producer = session.createProducer(destination); - _producer.setDeliveryMode(DeliveryMode.PERSISTENT); - } - catch (JMSException e) - { - e.printStackTrace(); - fail("cannot create message producer: " + e.getMessage()); - } - // create standard consumer - try - { - _consumer = session.createConsumer(destination); - } - catch (JMSException e) - { - fail("cannot create message consumer: " + e.getMessage()); - } - // create a standard message - try - { - _message = session.createTextMessage(); - _message.setText("test XA"); - } - catch (JMSException e) - { - fail("cannot create standard message: " + e.getMessage()); - } - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/xa/FaultTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/xa/FaultTest.java deleted file mode 100644 index 0adf39980b..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/xa/FaultTest.java +++ /dev/null @@ -1,364 +0,0 @@ -package org.apache.qpid.test.unit.xa; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.*; -import javax.transaction.xa.Xid; -import javax.transaction.xa.XAResource; -import javax.transaction.xa.XAException; - -import junit.framework.TestSuite; - - -public class FaultTest extends AbstractXATestCase -{ - /* this clas logger */ - private static final Logger _logger = LoggerFactory.getLogger(FaultTest.class); - - /** - * the queue use by all the tests - */ - private static Queue _queue = null; - /** - * the queue connection factory used by all tests - */ - private static XAQueueConnectionFactory _queueFactory = null; - - /** - * standard xa queue connection - */ - private static XAQueueConnection _xaqueueConnection = null; - - /** - * standard xa queue connection - */ - private static QueueConnection _queueConnection = null; - - - /** - * standard queue session created from the standard connection - */ - private static QueueSession _nonXASession = null; - - /** - * the queue name - */ - private static final String QUEUENAME = "xaQueue"; - - /** ----------------------------------------------------------------------------------- **/ - /** - * ----------------------------- JUnit support ----------------------------------------- * - */ - - /** - * Gets the test suite tests - * - * @return the test suite tests - */ - public static TestSuite getSuite() - { - return new TestSuite(QueueTest.class); - } - - /** - * Run the test suite. - * - * @param args Any command line arguments specified to this class. - */ - public static void main(String args[]) - { - junit.textui.TestRunner.run(getSuite()); - } - - public void tearDown() throws Exception - { - if (!isBroker08()) - { - _xaqueueConnection.close(); - _queueConnection.close(); - } - super.tearDown(); - } - - /** - * Initialize standard actors - */ - public void init() throws Exception - { - if (!isBroker08()) - { - _queue = (Queue) getInitialContext().lookup(QUEUENAME); - _queueFactory = getConnectionFactory(); - _xaqueueConnection = _queueFactory.createXAQueueConnection("guest", "guest"); - XAQueueSession session = _xaqueueConnection.createXAQueueSession(); - _queueConnection = _queueFactory.createQueueConnection(); - _nonXASession = _queueConnection.createQueueSession(true, Session.AUTO_ACKNOWLEDGE); - init(session, _queue); - } - } - - /** -------------------------------------------------------------------------------------- **/ - /** ----------------------------- Test Suite -------------------------------------------- **/ - /** -------------------------------------------------------------------------------------- **/ - - /** - * Strategy: - * Invoke start twice with the same xid on an XA resource. - * Check that the second - * invocation is throwing the expected XA exception. - */ - public void testSameXID() throws Exception - { - Xid xid = getNewXid(); - _xaResource.start(xid, XAResource.TMNOFLAGS); - // we now exepct this operation to fail - try - { - _xaResource.start(xid, XAResource.TMNOFLAGS); - fail("We managed to start a transaction with the same xid"); - } - catch (XAException e) - { - assertEquals("Wrong error code: ", XAException.XAER_DUPID, e.errorCode); - } - } - - /** - * Strategy: - * Invoke start on a XA resource with flag other than TMNOFLAGS, TMJOIN, or TMRESUME. - * Check that a XA Exception is thrown. - */ - public void testWrongStartFlag() - { - Xid xid = getNewXid(); - try - { - _xaResource.start(xid, XAResource.TMONEPHASE); - fail("We managed to start a transaction with a wrong flag"); - } - catch (XAException e) - { - assertEquals("Wrong error code: ", XAException.XAER_INVAL, e.errorCode); - } - } - - /** - * Strategy: - * Check that a XA exception is thrown when: - * A non started xid is ended - */ - public void testEnd() - { - Xid xid = getNewXid(); - try - { - _xaResource.end(xid, XAResource.TMSUCCESS); - fail("We managed to end a transaction before it is started"); - } - catch (XAException e) - { - assertEquals("Wrong error code: ", XAException.XAER_PROTO, e.errorCode); - } - } - - - /** - * Strategy: - * Check that a XA exception is thrown when: - * Call forget on an unknown xid - * call forget on a started xid - * A non started xid is prepared - * A non ended xis is prepared - */ - public void testForget() - { - Xid xid = getNewXid(); - try - { - _xaResource.forget(xid); - fail("We managed to forget an unknown xid"); - } - catch (XAException e) - { - // assertEquals("Wrong error code: ", XAException.XAER_NOTA, e.errorCode); - } - xid = getNewXid(); - try - { - _xaResource.start(xid, XAResource.TMNOFLAGS); - _xaResource.forget(xid); - fail("We managed to forget a started xid"); - } - catch (XAException e) - { - assertEquals("Wrong error code: ", XAException.XAER_PROTO, e.errorCode); - } - } - - /** - * Strategy: - * Check that a XA exception is thrown when: - * A non started xid is prepared - * A non ended xid is prepared - */ - public void testPrepare() - { - Xid xid = getNewXid(); - try - { - _xaResource.prepare(xid); - fail("We managed to prepare an unknown xid"); - } - catch (XAException e) - { - assertEquals("Wrong error code: ", XAException.XAER_NOTA, e.errorCode); - } - xid = getNewXid(); - try - { - _xaResource.start(xid, XAResource.TMNOFLAGS); - _xaResource.prepare(xid); - fail("We managed to prepare a started xid"); - } - catch (XAException e) - { - assertEquals("Wrong error code: ", XAException.XAER_PROTO, e.errorCode); - } - } - - /** - * Strategy: - * Check that the expected XA exception is thrown when: - * A non started xid is committed - * A non ended xid is committed - * A non prepared xid is committed with one phase set to false. - * A prepared xid is committed with one phase set to true. - */ - public void testCommit() throws Exception - { - Xid xid = getNewXid(); - try - { - _xaResource.commit(xid, true); - fail("We managed to commit an unknown xid"); - } - catch (XAException e) - { - assertEquals("Wrong error code: ", XAException.XAER_NOTA, e.errorCode); - } - xid = getNewXid(); - try - { - _xaResource.start(xid, XAResource.TMNOFLAGS); - _xaResource.commit(xid, true); - fail("We managed to commit a not ended xid"); - } - catch (XAException e) - { - assertEquals("Wrong error code: ", XAException.XAER_PROTO, e.errorCode); - } - xid = getNewXid(); - try - { - _xaResource.start(xid, XAResource.TMNOFLAGS); - _xaResource.end(xid, XAResource.TMSUCCESS); - _xaResource.commit(xid, false); - fail("We managed to commit a not prepared xid"); - } - catch (XAException e) - { - assertEquals("Wrong error code: ", XAException.XAER_PROTO, e.errorCode); - } - xid = getNewXid(); - try - { - _xaResource.start(xid, XAResource.TMNOFLAGS); - _xaResource.end(xid, XAResource.TMSUCCESS); - _xaResource.prepare(xid); - _xaResource.commit(xid, true); - fail("We managed to commit a prepared xid"); - } - catch (XAException e) - { - assertEquals("Wrong error code: ", XAException.XAER_PROTO, e.errorCode); - } - finally - { - _xaResource.commit(xid, false); - } - } - - /** - * Strategy: - * Check that the expected XA exception is thrown when: - * A non started xid is rolled back - * A non ended xid is rolled back - */ - public void testRollback() - { - Xid xid = getNewXid(); - try - { - _xaResource.rollback(xid); - fail("We managed to rollback an unknown xid"); - } - catch (XAException e) - { - assertEquals("Wrong error code: ", XAException.XAER_NOTA, e.errorCode); - } - xid = getNewXid(); - try - { - _xaResource.start(xid, XAResource.TMNOFLAGS); - _xaResource.rollback(xid); - fail("We managed to rollback a not ended xid"); - } - catch (XAException e) - { - assertEquals("Wrong error code: ", XAException.XAER_PROTO, e.errorCode); - } - } - - /** - * Strategy: - * Check that the timeout is set correctly - */ - public void testTransactionTimeoutvalue() throws Exception - { - Xid xid = getNewXid(); - _xaResource.start(xid, XAResource.TMNOFLAGS); - assertEquals("Wrong timeout", _xaResource.getTransactionTimeout(), 0); - _xaResource.setTransactionTimeout(1000); - assertEquals("Wrong timeout", _xaResource.getTransactionTimeout(), 1000); - _xaResource.end(xid, XAResource.TMSUCCESS); - xid = getNewXid(); - _xaResource.start(xid, XAResource.TMNOFLAGS); - assertEquals("Wrong timeout", _xaResource.getTransactionTimeout(), 0); - } - - /** - * Strategy: - * Check that a transaction timeout as expected - * - set timeout to 10ms - * - sleep 1000ms - * - call end and check that the expected exception is thrown - */ - public void testTransactionTimeout() throws Exception - { - Xid xid = getNewXid(); - try - { - _xaResource.start(xid, XAResource.TMNOFLAGS); - assertEquals("Wrong timeout", _xaResource.getTransactionTimeout(), 0); - _xaResource.setTransactionTimeout(10); - Thread.sleep(1000); - _xaResource.end(xid, XAResource.TMSUCCESS); - } - catch (XAException e) - { - assertEquals("Wrong error code: ", XAException.XA_RBTIMEOUT, e.errorCode); - } - } - -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/xa/QueueTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/xa/QueueTest.java deleted file mode 100644 index 740f9e72ad..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/xa/QueueTest.java +++ /dev/null @@ -1,657 +0,0 @@ -/* 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.qpid.test.unit.xa; - -import javax.jms.*; -import javax.transaction.xa.XAResource; -import javax.transaction.xa.Xid; -import javax.transaction.xa.XAException; - -import junit.framework.TestSuite; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class QueueTest extends AbstractXATestCase -{ - /* this clas logger */ - private static final Logger _logger = LoggerFactory.getLogger(QueueTest.class); - - /** - * the queue use by all the tests - */ - private static Queue _queue = null; - /** - * the queue connection factory used by all tests - */ - private static XAQueueConnectionFactory _queueFactory = null; - - /** - * standard xa queue connection - */ - private static XAQueueConnection _xaqueueConnection= null; - - /** - * standard xa queue connection - */ - private static QueueConnection _queueConnection=null; - - - /** - * standard queue session created from the standard connection - */ - private static QueueSession _nonXASession = null; - - /** - * the queue name - */ - private static final String QUEUENAME = "xaQueue"; - - /** ----------------------------------------------------------------------------------- **/ - /** - * ----------------------------- JUnit support ----------------------------------------- * - */ - - /** - * Gets the test suite tests - * - * @return the test suite tests - */ - public static TestSuite getSuite() - { - return new TestSuite(QueueTest.class); - } - - /** - * Run the test suite. - * - * @param args Any command line arguments specified to this class. - */ - public static void main(String args[]) - { - junit.textui.TestRunner.run(getSuite()); - } - - public void tearDown() throws Exception - { - if (!isBroker08()) - { - try - { - _xaqueueConnection.close(); - _queueConnection.close(); - } - catch (Exception e) - { - fail("Exception thrown when cleaning standard connection: " + e.getStackTrace()); - } - } - super.tearDown(); - } - - /** - * Initialize standard actors - */ - public void init() - { - if (!isBroker08()) - { - // lookup test queue - try - { - _queue = (Queue) getInitialContext().lookup(QUEUENAME); - } - catch (Exception e) - { - fail("cannot lookup test queue " + e.getMessage()); - } - - // lookup connection factory - try - { - _queueFactory = getConnectionFactory(); - } - catch (Exception e) - { - fail("enable to lookup connection factory "); - } - // create standard connection - try - { - _xaqueueConnection= getNewQueueXAConnection(); - } - catch (JMSException e) - { - fail("cannot create queue connection: " + e.getMessage()); - } - // create xa session - XAQueueSession session = null; - try - { - session = _xaqueueConnection.createXAQueueSession(); - } - catch (JMSException e) - { - fail("cannot create queue session: " + e.getMessage()); - } - // create a standard session - try - { - _queueConnection = _queueFactory.createQueueConnection(); - _nonXASession = _queueConnection.createQueueSession(true, Session.AUTO_ACKNOWLEDGE); - } - catch (JMSException e) - { - fail("cannot create queue session: " + e.getMessage()); - } - init(session, _queue); - } - } - - /** -------------------------------------------------------------------------------------- **/ - /** ----------------------------- Test Suite -------------------------------------------- **/ - /** -------------------------------------------------------------------------------------- **/ - - /** - * Uses two transactions respectively with xid1 and xid2 that are used to send a message - * within xid1 and xid2. xid2 is committed and xid1 is used to receive the message that was sent within xid2. - * Xid is then committed and a standard transaction is used to receive the message that was sent within xid1. - */ - public void testProducer() - { - if (!isBroker08()) - { - _logger.debug("running testProducer"); - Xid xid1 = getNewXid(); - Xid xid2 = getNewXid(); - // start the xaResource for xid1 - try - { - _xaResource.start(xid1, XAResource.TMNOFLAGS); - } - catch (XAException e) - { - e.printStackTrace(); - fail("cannot start the transaction with xid1: " + e.getMessage()); - } - try - { - // start the connection - _xaqueueConnection.start(); - // produce a message with sequence number 1 - _message.setLongProperty(_sequenceNumberPropertyName, 1); - _producer.send(_message); - } - catch (JMSException e) - { - fail(" cannot send persistent message: " + e.getMessage()); - } - // suspend the transaction - try - { - _xaResource.end(xid1, XAResource.TMSUSPEND); - } - catch (XAException e) - { - fail("Cannot end the transaction with xid1: " + e.getMessage()); - } - // start the xaResource for xid2 - try - { - _xaResource.start(xid2, XAResource.TMNOFLAGS); - } - catch (XAException e) - { - fail("cannot start the transaction with xid2: " + e.getMessage()); - } - try - { - // produce a message - _message.setLongProperty(_sequenceNumberPropertyName, 2); - _producer.send(_message); - } - catch (JMSException e) - { - fail(" cannot send second persistent message: " + e.getMessage()); - } - // end xid2 and start xid1 - try - { - _xaResource.end(xid2, XAResource.TMSUCCESS); - _xaResource.start(xid1, XAResource.TMRESUME); - } - catch (XAException e) - { - fail("Exception when ending and starting transactions: " + e.getMessage()); - } - // two phases commit transaction with xid2 - try - { - int resPrepare = _xaResource.prepare(xid2); - if (resPrepare != XAResource.XA_OK) - { - fail("prepare returned: " + resPrepare); - } - _xaResource.commit(xid2, false); - } - catch (XAException e) - { - fail("Exception thrown when preparing transaction with xid2: " + e.getMessage()); - } - // receive a message from queue test we expect it to be the second one - try - { - TextMessage message = (TextMessage) _consumer.receive(1000); - if (message == null) - { - fail("did not receive second message as expected "); - } - else - { - if (message.getLongProperty(_sequenceNumberPropertyName) != 2) - { - fail("receive wrong message its sequence number is: " + message - .getLongProperty(_sequenceNumberPropertyName)); - } - } - } - catch (JMSException e) - { - fail("Exception when receiving second message: " + e.getMessage()); - } - // end and one phase commit the first transaction - try - { - _xaResource.end(xid1, XAResource.TMSUCCESS); - _xaResource.commit(xid1, true); - } - catch (XAException e) - { - fail("Exception thrown when commiting transaction with xid1"); - } - // We should now be able to receive the first message - try - { - _xaqueueConnection.close(); - Session nonXASession = _nonXASession; - MessageConsumer nonXAConsumer = nonXASession.createConsumer(_queue); - _queueConnection.start(); - TextMessage message1 = (TextMessage) nonXAConsumer.receive(1000); - if (message1 == null) - { - fail("did not receive first message as expected "); - } - else - { - if (message1.getLongProperty(_sequenceNumberPropertyName) != 1) - { - fail("receive wrong message its sequence number is: " + message1 - .getLongProperty(_sequenceNumberPropertyName)); - } - } - // commit that transacted session - nonXASession.commit(); - // the queue should be now empty - message1 = (TextMessage) nonXAConsumer.receive(1000); - if (message1 != null) - { - fail("receive an unexpected message "); - } - } - catch (JMSException e) - { - fail("Exception thrown when emptying the queue: " + e.getMessage()); - } - } - } - - /** - * strategy: Produce a message within Tx1 and prepare tx1. crash the server then commit tx1 and consume the message - */ - public void testSendAndRecover() - { - if (!isBroker08()) - { - _logger.debug("running testSendAndRecover"); - Xid xid1 = getNewXid(); - // start the xaResource for xid1 - try - { - _xaResource.start(xid1, XAResource.TMNOFLAGS); - } - catch (XAException e) - { - fail("cannot start the transaction with xid1: " + e.getMessage()); - } - try - { - // start the connection - _xaqueueConnection.start(); - // produce a message with sequence number 1 - _message.setLongProperty(_sequenceNumberPropertyName, 1); - _producer.send(_message); - } - catch (JMSException e) - { - fail(" cannot send persistent message: " + e.getMessage()); - } - // suspend the transaction - try - { - _xaResource.end(xid1, XAResource.TMSUCCESS); - } - catch (XAException e) - { - fail("Cannot end the transaction with xid1: " + e.getMessage()); - } - // prepare the transaction with xid1 - try - { - _xaResource.prepare(xid1); - } - catch (XAException e) - { - fail("Exception when preparing xid1: " + e.getMessage()); - } - - /////// stop the server now !! - try - { - _logger.debug("stopping broker"); - shutdownServer(); - init(); - } - catch (Exception e) - { - fail("Exception when stopping and restarting the server"); - } - - // get the list of in doubt transactions - try - { - Xid[] inDoubt = _xaResource.recover(XAResource.TMSTARTRSCAN); - if (inDoubt == null) - { - fail("the array of in doubt transactions should not be null "); - } - // At that point we expect only two indoubt transactions: - if (inDoubt.length != 1) - { - fail("in doubt transaction size is diffenrent thatn 2, there are " + inDoubt.length + "in doubt transactions"); - } - - // commit them - for (Xid anInDoubt : inDoubt) - { - if (anInDoubt.equals(xid1)) - { - System.out.println("commit xid1 "); - try - { - _xaResource.commit(anInDoubt, false); - } - catch (Exception e) - { - System.out.println("PB when aborted xid1"); - } - } - else - { - fail("did not receive right xid "); - } - } - } - catch (XAException e) - { - e.printStackTrace(); - fail("exception thrown when recovering transactions " + e.getMessage()); - } - // the queue should contain the first message! - try - { - _xaqueueConnection.close(); - Session nonXASession = _nonXASession; - MessageConsumer nonXAConsumer = nonXASession.createConsumer(_queue); - _queueConnection.start(); - TextMessage message1 = (TextMessage) nonXAConsumer.receive(1000); - - if (message1 == null) - { - fail("queue does not contain any message!"); - } - if (message1.getLongProperty(_sequenceNumberPropertyName) != 1) - { - fail("Wrong message returned! Sequence number is " + message1 - .getLongProperty(_sequenceNumberPropertyName)); - } - nonXASession.commit(); - } - catch (JMSException e) - { - fail("Exception thrown when testin that queue test is not empty: " + e.getMessage()); - } - } - } - - /** - * strategy: Produce a message within Tx1 and prepare tx1. Produce a standard message and consume - * it within tx2 and prepare tx2. Shutdown the server and get the list of in doubt transactions: - * we expect tx1 and tx2! Then, Tx1 is aborted and tx2 is committed so we expect the test's queue to be empty! - */ - public void testRecover() - { - if (!isBroker08()) - { - _logger.debug("running testRecover"); - Xid xid1 = getNewXid(); - Xid xid2 = getNewXid(); - // start the xaResource for xid1 - try - { - _xaResource.start(xid1, XAResource.TMNOFLAGS); - } - catch (XAException e) - { - fail("cannot start the transaction with xid1: " + e.getMessage()); - } - try - { - // start the connection - _xaqueueConnection.start(); - // produce a message with sequence number 1 - _message.setLongProperty(_sequenceNumberPropertyName, 1); - _producer.send(_message); - } - catch (JMSException e) - { - fail(" cannot send persistent message: " + e.getMessage()); - } - // suspend the transaction - try - { - _xaResource.end(xid1, XAResource.TMSUCCESS); - } - catch (XAException e) - { - fail("Cannot end the transaction with xid1: " + e.getMessage()); - } - // prepare the transaction with xid1 - try - { - _xaResource.prepare(xid1); - } - catch (XAException e) - { - fail("Exception when preparing xid1: " + e.getMessage()); - } - - // send a message using the standard session - try - { - Session nonXASession = _nonXASession; - MessageProducer nonXAProducer = nonXASession.createProducer(_queue); - TextMessage message2 = nonXASession.createTextMessage(); - message2.setText("non XA "); - message2.setLongProperty(_sequenceNumberPropertyName, 2); - nonXAProducer.setDeliveryMode(DeliveryMode.PERSISTENT); - nonXAProducer.send(message2); - // commit that transacted session - nonXASession.commit(); - } - catch (Exception e) - { - fail("Exception thrown when emptying the queue: " + e.getMessage()); - } - // start the xaResource for xid2 - try - { - _xaResource.start(xid2, XAResource.TMNOFLAGS); - } - catch (XAException e) - { - fail("cannot start the transaction with xid1: " + e.getMessage()); - } - // receive a message from queue test we expect it to be the second one - try - { - TextMessage message = (TextMessage) _consumer.receive(1000); - if (message == null || message.getLongProperty(_sequenceNumberPropertyName) != 2) - { - fail("did not receive second message as expected "); - } - } - catch (JMSException e) - { - fail("Exception when receiving second message: " + e.getMessage()); - } - // suspend the transaction - try - { - _xaResource.end(xid2, XAResource.TMSUCCESS); - } - catch (XAException e) - { - fail("Cannot end the transaction with xid2: " + e.getMessage()); - } - // prepare the transaction with xid1 - try - { - _xaResource.prepare(xid2); - } - catch (XAException e) - { - fail("Exception when preparing xid2: " + e.getMessage()); - } - - /////// stop the server now !! - try - { - _logger.debug("stopping broker"); - shutdownServer(); - init(); - } - catch (Exception e) - { - fail("Exception when stopping and restarting the server"); - } - - // get the list of in doubt transactions - try - { - Xid[] inDoubt = _xaResource.recover(XAResource.TMSTARTRSCAN); - if (inDoubt == null) - { - fail("the array of in doubt transactions should not be null "); - } - // At that point we expect only two indoubt transactions: - if (inDoubt.length != 2) - { - fail("in doubt transaction size is diffenrent thatn 2, there are " + inDoubt.length + "in doubt transactions"); - } - - // commit them - for (Xid anInDoubt : inDoubt) - { - if (anInDoubt.equals(xid1)) - { - _logger.debug("rollback xid1 "); - try - { - _xaResource.rollback(anInDoubt); - } - catch (Exception e) - { - System.out.println("PB when aborted xid1"); - } - } - else if (anInDoubt.equals(xid2)) - { - _logger.debug("commit xid2 "); - try - { - _xaResource.commit(anInDoubt, false); - } - catch (Exception e) - { - System.out.println("PB when commiting xid2"); - } - } - } - } - catch (XAException e) - { - e.printStackTrace(); - fail("exception thrown when recovering transactions " + e.getMessage()); - } - // the queue should be empty - try - { - _xaqueueConnection.close(); - Session nonXASession = _nonXASession; - MessageConsumer nonXAConsumer = nonXASession.createConsumer(_queue); - _queueConnection.start(); - TextMessage message1 = (TextMessage) nonXAConsumer.receive(1000); - if (message1 != null) - { - fail("The queue is not empty! "); - } - } - catch (JMSException e) - { - fail("Exception thrown when testin that queue test is empty: " + e.getMessage()); - } - } - } - - /** -------------------------------------------------------------------------------------- **/ - /** ----------------------------- Utility methods --------------------------------------- **/ - /** -------------------------------------------------------------------------------------- **/ - - /** - * get a new queue connection - * - * @return a new queue connection - * @throws JMSException If the JMS provider fails to create the queue connection - * due to some internal error or in case of authentication failure - */ - private XAQueueConnection getNewQueueXAConnection() throws JMSException - { - return _queueFactory.createXAQueueConnection("guest", "guest"); - } - - -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/xa/TopicTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/xa/TopicTest.java deleted file mode 100644 index 027257d761..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/xa/TopicTest.java +++ /dev/null @@ -1,1711 +0,0 @@ -/* 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.qpid.test.unit.xa; - -import javax.jms.*; -import javax.transaction.xa.XAResource; -import javax.transaction.xa.Xid; -import javax.transaction.xa.XAException; - -import junit.framework.TestSuite; - -import java.util.concurrent.atomic.AtomicBoolean; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * - */ -public class TopicTest extends AbstractXATestCase -{ - /* this clas logger */ - private static final Logger _logger = LoggerFactory.getLogger(TopicTest.class); - - /** - * the topic use by all the tests - */ - private static Topic _topic = null; - - /** - * the topic connection factory used by all tests - */ - private static XATopicConnectionFactory _topicFactory = null; - - /** - * standard topic connection - */ - private static XATopicConnection _topicConnection = null; - - /** - * standard topic session created from the standard connection - */ - private static XATopicSession _session = null; - - private static TopicSession _nonXASession = null; - - /** - * the topic name - */ - private static final String TOPICNAME = "xaTopic"; - - /** - * Indicate that a listenere has failed - */ - private static boolean _failure = false; - - /** -------------------------------------------------------------------------------------- **/ - /** ----------------------------- JUnit support ----------------------------------------- **/ - /** -------------------------------------------------------------------------------------- **/ - - /** - * Gets the test suite tests - * - * @return the test suite tests - */ - public static TestSuite getSuite() - { - return new TestSuite(TopicTest.class); - } - - /** - * Run the test suite. - * - * @param args Any command line arguments specified to this class. - */ - public static void main(String args[]) - { - junit.textui.TestRunner.run(getSuite()); - } - - public void tearDown() throws Exception - { - if (!isBroker08()) - { - try - { - _topicConnection.stop(); - _topicConnection.close(); - } - catch (Exception e) - { - fail("Exception thrown when cleaning standard connection: " + e.getStackTrace()); - } - } - super.tearDown(); - } - - /** - * Initialize standard actors - */ - public void init() - { - if (!isBroker08()) - { - // lookup test queue - try - { - _topic = (Topic) getInitialContext().lookup(TOPICNAME); - } - catch (Exception e) - { - fail("cannot lookup test topic " + e.getMessage()); - } - // lookup connection factory - try - { - _topicFactory = getConnectionFactory(); - } - catch (Exception e) - { - fail("enable to lookup connection factory "); - } - // create standard connection - try - { - _topicConnection = getNewTopicXAConnection(); - } - catch (JMSException e) - { - fail("cannot create queue connection: " + e.getMessage()); - } - // create standard session - try - { - _session = _topicConnection.createXATopicSession(); - } - catch (JMSException e) - { - fail("cannot create queue session: " + e.getMessage()); - } - // create a standard session - try - { - _nonXASession = _topicConnection.createTopicSession(true, Session.AUTO_ACKNOWLEDGE); - } - catch (JMSException e) - { - e.printStackTrace(); //To change body of catch statement use Options | File Templates. - } - init(_session, _topic); - } - } - - /** -------------------------------------------------------------------------------------- **/ - /** ----------------------------- Test Suite -------------------------------------------- **/ - /** -------------------------------------------------------------------------------------- **/ - - - /** - * Uses two transactions respectively with xid1 and xid2 that are use to send a message - * within xid1 and xid2. xid2 is committed and xid1 is used to receive the message that was sent within xid2. - * Xid is then committed and a standard transaction is used to receive the message that was sent within xid1. - */ - public void testProducer() - { - if (!isBroker08()) - { - _logger.debug("testProducer"); - Xid xid1 = getNewXid(); - Xid xid2 = getNewXid(); - try - { - Session nonXASession = _nonXASession; - MessageConsumer nonXAConsumer = nonXASession.createConsumer(_topic); - _producer.setDeliveryMode(DeliveryMode.PERSISTENT); - // start the xaResource for xid1 - try - { - _logger.debug("starting tx branch xid1"); - _xaResource.start(xid1, XAResource.TMNOFLAGS); - } - catch (XAException e) - { - e.printStackTrace(); - fail("cannot start the transaction with xid1: " + e.getMessage()); - } - try - { - // start the connection - _topicConnection.start(); - _logger.debug("produce a message with sequence number 1"); - _message.setLongProperty(_sequenceNumberPropertyName, 1); - _producer.send(_message); - } - catch (JMSException e) - { - fail(" cannot send persistent message: " + e.getMessage()); - } - _logger.debug("suspend the transaction branch xid1"); - try - { - _xaResource.end(xid1, XAResource.TMSUSPEND); - } - catch (XAException e) - { - fail("Cannot end the transaction with xid1: " + e.getMessage()); - } - _logger.debug("start the xaResource for xid2"); - try - { - _xaResource.start(xid2, XAResource.TMNOFLAGS); - } - catch (XAException e) - { - fail("cannot start the transaction with xid2: " + e.getMessage()); - } - try - { - _logger.debug("produce a message"); - _message.setLongProperty(_sequenceNumberPropertyName, 2); - _producer.send(_message); - } - catch (JMSException e) - { - fail(" cannot send second persistent message: " + e.getMessage()); - } - _logger.debug("end xid2 and start xid1"); - try - { - _xaResource.end(xid2, XAResource.TMSUCCESS); - _xaResource.start(xid1, XAResource.TMRESUME); - } - catch (XAException e) - { - fail("Exception when ending and starting transactions: " + e.getMessage()); - } - _logger.debug("two phases commit transaction with xid2"); - try - { - int resPrepare = _xaResource.prepare(xid2); - if (resPrepare != XAResource.XA_OK) - { - fail("prepare returned: " + resPrepare); - } - _xaResource.commit(xid2, false); - } - catch (XAException e) - { - fail("Exception thrown when preparing transaction with xid2: " + e.getMessage()); - } - _logger.debug("receiving a message from topic test we expect it to be the second one"); - try - { - TextMessage message = (TextMessage) _consumer.receive(1000); - if (message == null) - { - fail("did not receive second message as expected "); - } - else - { - if (message.getLongProperty(_sequenceNumberPropertyName) != 2) - { - fail("receive wrong message its sequence number is: " + message - .getLongProperty(_sequenceNumberPropertyName)); - } - } - } - catch (JMSException e) - { - fail("Exception when receiving second message: " + e.getMessage()); - } - _logger.debug("end and one phase commit the first transaction"); - try - { - _xaResource.end(xid1, XAResource.TMSUCCESS); - _xaResource.commit(xid1, true); - } - catch (XAException e) - { - fail("Exception thrown when commiting transaction with xid1"); - } - _logger.debug("We should now be able to receive the first and second message"); - try - { - TextMessage message1 = (TextMessage) nonXAConsumer.receive(1000); - if (message1 == null) - { - fail("did not receive first message as expected "); - } - else - { - if (message1.getLongProperty(_sequenceNumberPropertyName) != 2) - { - fail("receive wrong message its sequence number is: " + message1 - .getLongProperty(_sequenceNumberPropertyName)); - } - } - message1 = (TextMessage) nonXAConsumer.receive(1000); - if (message1 == null) - { - fail("did not receive first message as expected "); - } - else - { - if (message1.getLongProperty(_sequenceNumberPropertyName) != 1) - { - fail("receive wrong message its sequence number is: " + message1 - .getLongProperty(_sequenceNumberPropertyName)); - } - } - _logger.debug("commit transacted session"); - nonXASession.commit(); - _logger.debug("Test that the topic is now empty"); - message1 = (TextMessage) nonXAConsumer.receive(1000); - if (message1 != null) - { - fail("receive an unexpected message "); - } - } - catch (JMSException e) - { - fail("Exception thrown when emptying the queue: " + e.getMessage()); - } - } - catch (JMSException e) - { - fail("cannot create standard consumer: " + e.getMessage()); - } - } - } - - - /** - * strategy: Produce a message within Tx1 and commit tx1. consume this message within tx2 and abort tx2. - * Consume the same message within tx3 and commit it. Check that no more message is available. - */ - public void testDurSub() - { - if (!isBroker08()) - { - Xid xid1 = getNewXid(); - Xid xid2 = getNewXid(); - Xid xid3 = getNewXid(); - Xid xid4 = getNewXid(); - String durSubName = "xaSubDurable"; - try - { - TopicSubscriber xaDurSub = _session.createDurableSubscriber(_topic, durSubName); - try - { - _topicConnection.start(); - _logger.debug("start xid1"); - _xaResource.start(xid1, XAResource.TMNOFLAGS); - // start the connection - _topicConnection.start(); - _logger.debug("produce a message with sequence number 1"); - _message.setLongProperty(_sequenceNumberPropertyName, 1); - _producer.send(_message); - _logger.debug("2 phases commit xid1"); - _xaResource.end(xid1, XAResource.TMSUCCESS); - if (_xaResource.prepare(xid1) != XAResource.XA_OK) - { - fail("Problem when preparing tx1 "); - } - _xaResource.commit(xid1, false); - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception when working with xid1: " + e.getMessage()); - } - try - { - _logger.debug("start xid2"); - _xaResource.start(xid2, XAResource.TMNOFLAGS); - _logger.debug("receive the previously produced message"); - TextMessage message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received "); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != 1) - { - fail("wrong sequence number: " + message.getLongProperty(_sequenceNumberPropertyName)); - } - _logger.debug("rollback xid2"); - boolean rollbackOnFailure = false; - try - { - _xaResource.end(xid2, XAResource.TMFAIL); - } - catch (XAException e) - { - if (e.errorCode != XAException.XA_RBROLLBACK) - { - fail("Exception when working with xid2: " + e.getMessage()); - } - rollbackOnFailure = true; - } - if (!rollbackOnFailure) - { - if (_xaResource.prepare(xid2) != XAResource.XA_OK) - { - fail("Problem when preparing tx2 "); - } - _xaResource.rollback(xid2); - } - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception when working with xid2: " + e.getMessage()); - } - try - { - _logger.debug("start xid3"); - _xaResource.start(xid3, XAResource.TMNOFLAGS); - _logger.debug(" receive the previously aborted consumed message"); - TextMessage message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received "); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != 1) - { - fail("wrong sequence number: " + message.getLongProperty(_sequenceNumberPropertyName)); - } - _logger.debug("commit xid3"); - _xaResource.end(xid3, XAResource.TMSUCCESS); - if (_xaResource.prepare(xid3) != XAResource.XA_OK) - { - fail("Problem when preparing tx3 "); - } - _xaResource.commit(xid3, false); - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception when working with xid3: " + e.getMessage()); - } - try - { - _logger.debug("start xid4"); - _xaResource.start(xid4, XAResource.TMNOFLAGS); - _logger.debug("check that topic is empty"); - TextMessage message = (TextMessage) xaDurSub.receive(1000); - if (message != null) - { - fail("An unexpected message was received "); - } - _logger.debug("commit xid4"); - _xaResource.end(xid4, XAResource.TMSUCCESS); - _xaResource.commit(xid4, true); - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception when working with xid4: " + e.getMessage()); - } - } - catch (Exception e) - { - e.printStackTrace(); - fail("problem when creating dur sub: " + e.getMessage()); - } - finally - { - try - { - _session.unsubscribe(durSubName); - } - catch (JMSException e) - { - e.printStackTrace(); - fail("problem when unsubscribing dur sub: " + e.getMessage()); - } - } - } - } - - /** - * strategy: create a XA durable subscriber dusSub, produce 7 messages with the standard session, - * consume 2 messages respectively with tx1, tx2 and tx3 - * abort tx2, we now expect to receive messages 3 and 4 first! Receive 3 messages within tx1 i.e. 34 and 7! - * commit tx3 - * abort tx1: we now expect that only messages 5 and 6 are definitly consumed! - * start tx4 and consume messages 1 - 4 and 7 - * commit tx4 - * Now the topic should be empty! - */ - public void testMultiMessagesDurSub() - { - if (!isBroker08()) - { - Xid xid1 = getNewXid(); - Xid xid2 = getNewXid(); - Xid xid3 = getNewXid(); - Xid xid4 = getNewXid(); - Xid xid6 = getNewXid(); - String durSubName = "xaSubDurable"; - TextMessage message; - try - { - TopicSubscriber xaDurSub = _session.createDurableSubscriber(_topic, durSubName); - try - { - Session txSession = _nonXASession; - MessageProducer txProducer = txSession.createProducer(_topic); - _logger.debug("produce 10 persistent messages"); - txProducer.setDeliveryMode(DeliveryMode.PERSISTENT); - _topicConnection.start(); - for (int i = 1; i <= 7; i++) - { - _message.setLongProperty(_sequenceNumberPropertyName, i); - txProducer.send(_message); - } - // commit txSession - txSession.commit(); - } - catch (JMSException e) - { - e.printStackTrace(); - fail("Exception thrown when producing messages: " + e.getMessage()); - } - - try - { - _logger.debug(" consume 2 messages respectively with tx1, tx2 and tx3"); - //----- start xid1 - _xaResource.start(xid1, XAResource.TMNOFLAGS); - // receive the 2 first messages - for (int i = 1; i <= 2; i++) - { - message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received! expected: " + i); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != i) - { - fail("wrong sequence number: " + message.getLongProperty(_sequenceNumberPropertyName)); - } - } - _xaResource.end(xid1, XAResource.TMSUSPEND); - //----- start xid2 - _xaResource.start(xid2, XAResource.TMNOFLAGS); - // receive the 2 first messages - for (int i = 3; i <= 4; i++) - { - message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received! expected: " + i); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != i) - { - fail("wrong sequence number: " + message.getLongProperty(_sequenceNumberPropertyName)); - } - } - _xaResource.end(xid2, XAResource.TMSUSPEND); - //----- start xid3 - _xaResource.start(xid3, XAResource.TMNOFLAGS); - // receive the 2 first messages - for (int i = 5; i <= 6; i++) - { - message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received! expected: " + i); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != i) - { - fail("wrong sequence number: " + message.getLongProperty(_sequenceNumberPropertyName)); - } - } - _xaResource.end(xid3, XAResource.TMSUCCESS); - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception thrown when consumming 6 first messages: " + e.getMessage()); - } - try - { - _logger.debug("abort tx2, we now expect to receive messages 3, 4 and 7"); - _xaResource.start(xid2, XAResource.TMRESUME); - _xaResource.end(xid2, XAResource.TMSUCCESS); - _xaResource.prepare(xid2); - _xaResource.rollback(xid2); - // receive 3 message within tx1: 3, 4 and 7 - _xaResource.start(xid1, XAResource.TMRESUME); - _logger.debug(" 3, 4 and 7"); - for (int i = 1; i <= 3; i++) - { - message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received! expected: " + 3); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) <= 2 || 5 == message - .getLongProperty(_sequenceNumberPropertyName) || message - .getLongProperty(_sequenceNumberPropertyName) == 6) - { - fail("wrong sequence number: " + message - .getLongProperty(_sequenceNumberPropertyName)); - } - } - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception thrown when consumming message: 3, 4 and 7: " + e.getMessage()); - } - - try - { - _xaResource.end(xid1, XAResource.TMSUCCESS); - _logger.debug(" commit tx3"); - _xaResource.commit(xid3, true); - _logger.debug("abort tx1"); - _xaResource.prepare(xid1); - _xaResource.rollback(xid1); - } - catch (XAException e) - { - e.printStackTrace(); - fail("XAException thrown when committing tx3 or aborting tx1: " + e.getMessage()); - } - - try - { - // consume messages 1 - 4 + 7 - //----- start xid1 - _xaResource.start(xid4, XAResource.TMNOFLAGS); - for (int i = 1; i <= 5; i++) - { - - message = (TextMessage) xaDurSub.receive(1000); - _logger.debug(" received message: " + message.getLongProperty(_sequenceNumberPropertyName)); - if (message == null) - { - fail("no message received! expected: " + i); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) == 5 || message - .getLongProperty(_sequenceNumberPropertyName) == 6) - { - fail("wrong sequence number: " + message.getLongProperty(_sequenceNumberPropertyName)); - } - } - _xaResource.end(xid4, XAResource.TMSUCCESS); - _xaResource.prepare(xid4); - _xaResource.commit(xid4, false); - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception thrown in last phase: " + e.getMessage()); - } - // now the topic should be empty!! - try - { - // start xid6 - _xaResource.start(xid6, XAResource.TMNOFLAGS); - // should now be empty - message = (TextMessage) xaDurSub.receive(1000); - if (message != null) - { - fail("An unexpected message was received " + message - .getLongProperty(_sequenceNumberPropertyName)); - } - // commit xid6 - _xaResource.end(xid6, XAResource.TMSUCCESS); - _xaResource.commit(xid6, true); - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception when working with xid6: " + e.getMessage()); - } - } - catch (Exception e) - { - e.printStackTrace(); - fail("problem when creating dur sub: " + e.getMessage()); - } - finally - { - try - { - _session.unsubscribe(durSubName); - } - catch (JMSException e) - { - e.printStackTrace(); - fail("problem when unsubscribing dur sub: " + e.getMessage()); - } - } - } - } - - /** - * strategy: create a XA durable subscriber dusSub, produce 10 messages with the standard session, - * consume 2 messages respectively with tx1, tx2 and tx3 - * prepare xid2 and xid3 - * crash the server - * Redo the job for xid1 that has been aborted by server crash - * abort tx2, we now expect to receive messages 3 and 4 first! Receive 3 messages within tx1 i.e. 34 and 7! - * commit tx3 - * abort tx1: we now expect that only messages 5 and 6 are definitly consumed! - * start tx4 and consume messages 1 - 4 - * start tx5 and consume messages 7 - 10 - * abort tx4 - * consume messages 1-4 with tx5 - * commit tx5 - * Now the topic should be empty! - */ - public void testMultiMessagesDurSubCrash() - { - if (!isBroker08()) - { - Xid xid1 = getNewXid(); - Xid xid2 = getNewXid(); - Xid xid3 = getNewXid(); - Xid xid4 = getNewXid(); - Xid xid5 = getNewXid(); - Xid xid6 = getNewXid(); - String durSubName = "xaSubDurable"; - TextMessage message; - try - { - TopicSubscriber xaDurSub = _session.createDurableSubscriber(_topic, durSubName); - try - { - Session txSession = _nonXASession; - MessageProducer txProducer = txSession.createProducer(_topic); - // produce 10 persistent messages - txProducer.setDeliveryMode(DeliveryMode.PERSISTENT); - _topicConnection.start(); - for (int i = 1; i <= 10; i++) - { - _message.setLongProperty(_sequenceNumberPropertyName, i); - txProducer.send(_message); - } - // commit txSession - txSession.commit(); - } - catch (JMSException e) - { - e.printStackTrace(); - fail("Exception thrown when producing messages: " + e.getMessage()); - } - try - { - // consume 2 messages respectively with tx1, tx2 and tx3 - //----- start xid1 - _xaResource.start(xid1, XAResource.TMNOFLAGS); - // receive the 2 first messages - for (int i = 1; i <= 2; i++) - { - message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received! expected: " + i); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != i) - { - fail("wrong sequence number: " + message.getLongProperty(_sequenceNumberPropertyName)); - } - } - _xaResource.end(xid1, XAResource.TMSUCCESS); - //----- start xid2 - _xaResource.start(xid2, XAResource.TMNOFLAGS); - // receive the 2 first messages - for (int i = 3; i <= 4; i++) - { - message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received! expected: " + i); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != i) - { - fail("wrong sequence number: " + message.getLongProperty(_sequenceNumberPropertyName)); - } - } - _xaResource.end(xid2, XAResource.TMSUCCESS); - //----- start xid3 - _xaResource.start(xid3, XAResource.TMNOFLAGS); - // receive the 2 first messages - for (int i = 5; i <= 6; i++) - { - message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received! expected: " + i); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != i) - { - fail("wrong sequence number: " + message.getLongProperty(_sequenceNumberPropertyName)); - } - } - _xaResource.end(xid3, XAResource.TMSUCCESS); - // prepare tx2 and tx3 - - _xaResource.prepare(xid2); - _xaResource.prepare(xid3); - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception thrown when consumming 6 first messages: " + e.getMessage()); - } - /////// stop the broker now !! - try - { - shutdownServer(); - init(); - } - catch (Exception e) - { - fail("Exception when stopping and restarting the server"); - } - // get the list of in doubt transactions - try - { - _topicConnection.start(); - // reconnect to dursub! - xaDurSub = _session.createDurableSubscriber(_topic, durSubName); - Xid[] inDoubt = _xaResource.recover(XAResource.TMSTARTRSCAN); - if (inDoubt == null) - { - fail("the array of in doubt transactions should not be null "); - } - // At that point we expect only two indoubt transactions: - if (inDoubt.length != 2) - { - fail("in doubt transaction size is diffenrent than 2, there are " + inDoubt.length + "in doubt transactions"); - } - } - catch (XAException e) - { - e.printStackTrace(); - fail("exception thrown when recovering transactions " + e.getMessage()); - } - try - { - // xid1 has been aborted redo the job! - // consume 2 messages with tx1 - //----- start xid1 - _xaResource.start(xid1, XAResource.TMNOFLAGS); - // receive the 2 first messages - for (int i = 1; i <= 2; i++) - { - message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received! expected: " + i); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != i) - { - fail("wrong sequence number: " + message.getLongProperty(_sequenceNumberPropertyName)); - } - } - _xaResource.end(xid1, XAResource.TMSUSPEND); - // abort tx2, we now expect to receive messages 3 and 4 first! - _xaResource.rollback(xid2); - - // receive 3 message within tx1: 3, 4 and 7 - _xaResource.start(xid1, XAResource.TMRESUME); - // receive messages 3, 4 and 7 - message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received! expected: " + 3); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != 3) - { - fail("wrong sequence number: " + message - .getLongProperty(_sequenceNumberPropertyName) + " 3 was expected"); - } - message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received! expected: " + 4); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != 4) - { - fail("wrong sequence number: " + message - .getLongProperty(_sequenceNumberPropertyName) + " 4 was expected"); - } - message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received! expected: " + 7); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != 7) - { - fail("wrong sequence number: " + message - .getLongProperty(_sequenceNumberPropertyName) + " 7 was expected"); - } - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception thrown when consumming message: 3, 4 and 7: " + e.getMessage()); - } - - try - { - _xaResource.end(xid1, XAResource.TMSUSPEND); - // commit tx3 - _xaResource.commit(xid3, false); - // abort tx1 - _xaResource.prepare(xid1); - _xaResource.rollback(xid1); - } - catch (XAException e) - { - e.printStackTrace(); - fail("XAException thrown when committing tx3 or aborting tx1: " + e.getMessage()); - } - - try - { - // consume messages 1 - 4 - //----- start xid1 - _xaResource.start(xid4, XAResource.TMNOFLAGS); - for (int i = 1; i <= 4; i++) - { - message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received! expected: " + i); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != i) - { - fail("wrong sequence number: " + message.getLongProperty(_sequenceNumberPropertyName)); - } - } - _xaResource.end(xid4, XAResource.TMSUSPEND); - // consume messages 8 - 10 - _xaResource.start(xid5, XAResource.TMNOFLAGS); - for (int i = 7; i <= 10; i++) - { - message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received! expected: " + i); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != i) - { - fail("wrong sequence number: " + message.getLongProperty(_sequenceNumberPropertyName)); - } - } - _xaResource.end(xid5, XAResource.TMSUSPEND); - // abort tx4 - _xaResource.prepare(xid4); - _xaResource.rollback(xid4); - // consume messages 1-4 with tx5 - _xaResource.start(xid5, XAResource.TMRESUME); - for (int i = 1; i <= 4; i++) - { - message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received! expected: " + i); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != i) - { - fail("wrong sequence number: " + message.getLongProperty(_sequenceNumberPropertyName)); - } - } - _xaResource.end(xid5, XAResource.TMSUSPEND); - // commit tx5 - _xaResource.prepare(xid5); - _xaResource.commit(xid5, false); - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception thrown in last phase: " + e.getMessage()); - } - // now the topic should be empty!! - try - { - // start xid6 - _xaResource.start(xid6, XAResource.TMNOFLAGS); - // should now be empty - message = (TextMessage) xaDurSub.receive(1000); - if (message != null) - { - fail("An unexpected message was received " + message - .getLongProperty(_sequenceNumberPropertyName)); - } - // commit xid6 - _xaResource.end(xid6, XAResource.TMSUSPEND); - _xaResource.commit(xid6, true); - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception when working with xid6: " + e.getMessage()); - } - } - catch (Exception e) - { - e.printStackTrace(); - fail("problem when creating dur sub: " + e.getMessage()); - } - finally - { - try - { - _session.unsubscribe(durSubName); - } - catch (JMSException e) - { - e.printStackTrace(); - fail("problem when unsubscribing dur sub: " + e.getMessage()); - } - } - } - } - - - /** - * strategy: Produce a message within Tx1 and commit tx1. a durable subscriber then receives that message within tx2 - * that is then prepared. - * Shutdown the server and get the list of in doubt transactions: - * we expect tx2, Tx2 is aborted and the message consumed within tx3 that is committed we then check that the topic is empty. - */ - public void testDurSubCrash() - { - if (!isBroker08()) - { - Xid xid1 = getNewXid(); - Xid xid2 = getNewXid(); - Xid xid3 = getNewXid(); - Xid xid4 = getNewXid(); - String durSubName = "xaSubDurable"; - try - { - TopicSubscriber xaDurSub = _session.createDurableSubscriber(_topic, durSubName); - try - { - _topicConnection.start(); - //----- start xid1 - _xaResource.start(xid1, XAResource.TMNOFLAGS); - // start the connection - _topicConnection.start(); - // produce a message with sequence number 1 - _message.setLongProperty(_sequenceNumberPropertyName, 1); - _producer.send(_message); - // commit - _xaResource.end(xid1, XAResource.TMSUCCESS); - if (_xaResource.prepare(xid1) != XAResource.XA_OK) - { - fail("Problem when preparing tx1 "); - } - _xaResource.commit(xid1, false); - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception when working with xid1: " + e.getMessage()); - } - try - { - // start xid2 - _xaResource.start(xid2, XAResource.TMNOFLAGS); - // receive the previously produced message - TextMessage message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received "); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != 1) - { - fail("wrong sequence number: " + message.getLongProperty(_sequenceNumberPropertyName)); - } - // prepare xid2 - _xaResource.end(xid2, XAResource.TMSUCCESS); - if (_xaResource.prepare(xid2) != XAResource.XA_OK) - { - fail("Problem when preparing tx2 "); - } - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception when working with xid2: " + e.getMessage()); - } - - /////// stop the server now !! - try - { - shutdownServer(); - init(); - } - catch (Exception e) - { - fail("Exception when stopping and restarting the server"); - } - - // get the list of in doubt transactions - try - { - _topicConnection.start(); - // reconnect to dursub! - xaDurSub = _session.createDurableSubscriber(_topic, durSubName); - Xid[] inDoubt = _xaResource.recover(XAResource.TMSTARTRSCAN); - if (inDoubt == null) - { - fail("the array of in doubt transactions should not be null "); - } - // At that point we expect only two indoubt transactions: - if (inDoubt.length != 1) - { - fail("in doubt transaction size is diffenrent than 2, there are " + inDoubt.length + "in doubt transactions"); - } - - // commit them - for (Xid anInDoubt : inDoubt) - { - if (anInDoubt.equals(xid2)) - { - System.out.println("aborting xid2 "); - try - { - _xaResource.rollback(anInDoubt); - } - catch (Exception e) - { - e.printStackTrace(); - fail("exception when aborting xid2 "); - } - } - else - { - System.out.println("XID2 is not in doubt "); - } - } - } - catch (XAException e) - { - e.printStackTrace(); - fail("exception thrown when recovering transactions " + e.getMessage()); - } - - try - { - // start xid3 - _xaResource.start(xid3, XAResource.TMNOFLAGS); - // receive the previously produced message and aborted - TextMessage message = (TextMessage) xaDurSub.receive(1000); - if (message == null) - { - fail("no message received "); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != 1) - { - fail("wrong sequence number: " + message.getLongProperty(_sequenceNumberPropertyName)); - } - // commit xid3 - _xaResource.end(xid3, XAResource.TMSUCCESS); - if (_xaResource.prepare(xid3) != XAResource.XA_OK) - { - fail("Problem when preparing tx3 "); - } - _xaResource.commit(xid3, false); - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception when working with xid3: " + e.getMessage()); - } - try - { - // start xid4 - _xaResource.start(xid4, XAResource.TMNOFLAGS); - // should now be empty - TextMessage message = (TextMessage) xaDurSub.receive(1000); - if (message != null) - { - fail("An unexpected message was received " + message - .getLongProperty(_sequenceNumberPropertyName)); - } - // commit xid4 - _xaResource.end(xid4, XAResource.TMSUCCESS); - _xaResource.commit(xid4, true); - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception when working with xid4: " + e.getMessage()); - } - } - catch (Exception e) - { - e.printStackTrace(); - fail("problem when creating dur sub: " + e.getMessage()); - } - finally - { - try - { - _session.unsubscribe(durSubName); - } - catch (JMSException e) - { - e.printStackTrace(); - fail("problem when unsubscribing dur sub: " + e.getMessage()); - } - } - } - } - - /** - * strategy: Produce a message within Tx1 and prepare tx1. Shutdown the server and get the list of indoubt transactions: - * we expect tx1, Tx1 is committed so we expect the test topic not to be empty! - */ - public void testRecover() - { - if (!isBroker08()) - { - Xid xid1 = getNewXid(); - String durSubName = "test1"; - try - { - // create a dummy durable subscriber to be sure that messages are persisted! - _nonXASession.createDurableSubscriber(_topic, durSubName); - // start the xaResource for xid1 - try - { - _xaResource.start(xid1, XAResource.TMNOFLAGS); - } - catch (XAException e) - { - fail("cannot start the transaction with xid1: " + e.getMessage()); - } - try - { - // start the connection - _topicConnection.start(); - // produce a message with sequence number 1 - _message.setLongProperty(_sequenceNumberPropertyName, 1); - _producer.send(_message); - } - catch (JMSException e) - { - fail(" cannot send persistent message: " + e.getMessage()); - } - // suspend the transaction - try - { - _xaResource.end(xid1, XAResource.TMSUCCESS); - } - catch (XAException e) - { - fail("Cannot end the transaction with xid1: " + e.getMessage()); - } - // prepare the transaction with xid1 - try - { - _xaResource.prepare(xid1); - } - catch (XAException e) - { - fail("Exception when preparing xid1: " + e.getMessage()); - } - - /////// stop the server now !! - try - { - shutdownServer(); - init(); - } - catch (Exception e) - { - fail("Exception when stopping and restarting the server"); - } - - try - { - MessageConsumer nonXAConsumer = _nonXASession.createDurableSubscriber(_topic, durSubName); - _topicConnection.start(); - // get the list of in doubt transactions - try - { - Xid[] inDoubt = _xaResource.recover(XAResource.TMSTARTRSCAN); - if (inDoubt == null) - { - fail("the array of in doubt transactions should not be null "); - } - // At that point we expect only two indoubt transactions: - if (inDoubt.length != 1) - { - fail("in doubt transaction size is diffenrent thatn 2, there are " + inDoubt.length + "in doubt transactions"); - } - // commit them - for (Xid anInDoubt : inDoubt) - { - if (anInDoubt.equals(xid1)) - { - _logger.debug("committing xid1 "); - try - { - _xaResource.commit(anInDoubt, false); - } - catch (Exception e) - { - _logger.debug("PB when aborted xid1"); - e.printStackTrace(); - fail("exception when committing xid1 "); - } - } - else - { - _logger.debug("XID1 is not in doubt "); - } - } - } - catch (XAException e) - { - e.printStackTrace(); - fail("exception thrown when recovering transactions " + e.getMessage()); - } - _logger.debug("the topic should not be empty"); - TextMessage message1 = (TextMessage) nonXAConsumer.receive(1000); - if (message1 == null) - { - fail("The topic is empty! "); - } - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception thrown when testin that queue test is empty: " + e.getMessage()); - } - } - catch (JMSException e) - { - e.printStackTrace(); - fail("cannot create dummy durable subscriber: " + e.getMessage()); - } - finally - { - try - { - // unsubscribe the dummy durable subscriber - TopicSession nonXASession = _nonXASession; - nonXASession.unsubscribe(durSubName); - } - catch (JMSException e) - { - fail("cannot unsubscribe durable subscriber: " + e.getMessage()); - } - } - } - } - - /** - * strategy: - * create a standard durable subscriber - * produce 3 messages - * consume the first message with that durable subscriber - * close the standard session that deactivates the durable subscriber - * migrate the durable subscriber to an xa one - * consume the second message with that xa durable subscriber - * close the xa session that deactivates the durable subscriber - * reconnect to the durable subscriber with a standard session - * consume the two remaining messages and check that the topic is empty! - */ - public void testMigrateDurableSubscriber() - { - if (!isBroker08()) - { - Xid xid1 = getNewXid(); - Xid xid2 = getNewXid(); - String durSubName = "DurableSubscriberMigrate"; - try - { - Session stSession = _nonXASession; - MessageProducer producer = stSession.createProducer(_topic); - _logger.debug("Create a standard durable subscriber!"); - TopicSubscriber durSub = stSession.createDurableSubscriber(_topic, durSubName); - TopicSubscriber durSub1 = stSession.createDurableSubscriber(_topic, durSubName + "_second"); - TextMessage message; - producer.setDeliveryMode(DeliveryMode.PERSISTENT); - _topicConnection.start(); - _logger.debug("produce 3 messages"); - for (int i = 1; i <= 3; i++) - { - _message.setLongProperty(_sequenceNumberPropertyName, i); - //producer.send( _message ); - producer.send(_message, DeliveryMode.PERSISTENT, 9 - i, 0); - stSession.commit(); - } - _logger.debug("consume the first message with that durable subscriber"); - message = (TextMessage) durSub.receive(1000); - if (message == null) - { - fail("no message received "); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != 1) - { - fail("wrong sequence number: " + message.getLongProperty(_sequenceNumberPropertyName)); - } - // commit the standard session - stSession.commit(); - _logger.debug("first message consumed "); - // close the session that deactivates the durable subscriber - stSession.close(); - _logger.debug("migrate the durable subscriber to an xa one"); - _xaResource.start(xid1, XAResource.TMNOFLAGS); - durSub = _session.createDurableSubscriber(_topic, durSubName); - _logger.debug(" consume the second message with that xa durable subscriber and abort it"); - message = (TextMessage) durSub.receive(1000); - if (message == null) - { - fail("no message received "); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != 2) - { - System.out.println("wrong sequence number, 2 expected, received: " + message - .getLongProperty(_sequenceNumberPropertyName)); - } - _xaResource.end(xid1, XAResource.TMSUCCESS); - _xaResource.prepare(xid1); - _xaResource.rollback(xid1); - _logger.debug("close the session that deactivates the durable subscriber"); - _session.close(); - _logger.debug("create a new standard session"); - stSession = _topicConnection.createTopicSession(true, 1); - _logger.debug("reconnect to the durable subscriber"); - durSub = stSession.createDurableSubscriber(_topic, durSubName); - durSub1 = stSession.createDurableSubscriber(_topic, durSubName + "_second"); - _logger.debug("Reconnected to durablse subscribers"); - _logger.debug(" consume the 2 remaining messages"); - message = (TextMessage) durSub.receive(1000); - if (message == null) - { - fail("no message received "); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != 2) - { - System.out.println("wrong sequence number, 2 expected, received: " + message - .getLongProperty(_sequenceNumberPropertyName)); - } - // consume the third message with that xa durable subscriber - message = (TextMessage) durSub.receive(1000); - if (message == null) - { - fail("no message received "); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != 3) - { - System.out.println("wrong sequence number, 3 expected, received: " + message - .getLongProperty(_sequenceNumberPropertyName)); - } - stSession.commit(); - _logger.debug("the topic should be empty now"); - message = (TextMessage) durSub.receive(1000); - if (message != null) - { - fail("Received unexpected message "); - } - stSession.commit(); - _logger.debug(" use dursub1 to receive all the 3 messages"); - for (int i = 1; i <= 3; i++) - { - message = (TextMessage) durSub1.receive(1000); - if (message == null) - { - _logger.debug("no message received "); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != i) - { - fail("wrong sequence number, " + i + " expected, received: " + message - .getLongProperty(_sequenceNumberPropertyName)); - } - } - stSession.commit(); - // send a non persistent message to check that all persistent messages are deleted - producer = stSession.createProducer(_topic); - producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); - producer.send(_message); - stSession.commit(); - message = (TextMessage) durSub.receive(1000); - if (message == null) - { - fail("message not received "); - } - message = (TextMessage) durSub1.receive(1000); - if (message == null) - { - fail("message not received "); - } - stSession.commit(); - stSession.close(); - _logger.debug(" now create a standard non transacted session and reconnect to the durable xubscriber"); - TopicConnection stConnection = - _topicConnection; //_topicFactory.createTopicConnection("guest", "guest"); - TopicSession autoAclSession = stConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - TopicPublisher publisher = autoAclSession.createPublisher(_topic); - durSub = autoAclSession.createDurableSubscriber(_topic, durSubName); - stConnection.start(); - // produce 3 persistent messages - for (int i = 1; i <= 3; i++) - { - _message.setLongProperty(_sequenceNumberPropertyName, i); - //producer.send( _message ); - publisher.send(_message, DeliveryMode.PERSISTENT, 9 - i, 0); - } - _logger.debug(" use dursub to receive all the 3 messages"); - for (int i = 1; i <= 3; i++) - { - message = (TextMessage) durSub.receive(1000); - if (message == null) - { - System.out.println("no message received "); - } - else if (message.getLongProperty(_sequenceNumberPropertyName) != i) - { - System.out.println("wrong sequence number, " + i + " expected, received: " + message - .getLongProperty(_sequenceNumberPropertyName)); - } - } - - _logger.debug("now set a message listener"); - AtomicBoolean lock = new AtomicBoolean(true); - reset(); - stConnection.stop(); - durSub.setMessageListener(new TopicListener(1, 3, lock)); - _logger.debug(" produce 3 persistent messages"); - for (int i = 1; i <= 3; i++) - { - _message.setLongProperty(_sequenceNumberPropertyName, i); - //producer.send( _message ); - publisher.send(_message, DeliveryMode.PERSISTENT, 9 - i, 0); - } - // start the connection - stConnection.start(); - while (lock.get()) - { - synchronized (lock) - { - lock.wait(); - } - } - if (getFailureStatus()) - { - fail("problem with message listener"); - } - stConnection.stop(); - durSub.setMessageListener(null); - _logger.debug(" do the same with an xa session"); - // produce 3 persistent messages - for (int i = 1; i <= 3; i++) - { - _message.setLongProperty(_sequenceNumberPropertyName, i); - //producer.send( _message ); - publisher.send(_message, DeliveryMode.PERSISTENT, 9 - i, 0); - } - //stConnection.close(); - autoAclSession.close(); - _logger.debug(" migrate the durable subscriber to an xa one"); - _session = _topicConnection.createXATopicSession(); - _xaResource = _session.getXAResource(); - _xaResource.start(xid2, XAResource.TMNOFLAGS); - durSub = _session.createDurableSubscriber(_topic, durSubName); - lock = new AtomicBoolean(); - reset(); - _topicConnection.stop(); - durSub.setMessageListener(new TopicListener(1, 3, lock)); - // start the connection - _topicConnection.start(); - while (lock.get()) - { - synchronized (lock) - { - lock.wait(); - } - } - if (getFailureStatus()) - { - fail("problem with XA message listener"); - } - _xaResource.end(xid2, XAResource.TMSUCCESS); - _xaResource.commit(xid2, true); - } - catch (Exception e) - { - e.printStackTrace(); - fail("Exception thrown: " + e.getMessage()); - } - finally - { - try - { - _topicConnection.createXASession().unsubscribe(durSubName); - _topicConnection.createXASession().unsubscribe(durSubName + "_second"); - } - catch (JMSException e) - { - fail("Exception thrown when unsubscribing durable subscriber " + e.getMessage()); - } - } - } - } - - /** -------------------------------------------------------------------------------------- **/ - /** ----------------------------- Utility methods --------------------------------------- **/ - /** -------------------------------------------------------------------------------------- **/ - - /** - * get a new queue connection - * - * @return a new queue connection - * @throws javax.jms.JMSException If the JMS provider fails to create the queue connection - * due to some internal error or in case of authentication failure - */ - private XATopicConnection getNewTopicXAConnection() throws JMSException - { - return _topicFactory.createXATopicConnection("guest", "guest"); - } - - public static void failure() - { - _failure = true; - } - - public static void reset() - { - _failure = false; - } - - public static boolean getFailureStatus() - { - return _failure; - } - - private class TopicListener implements MessageListener - { - private long _counter; - private long _end; - private final AtomicBoolean _lock; - - public TopicListener(long init, long end, AtomicBoolean lock) - { - _counter = init; - _end = end; - _lock = lock; - } - - public void onMessage(Message message) - { - long seq = 0; - try - { - seq = message.getLongProperty(TopicTest._sequenceNumberPropertyName); - } - catch (JMSException e) - { - e.printStackTrace(); - TopicTest.failure(); - _lock.set(false); - synchronized (_lock) - { - _lock.notifyAll(); - } - } - if (seq != _counter) - { - System.out.println("received message " + seq + " expected " + _counter); - TopicTest.failure(); - _lock.set(false); - synchronized (_lock) - { - _lock.notifyAll(); - } - } - _counter++; - if (_counter > _end) - { - _lock.set(false); - synchronized (_lock) - { - _lock.notifyAll(); - } - } - } - } - -} diff --git a/java/client/src/test/java/org/apache/qpid/testutil/Config.java b/java/client/src/test/java/org/apache/qpid/testutil/Config.java deleted file mode 100644 index b777cf93b6..0000000000 --- a/java/client/src/test/java/org/apache/qpid/testutil/Config.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * - * 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.qpid.testutil; - -import javax.jms.Connection; -import javax.jms.Destination; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQHeadersExchange; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.exchange.ExchangeDefaults; - -public class Config -{ - public static final String QUEUE = "queue"; - public static final String TOPIC = "topic"; - public static final String HEADERS = "headers"; - - private String host = "localhost"; - private int port = 5672; - private String type; - private String name = "simple_test_queue"; - - public Config() - { - this("localhost", 5672, QUEUE, "simple_test_queue"); - } - - public Config(String host, int port, String type, String name) - { - setHost(host); - setPort(port); - setType(type); - setName(name); - } - - public String getHost() - { - return host; - } - - public void setHost(String host) - { - this.host = host; - } - - public int getPort() - { - return port; - } - - public void setPort(int port) - { - this.port = port; - } - - public String getType() - { - return type; - } - - public void setType(String type) - { - this.type = type; - } - - public boolean isQueue() - { - return QUEUE.equalsIgnoreCase(type); - } - - public boolean isTopic() - { - return TOPIC.equalsIgnoreCase(type); - } - - private boolean isHeaders() - { - return HEADERS.equalsIgnoreCase(type); - } - - public void setQueue(boolean queue) - { - type = queue ? QUEUE : TOPIC; - } - - public String getName() - { - return name; - } - - public void setName(String name) - { - this.name = name; - } - - public Destination getDestination() - { - if(isQueue()) - { - System.out.println("Using queue named " + name); - return new AMQQueue(ExchangeDefaults.DIRECT_EXCHANGE_NAME,name); - } - else if(isTopic()) - { - System.out.println("Using topic named " + name); - return new AMQTopic(ExchangeDefaults.TOPIC_EXCHANGE_NAME,name); - } - else if(isHeaders()) - { - System.out.println("Using headers exhange named " + name); - return new AMQHeadersExchange(name); - } - return null; - } - - public Connection getConnection() throws Exception - { - System.out.println("Connecting to " + host + " on " + port + "..."); - return new AMQConnection(host, port, "guest", "guest", "Client" + System.currentTimeMillis(), "/test"); - } - - public boolean setOptions(String[] argv) - { - try - { - for(int i = 0; i < argv.length - 1; i += 2) - { - String key = argv[i]; - String value = argv[i+1]; - setOption(key, value); - } - return true; - } - catch(Exception e) - { - System.out.println(e.getMessage()); - } - return false; - } - - private void setOption(String key, String value) - { - if("-host".equalsIgnoreCase(key)) - { - setHost(value); - } - else if("-port".equalsIgnoreCase(key)) - { - try - { - setPort(Integer.parseInt(value)); - } - catch(NumberFormatException e) - { - throw new RuntimeException("Bad port number: " + value, e); - } - } - else if("-name".equalsIgnoreCase(key)) - { - setName(value); - } - else if("-type".equalsIgnoreCase(key)) - { - if(QUEUE.equalsIgnoreCase(value) - || TOPIC.equalsIgnoreCase(value) - || HEADERS.equalsIgnoreCase(value)) - { - type = value; - } - else{ - throw new RuntimeException("Bad destination type: " + value); - } - } - else - { - System.out.println("Ignoring unrecognised option: " + key); - } - } -} diff --git a/java/client/src/test/java/org/apache/qpid/testutil/QpidClientConnection.java b/java/client/src/test/java/org/apache/qpid/testutil/QpidClientConnection.java deleted file mode 100644 index e99a51e1c7..0000000000 --- a/java/client/src/test/java/org/apache/qpid/testutil/QpidClientConnection.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * - * 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.qpid.testutil; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQConnectionFactory; -import org.apache.qpid.client.AMQConnectionURL; -import org.apache.qpid.client.JMSAMQException; -import org.apache.qpid.url.URLSyntaxException; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.Connection; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.TextMessage; - -public class QpidClientConnection extends QpidTestCase implements ExceptionListener -{ - private static final Logger _logger = LoggerFactory.getLogger(QpidClientConnection.class); - - private boolean transacted = true; - private int ackMode = Session.CLIENT_ACKNOWLEDGE; - private Connection connection; - - private String virtualHost; - private String brokerlist; - private int prefetch; - protected Session session; - protected boolean connected; - - public QpidClientConnection(String broker) - { - super(); - setVirtualHost("/test"); - setBrokerList(broker); - setPrefetch(5000); - } - - - public Connection getConnection() - { - return connection; - } - - public void connect() throws JMSException - { - if (!connected) - { - /* - * amqp://[user:pass@][clientid]/virtualhost? - * brokerlist='[transport://]host[:port][?option='value'[&option='value']];' - * [&failover='method[?option='value'[&option='value']]'] - * [&option='value']" - */ - String brokerUrl = "amqp://guest:guest@" + virtualHost + "?brokerlist='" + brokerlist + "'"; - try - { - _logger.info("connecting to Qpid :" + brokerUrl); - connection = getConnection("guest", "guest") ; - // register exception listener - connection.setExceptionListener(this); - - session = ((AMQConnection) connection).createSession(transacted, ackMode, prefetch); - - _logger.info("starting connection"); - connection.start(); - - connected = true; - } - catch (Exception e) - { - throw new JMSAMQException("URL syntax error in [" + brokerUrl + "]: " + e.getMessage(), e); - } - } - } - - public void disconnect() throws Exception - { - if (connected) - { - session.commit(); - session.close(); - connection.close(); - connected = false; - _logger.info("disconnected"); - } - } - - public void disconnectWithoutCommit() throws JMSException - { - if (connected) - { - session.close(); - connection.close(); - connected = false; - _logger.info("disconnected without commit"); - } - } - - public String getBrokerList() - { - return brokerlist; - } - - public void setBrokerList(String brokerlist) - { - this.brokerlist = brokerlist; - } - - public String getVirtualHost() - { - return virtualHost; - } - - public void setVirtualHost(String virtualHost) - { - this.virtualHost = virtualHost; - } - - public void setPrefetch(int prefetch) - { - this.prefetch = prefetch; - } - - /** override as necessary */ - public void onException(JMSException exception) - { - _logger.info("ExceptionListener event: error " + exception.getErrorCode() + ", message: " + exception.getMessage()); - } - - public boolean isConnected() - { - return connected; - } - - public Session getSession() - { - return session; - } - - /** - * Put a String as a text messages, repeat n times. A null payload will result in a null message. - * - * @param queueName The queue name to put to - * @param payload the content of the payload - * @param copies the number of messages to put - * - * @throws javax.jms.JMSException any exception that occurs - */ - public void put(String queueName, String payload, int copies) throws JMSException - { - if (!connected) - { - connect(); - } - - _logger.info("putting to queue " + queueName); - Queue queue = session.createQueue(queueName); - - final MessageProducer sender = session.createProducer(queue); - - for (int i = 0; i < copies; i++) - { - Message m = session.createTextMessage(payload + i); - m.setIntProperty("index", i + 1); - sender.send(m); - } - - session.commit(); - sender.close(); - _logger.info("put " + copies + " copies"); - } - - /** - * GET the top message on a queue. Consumes the message. Accepts timeout value. - * - * @param queueName The quename to get from - * @param readTimeout The timeout to use - * - * @return the content of the text message if any - * - * @throws javax.jms.JMSException any exception that occured - */ - public Message getNextMessage(String queueName, long readTimeout) throws JMSException - { - if (!connected) - { - connect(); - } - - Queue queue = session.createQueue(queueName); - - final MessageConsumer consumer = session.createConsumer(queue); - - Message message = consumer.receive(readTimeout); - session.commit(); - consumer.close(); - - Message result; - - // all messages we consume should be TextMessages - if (message instanceof TextMessage) - { - result = ((TextMessage) message); - } - else if (null == message) - { - result = null; - } - else - { - _logger.info("warning: received non-text message"); - result = message; - } - - return result; - } - - /** - * GET the top message on a queue. Consumes the message. - * - * @param queueName The Queuename to get from - * - * @return The string content of the text message, if any received - * - * @throws javax.jms.JMSException any exception that occurs - */ - public Message getNextMessage(String queueName) throws JMSException - { - return getNextMessage(queueName, 0); - } - - /** - * Completely clears a queue. For readTimeout behaviour see Javadocs for javax.jms.MessageConsumer. - * - * @param queueName The Queue name to consume from - * @param readTimeout The timeout for each consume - * - * @throws javax.jms.JMSException Any exception that occurs during the consume - * @throws InterruptedException If the consume thread was interrupted during a consume. - */ - public void consume(String queueName, int readTimeout) throws JMSException, InterruptedException - { - if (!connected) - { - connect(); - } - - _logger.info("consuming queue " + queueName); - Queue queue = session.createQueue(queueName); - - final MessageConsumer consumer = session.createConsumer(queue); - int messagesReceived = 0; - - _logger.info("consuming..."); - while ((consumer.receive(readTimeout)) != null) - { - messagesReceived++; - } - - session.commit(); - consumer.close(); - _logger.info("consumed: " + messagesReceived); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/testutil/VMBrokerSetup.java b/java/client/src/test/java/org/apache/qpid/testutil/VMBrokerSetup.java deleted file mode 100644 index cedf1ac824..0000000000 --- a/java/client/src/test/java/org/apache/qpid/testutil/VMBrokerSetup.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.qpid.testutil; - -import junit.extensions.TestSetup; -import junit.framework.Test; - -import org.apache.qpid.client.transport.TransportConnection; - -public class VMBrokerSetup extends TestSetup -{ - public VMBrokerSetup(Test t) - { - super(t); - } - - protected void setUp() throws Exception - { - super.setUp(); - try - { - TransportConnection.createVMBroker(1); - } - catch (Exception e) - { - fail("Unable to create broker: " + e); - } - } - - protected void tearDown() throws Exception - { - TransportConnection.killVMBroker(1); - super.tearDown(); - } -} |
