summaryrefslogtreecommitdiff
path: root/java/client/src
diff options
context:
space:
mode:
authorStephen D. Huston <shuston@apache.org>2011-10-21 01:19:00 +0000
committerStephen D. Huston <shuston@apache.org>2011-10-21 01:19:00 +0000
commitebfd9ff053b04ab379acfc0fefedee5a31b6d8a5 (patch)
treedcfb94e75656c6c239fc3dcb754cd2015126424d /java/client/src
parent5eb354b338bb8d8fcd35b6ac3fb33f8103e757c3 (diff)
downloadqpid-python-ebfd9ff053b04ab379acfc0fefedee5a31b6d8a5.tar.gz
Undo bad merge from trunk - merged at wrong level.
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/QPID-2519@1187150 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/client/src')
-rwxr-xr-xjava/client/src/main/java/client.bnd2
-rw-r--r--java/client/src/main/java/org/apache/mina/transport/socket/nio/ExistingSocketConnector.java478
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQAnyDestination.java13
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java156
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQConnection.java178
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java4
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java158
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java75
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQConnectionFactory.java280
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java19
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQDestination.java114
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQSession.java447
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java238
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java83
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQTemporaryQueue.java17
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQTemporaryTopic.java12
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQTopic.java75
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java163
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java182
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java4
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java60
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java77
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java23
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/ChannelToSessionMap.java20
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java29
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java9
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java87
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/SSLConfiguration.java61
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/TemporaryDestination.java5
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/XAConnectionImpl.java4
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java35
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java2
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/failover/FailoverRetrySupport.java4
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java2
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java46
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate.java6
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegateFactory.java5
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java178
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_8.java61
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessage.java28
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessageFactory.java13
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/AbstractAMQMessageDelegate.java67
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java124
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesTypedMessage.java760
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java103
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java19
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java169
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessageFactory.java3
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSHeaderAdapter.java31
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessage.java71
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessageFactory.java8
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java217
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessageFactory.java8
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessage.java129
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessageFactory.java5
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java161
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessageFactory.java2
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java2
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/TypedBytesContentReader.java674
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/TypedBytesContentWriter.java370
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage_0_8.java4
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java35
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java15
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java258
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java54
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/protocol/ProtocolBufferMonitorFilter.java115
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java4
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.java256
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties18
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties1
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java30
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java17
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClient.java52
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClientFactory.java52
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java16
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/state/StateWaiter.java18
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/transport/ClientConnectionDelegate.java168
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java90
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java351
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java63
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/url/URLParser.java4
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/util/BlockingWaiter.java17
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/util/ClassLoadingAwareObjectInputStream.java134
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java60
-rw-r--r--java/client/src/main/java/org/apache/qpid/filter/JMSSelectorFilter.java10
-rw-r--r--java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java13
-rw-r--r--java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java10
-rw-r--r--java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java2
-rw-r--r--java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java5
-rw-r--r--java/client/src/main/java/org/apache/qpid/jms/MessageProducer.java3
-rw-r--r--java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java7
-rw-r--r--java/client/src/main/java/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java21
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindConnectionFactory.java185
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindQueue.java213
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindTopic.java212
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/README.txt11
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/cluster/Client.java129
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/codec/BasicDeliverTest.java277
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/codec/Client.java133
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/codec/Server.java103
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/config/AMQConnectionFactoryInitialiser.java (renamed from java/client/src/main/java/org/apache/qpid/client/message/TypedBytesCodes.java)37
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/config/AbstractConfig.java69
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/config/ConnectionFactoryInitialiser.java (renamed from java/client/src/main/java/org/apache/qpid/client/message/QpidMessageProperties.java)21
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/config/Connector.java40
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/config/ConnectorConfig.java28
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/config/JBossConnectionFactoryInitialiser.java117
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/flow/ChannelFlowTest.java112
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/fragmentation/TestLargePublisher.java196
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/fragmentation/TestLargeSubscriber.java167
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/headers/Listener.java117
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/headers/MessageFactory.java175
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/headers/Publisher.java133
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Bind.java273
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Lookup.java196
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Unbind.java166
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/latency/LatencyTest.java153
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/mina/AcceptorTest.java102
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/mina/BlockingAcceptorTest.java93
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/mina/WriterTest.java271
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/multiconsumer/AMQTest.java269
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/pubsub1/TestPublisher.java176
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/pubsub1/TestSubscriber.java122
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/test/unit/client/connection/TestManyConnections.java95
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/PropertiesFileInitialContextFactoryTest.java153
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/example.properties38
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/topic/Config.java243
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/topic/Listener.java141
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/topic/MessageFactory.java155
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/topic/Publisher.java175
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/transacted/Config.java110
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/transacted/Ping.java45
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/transacted/Pong.java45
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/transacted/Relay.java127
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/transacted/Start.java44
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/weblogic/ServiceProvider.java151
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/weblogic/ServiceRequestingClient.java185
-rw-r--r--java/client/src/test/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.java125
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/AMQSession_0_10Test.java765
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java36
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/message/TestMessageHelper.java5
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/protocol/AMQProtocolHandlerTest.java23
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/protocol/MockIoSession.java312
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/security/CallbackHandlerRegistryTest.java185
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandlerTest.java99
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandlerTest.java78
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/util/ClassLoadingAwareObjectInputStreamTest.java86
-rw-r--r--java/client/src/test/java/org/apache/qpid/jms/FailoverPolicyTest.java338
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java9
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseMethodHandlerNoCloseOk.java2
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java99
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/client/message/ObjectMessageUnitTest.java105
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/jndi/ConnectionFactoryTest.java18
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/jndi/JNDIPropertyFileTest.java19
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java36
154 files changed, 10920 insertions, 5702 deletions
diff --git a/java/client/src/main/java/client.bnd b/java/client/src/main/java/client.bnd
index 98696dc7d8..0ddd163d4f 100755
--- a/java/client/src/main/java/client.bnd
+++ b/java/client/src/main/java/client.bnd
@@ -17,7 +17,7 @@
# under the License.
#
-ver: 0.13.0
+ver: 0.9.0
Bundle-SymbolicName: qpid-client
Bundle-Version: ${ver}
diff --git a/java/client/src/main/java/org/apache/mina/transport/socket/nio/ExistingSocketConnector.java b/java/client/src/main/java/org/apache/mina/transport/socket/nio/ExistingSocketConnector.java
new file mode 100644
index 0000000000..98716c0c3c
--- /dev/null
+++ b/java/client/src/main/java/org/apache/mina/transport/socket/nio/ExistingSocketConnector.java
@@ -0,0 +1,478 @@
+/*
+ * 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.socket.nio;
+
+import edu.emory.mathcs.backport.java.util.concurrent.Executor;
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.common.ExceptionMonitor;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoConnectorConfig;
+import org.apache.mina.common.IoHandler;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.common.support.BaseIoConnector;
+import org.apache.mina.common.support.DefaultConnectFuture;
+import org.apache.mina.util.NamePreservingRunnable;
+import org.apache.mina.util.NewThreadExecutor;
+import org.apache.mina.util.Queue;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * {@link IoConnector} for socket transport (TCP/IP).
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 627427 $, $Date: 2008-02-13 14:39:10 +0000 (Wed, 13 Feb 2008) $
+ */
+public class ExistingSocketConnector extends BaseIoConnector
+{
+ /** @noinspection StaticNonFinalField */
+ private static volatile int nextId = 0;
+
+ private final Object lock = new Object();
+ private final int id = nextId++;
+ private final String threadName = "SocketConnector-" + id;
+ private SocketConnectorConfig defaultConfig = new SocketConnectorConfig();
+ private final Queue connectQueue = new Queue();
+ private final SocketIoProcessor[] ioProcessors;
+ private final int processorCount;
+ private final Executor executor;
+
+ /** @noinspection FieldAccessedSynchronizedAndUnsynchronized */
+ private Selector selector;
+ private Worker worker;
+ private int processorDistributor = 0;
+ private int workerTimeout = 60; // 1 min.
+ private Socket _openSocket = null;
+
+ /** Create a connector with a single processing thread using a NewThreadExecutor */
+ public ExistingSocketConnector()
+ {
+ this(1, new NewThreadExecutor());
+ }
+
+ /**
+ * Create a connector with the desired number of processing threads
+ *
+ * @param processorCount Number of processing threads
+ * @param executor Executor to use for launching threads
+ */
+ public ExistingSocketConnector(int processorCount, Executor executor)
+ {
+ if (processorCount < 1)
+ {
+ throw new IllegalArgumentException("Must have at least one processor");
+ }
+
+ this.executor = executor;
+ this.processorCount = processorCount;
+ ioProcessors = new SocketIoProcessor[processorCount];
+
+ for (int i = 0; i < processorCount; i++)
+ {
+ ioProcessors[i] = new SocketIoProcessor("SocketConnectorIoProcessor-" + id + "." + i, executor);
+ }
+ }
+
+ /**
+ * How many seconds to keep the connection thread alive between connection requests
+ *
+ * @return Number of seconds to keep connection thread alive
+ */
+ public int getWorkerTimeout()
+ {
+ return workerTimeout;
+ }
+
+ /**
+ * Set how many seconds the connection worker thread should remain alive once idle before terminating itself.
+ *
+ * @param workerTimeout Number of seconds to keep thread alive. Must be >=0
+ */
+ public void setWorkerTimeout(int workerTimeout)
+ {
+ if (workerTimeout < 0)
+ {
+ throw new IllegalArgumentException("Must be >= 0");
+ }
+ this.workerTimeout = workerTimeout;
+ }
+
+ public ConnectFuture connect(SocketAddress address, IoHandler handler, IoServiceConfig config)
+ {
+ return connect(address, null, handler, config);
+ }
+
+ public ConnectFuture connect(SocketAddress address, SocketAddress localAddress,
+ IoHandler handler, IoServiceConfig config)
+ {
+ /** Changes here from the Mina OpenSocketConnector.
+ * Ignoreing all address as they are not needed */
+
+ if (handler == null)
+ {
+ throw new NullPointerException("handler");
+ }
+
+
+ if (config == null)
+ {
+ config = getDefaultConfig();
+ }
+
+ if (_openSocket == null)
+ {
+ throw new IllegalArgumentException("Specifed Socket not active");
+ }
+
+ boolean success = false;
+
+ try
+ {
+ DefaultConnectFuture future = new DefaultConnectFuture();
+ newSession(_openSocket, handler, config, future);
+ success = true;
+ return future;
+ }
+ catch (IOException e)
+ {
+ return DefaultConnectFuture.newFailedFuture(e);
+ }
+ finally
+ {
+ if (!success && _openSocket != null)
+ {
+ try
+ {
+ _openSocket.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ }
+ }
+ }
+
+ public IoServiceConfig getDefaultConfig()
+ {
+ return defaultConfig;
+ }
+
+ /**
+ * Sets the config this connector will use by default.
+ *
+ * @param defaultConfig the default config.
+ *
+ * @throws NullPointerException if the specified value is <code>null</code>.
+ */
+ public void setDefaultConfig(SocketConnectorConfig defaultConfig)
+ {
+ if (defaultConfig == null)
+ {
+ throw new NullPointerException("defaultConfig");
+ }
+ this.defaultConfig = defaultConfig;
+ }
+
+ private synchronized void startupWorker() throws IOException
+ {
+ if (worker == null)
+ {
+ selector = Selector.open();
+ worker = new Worker();
+ executor.execute(new NamePreservingRunnable(worker));
+ }
+ }
+
+ private void registerNew()
+ {
+ if (connectQueue.isEmpty())
+ {
+ return;
+ }
+
+ for (; ;)
+ {
+ ConnectionRequest req;
+ synchronized (connectQueue)
+ {
+ req = (ConnectionRequest) connectQueue.pop();
+ }
+
+ if (req == null)
+ {
+ break;
+ }
+
+ SocketChannel ch = req.channel;
+ try
+ {
+ ch.register(selector, SelectionKey.OP_CONNECT, req);
+ }
+ catch (IOException e)
+ {
+ req.setException(e);
+ }
+ }
+ }
+
+ private void processSessions(Set keys)
+ {
+ Iterator it = keys.iterator();
+
+ while (it.hasNext())
+ {
+ SelectionKey key = (SelectionKey) it.next();
+
+ if (!key.isConnectable())
+ {
+ continue;
+ }
+
+ SocketChannel ch = (SocketChannel) key.channel();
+ ConnectionRequest entry = (ConnectionRequest) key.attachment();
+
+ boolean success = false;
+ try
+ {
+ ch.finishConnect();
+ newSession(ch, entry.handler, entry.config, entry);
+ success = true;
+ }
+ catch (Throwable e)
+ {
+ entry.setException(e);
+ }
+ finally
+ {
+ key.cancel();
+ if (!success)
+ {
+ try
+ {
+ ch.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ }
+ }
+ }
+
+ keys.clear();
+ }
+
+ private void processTimedOutSessions(Set keys)
+ {
+ long currentTime = System.currentTimeMillis();
+ Iterator it = keys.iterator();
+
+ while (it.hasNext())
+ {
+ SelectionKey key = (SelectionKey) it.next();
+
+ if (!key.isValid())
+ {
+ continue;
+ }
+
+ ConnectionRequest entry = (ConnectionRequest) key.attachment();
+
+ if (currentTime >= entry.deadline)
+ {
+ entry.setException(new ConnectException());
+ try
+ {
+ key.channel().close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ finally
+ {
+ key.cancel();
+ }
+ }
+ }
+ }
+
+ private void newSession(Socket socket, IoHandler handler, IoServiceConfig config, ConnectFuture connectFuture)
+ throws IOException
+ {
+ SocketSessionImpl session = new SocketSessionImpl(this,
+ nextProcessor(),
+ getListeners(),
+ config,
+ socket.getChannel(),
+ handler,
+ socket.getRemoteSocketAddress());
+
+ newSession(session, config, connectFuture);
+ }
+
+ private void newSession(SocketChannel ch, IoHandler handler, IoServiceConfig config, ConnectFuture connectFuture)
+ throws IOException
+
+ {
+ SocketSessionImpl session = new SocketSessionImpl(this,
+ nextProcessor(),
+ getListeners(),
+ config,
+ ch,
+ handler,
+ ch.socket().getRemoteSocketAddress());
+
+ newSession(session, config, connectFuture);
+ }
+
+ private void newSession(SocketSessionImpl session, IoServiceConfig config, ConnectFuture connectFuture)
+ throws IOException
+ {
+ try
+ {
+ getFilterChainBuilder().buildFilterChain(session.getFilterChain());
+ config.getFilterChainBuilder().buildFilterChain(session.getFilterChain());
+ config.getThreadModel().buildFilterChain(session.getFilterChain());
+ }
+ catch (Throwable e)
+ {
+ throw (IOException) new IOException("Failed to create a session.").initCause(e);
+ }
+ session.getIoProcessor().addNew(session);
+ connectFuture.setSession(session);
+ }
+
+ private SocketIoProcessor nextProcessor()
+ {
+ return ioProcessors[processorDistributor++ % processorCount];
+ }
+
+ public void setOpenSocket(Socket openSocket)
+ {
+ _openSocket = openSocket;
+ }
+
+ private class Worker implements Runnable
+ {
+ private long lastActive = System.currentTimeMillis();
+
+ public void run()
+ {
+ Thread.currentThread().setName(ExistingSocketConnector.this.threadName);
+
+ for (; ;)
+ {
+ try
+ {
+ int nKeys = selector.select(1000);
+
+ registerNew();
+
+ if (nKeys > 0)
+ {
+ processSessions(selector.selectedKeys());
+ }
+
+ processTimedOutSessions(selector.keys());
+
+ if (selector.keys().isEmpty())
+ {
+ if (System.currentTimeMillis() - lastActive > workerTimeout * 1000L)
+ {
+ synchronized (lock)
+ {
+ if (selector.keys().isEmpty() &&
+ connectQueue.isEmpty())
+ {
+ worker = null;
+ try
+ {
+ selector.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ finally
+ {
+ selector = null;
+ }
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ lastActive = System.currentTimeMillis();
+ }
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+
+ try
+ {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e1)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e1);
+ }
+ }
+ }
+ }
+ }
+
+ private class ConnectionRequest extends DefaultConnectFuture
+ {
+ private final SocketChannel channel;
+ private final long deadline;
+ private final IoHandler handler;
+ private final IoServiceConfig config;
+
+ private ConnectionRequest(SocketChannel channel, IoHandler handler, IoServiceConfig config)
+ {
+ this.channel = channel;
+ long timeout;
+ if (config instanceof IoConnectorConfig)
+ {
+ timeout = ((IoConnectorConfig) config).getConnectTimeoutMillis();
+ }
+ else
+ {
+ timeout = ((IoConnectorConfig) getDefaultConfig()).getConnectTimeoutMillis();
+ }
+ this.deadline = System.currentTimeMillis() + timeout;
+ this.handler = handler;
+ this.config = config;
+ }
+ }
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQAnyDestination.java b/java/client/src/main/java/org/apache/qpid/client/AMQAnyDestination.java
index 999b22299c..a201f7d61e 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQAnyDestination.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQAnyDestination.java
@@ -72,17 +72,6 @@ public class AMQAnyDestination extends AMQDestination implements Queue, Topic
public String getTopicName() throws JMSException
{
- if (getRoutingKey() != null)
- {
- return getRoutingKey().asString();
- }
- else if (getSubject() != null)
- {
- return getSubject();
- }
- else
- {
- return null;
- }
+ return super.getRoutingKey().toString();
}
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java b/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java
index c0d4d8a893..ee52cd50af 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java
@@ -26,7 +26,7 @@ import java.util.HashMap;
import java.util.Map;
import org.apache.qpid.jms.BrokerDetails;
-import org.apache.qpid.transport.ConnectionSettings;
+import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.url.URLHelper;
import org.apache.qpid.url.URLSyntaxException;
@@ -38,6 +38,8 @@ public class AMQBrokerDetails implements BrokerDetails
private Map<String, String> _options = new HashMap<String, String>();
+ private SSLConfiguration _sslConfiguration;
+
public AMQBrokerDetails(){}
public AMQBrokerDetails(String url) throws URLSyntaxException
@@ -54,7 +56,9 @@ public class AMQBrokerDetails implements BrokerDetails
if (transport != null)
{
//todo this list of valid transports should be enumerated somewhere
- if (!(transport.equalsIgnoreCase(BrokerDetails.TCP)))
+ if ((!(transport.equalsIgnoreCase(BrokerDetails.VM) ||
+ transport.equalsIgnoreCase(BrokerDetails.TCP) ||
+ transport.equalsIgnoreCase(BrokerDetails.SOCKET))))
{
if (transport.equalsIgnoreCase("localhost"))
{
@@ -101,21 +105,6 @@ public class AMQBrokerDetails implements BrokerDetails
if (host == null)
{
host = "";
-
- String auth = connection.getAuthority();
- if (auth != null)
- {
- // contains both host & port myhost:5672
- if (auth.contains(":"))
- {
- host = auth.substring(0,auth.indexOf(":"));
- }
- else
- {
- host = auth;
- }
- }
-
}
setHost(host);
@@ -178,7 +167,10 @@ public class AMQBrokerDetails implements BrokerDetails
}
else
{
- setPort(port);
+ if (!_transport.equalsIgnoreCase(SOCKET))
+ {
+ setPort(port);
+ }
}
String queryString = connection.getQuery();
@@ -198,10 +190,11 @@ public class AMQBrokerDetails implements BrokerDetails
}
}
- public AMQBrokerDetails(String host, int port)
+ public AMQBrokerDetails(String host, int port, SSLConfiguration sslConfiguration)
{
_host = host;
_port = port;
+ _sslConfiguration = sslConfiguration;
}
public String getHost()
@@ -277,15 +270,33 @@ public class AMQBrokerDetails implements BrokerDetails
setProperty(OPTIONS_CONNECT_TIMEOUT, Long.toString(timeout));
}
+ public SSLConfiguration getSSLConfiguration()
+ {
+ return _sslConfiguration;
+ }
+
+ public void setSSLConfiguration(SSLConfiguration sslConfig)
+ {
+ _sslConfiguration = sslConfig;
+ }
+
public String toString()
{
StringBuffer sb = new StringBuffer();
sb.append(_transport);
sb.append("://");
- sb.append(_host);
- sb.append(':');
- sb.append(_port);
+
+ if (!(_transport.equalsIgnoreCase(VM)))
+ {
+ sb.append(_host);
+ }
+
+ if (!(_transport.equalsIgnoreCase(SOCKET)))
+ {
+ sb.append(':');
+ sb.append(_port);
+ }
sb.append(printOptionsURL());
@@ -303,8 +314,9 @@ public class AMQBrokerDetails implements BrokerDetails
return _host.equalsIgnoreCase(bd.getHost()) &&
(_port == bd.getPort()) &&
- _transport.equalsIgnoreCase(bd.getTransport());
- //TODO do we need to compare all the options as well?
+ _transport.equalsIgnoreCase(bd.getTransport()) &&
+ compareSSLConfigurations(bd.getSSLConfiguration());
+ //todo do we need to compare all the options as well?
}
@Override
@@ -345,6 +357,24 @@ public class AMQBrokerDetails implements BrokerDetails
return optionsURL.toString();
}
+ // Do we need to do a more in-depth comparison?
+ private boolean compareSSLConfigurations(SSLConfiguration other)
+ {
+ boolean retval = false;
+ if (_sslConfiguration == null &&
+ other == null)
+ {
+ retval = true;
+ }
+ else if (_sslConfiguration != null &&
+ other != null)
+ {
+ retval = true;
+ }
+
+ return retval;
+ }
+
public static String checkTransport(String broker)
{
if ((!broker.contains("://")))
@@ -366,82 +396,4 @@ public class AMQBrokerDetails implements BrokerDetails
{
_options = props;
}
-
- public ConnectionSettings buildConnectionSettings()
- {
- ConnectionSettings conSettings = new ConnectionSettings();
-
- conSettings.setHost(getHost());
- conSettings.setPort(getPort());
-
- // ------------ sasl options ---------------
- if (getProperty(BrokerDetails.OPTIONS_SASL_MECHS) != null)
- {
- conSettings.setSaslMechs(
- getProperty(BrokerDetails.OPTIONS_SASL_MECHS));
- }
-
- // Sun SASL Kerberos client uses the
- // protocol + servername as the service key.
-
- if (getProperty(BrokerDetails.OPTIONS_SASL_PROTOCOL_NAME) != null)
- {
- conSettings.setSaslProtocol(
- getProperty(BrokerDetails.OPTIONS_SASL_PROTOCOL_NAME));
- }
-
-
- if (getProperty(BrokerDetails.OPTIONS_SASL_SERVER_NAME) != null)
- {
- conSettings.setSaslServerName(
- getProperty(BrokerDetails.OPTIONS_SASL_SERVER_NAME));
- }
-
- conSettings.setUseSASLEncryption(
- getBooleanProperty(BrokerDetails.OPTIONS_SASL_ENCRYPTION));
-
- // ------------- ssl options ---------------------
- conSettings.setUseSSL(getBooleanProperty(BrokerDetails.OPTIONS_SSL));
-
- if (getProperty(BrokerDetails.OPTIONS_TRUST_STORE) != null)
- {
- conSettings.setTrustStorePath(
- getProperty(BrokerDetails.OPTIONS_TRUST_STORE));
- }
-
- if (getProperty(BrokerDetails.OPTIONS_TRUST_STORE_PASSWORD) != null)
- {
- conSettings.setTrustStorePassword(
- getProperty(BrokerDetails.OPTIONS_TRUST_STORE_PASSWORD));
- }
-
- if (getProperty(BrokerDetails.OPTIONS_KEY_STORE) != null)
- {
- conSettings.setKeyStorePath(
- getProperty(BrokerDetails.OPTIONS_KEY_STORE));
- }
-
- if (getProperty(BrokerDetails.OPTIONS_KEY_STORE_PASSWORD) != null)
- {
- conSettings.setKeyStorePassword(
- getProperty(BrokerDetails.OPTIONS_KEY_STORE_PASSWORD));
- }
-
- if (getProperty(BrokerDetails.OPTIONS_SSL_CERT_ALIAS) != null)
- {
- conSettings.setCertAlias(
- getProperty(BrokerDetails.OPTIONS_SSL_CERT_ALIAS));
- }
- // ----------------------------
-
- conSettings.setVerifyHostname(getBooleanProperty(BrokerDetails.OPTIONS_SSL_VERIFY_HOSTNAME));
-
- if (getProperty(BrokerDetails.OPTIONS_TCP_NO_DELAY) != null)
- {
- conSettings.setTcpNodelay(
- getBooleanProperty(BrokerDetails.OPTIONS_TCP_NO_DELAY));
- }
-
- return conSettings;
- }
}
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 f15af72407..ab59fee020 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
@@ -111,7 +111,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
/** Maps from session id (Integer) to AMQSession instance */
private final ChannelToSessionMap _sessions = new ChannelToSessionMap();
- private final String _clientName;
+ private String _clientName;
/** The user name to use for authentication */
private String _username;
@@ -126,7 +126,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
private ConnectionListener _connectionListener;
- private final ConnectionURL _connectionURL;
+ private ConnectionURL _connectionURL;
/**
* Whether this connection is started, i.e. whether messages are flowing to consumers. It has no meaning for message
@@ -147,6 +147,9 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
*/
private QpidConnectionMetaData _connectionMetaData;
+ /** Configuration info for SSL */
+ private SSLConfiguration _sslConfiguration;
+
private AMQShortString _defaultTopicExchangeName = ExchangeDefaults.TOPIC_EXCHANGE_NAME;
private AMQShortString _defaultQueueExchangeName = ExchangeDefaults.DIRECT_EXCHANGE_NAME;
private AMQShortString _temporaryTopicExchangeName = ExchangeDefaults.TOPIC_EXCHANGE_NAME;
@@ -170,8 +173,8 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
//Indicates the sync publish options (persistent|all)
//By default it's async publish
private String _syncPublish = "";
-
- // Indicates whether to use the old map message format or the
+
+ // Indicates whether to use the old map message format or the
// new amqp-0-10 encoded format.
private boolean _useLegacyMapMessageFormat;
@@ -191,33 +194,69 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
this(new AMQConnectionURL(
ConnectionURL.AMQ_PROTOCOL + "://" + username + ":" + password + "@"
+ ((clientName == null) ? "" : clientName) + "/" + virtualHost + "?brokerlist='"
- + AMQBrokerDetails.checkTransport(broker) + "'"));
+ + AMQBrokerDetails.checkTransport(broker) + "'"), null);
+ }
+
+ /**
+ * @param broker brokerdetails
+ * @param username username
+ * @param password password
+ * @param clientName clientid
+ * @param virtualHost virtualhost
+ *
+ * @throws AMQException
+ * @throws URLSyntaxException
+ */
+ public AMQConnection(String broker, String username, String password, String clientName, String virtualHost,
+ SSLConfiguration sslConfig) throws AMQException, URLSyntaxException
+ {
+ this(new AMQConnectionURL(
+ ConnectionURL.AMQ_PROTOCOL + "://" + username + ":" + password + "@"
+ + ((clientName == null) ? "" : clientName) + "/" + virtualHost + "?brokerlist='"
+ + AMQBrokerDetails.checkTransport(broker) + "'"), sslConfig);
}
public AMQConnection(String host, int port, String username, String password, String clientName, String virtualHost)
throws AMQException, URLSyntaxException
{
+ this(host, port, false, username, password, clientName, virtualHost, null);
+ }
+
+ public AMQConnection(String host, int port, String username, String password, String clientName, String virtualHost,
+ SSLConfiguration sslConfig) throws AMQException, URLSyntaxException
+ {
+ this(host, port, false, username, password, clientName, virtualHost, sslConfig);
+ }
+
+ public AMQConnection(String host, int port, boolean useSSL, String username, String password, String clientName,
+ String virtualHost, SSLConfiguration sslConfig) throws AMQException, URLSyntaxException
+ {
this(new AMQConnectionURL(
- ConnectionURL.AMQ_PROTOCOL + "://" + username + ":" + password + "@"
- + ((clientName == null) ? "" : clientName) + virtualHost + "?brokerlist='tcp://" + host + ":" + port + "'"));
+ useSSL
+ ? (ConnectionURL.AMQ_PROTOCOL + "://" + username + ":" + password + "@"
+ + ((clientName == null) ? "" : clientName) + virtualHost + "?brokerlist='tcp://" + host + ":" + port
+ + "'" + "," + BrokerDetails.OPTIONS_SSL + "='true'")
+ : (ConnectionURL.AMQ_PROTOCOL + "://" + username + ":" + password + "@"
+ + ((clientName == null) ? "" : clientName) + virtualHost + "?brokerlist='tcp://" + host + ":" + port
+ + "'" + "," + BrokerDetails.OPTIONS_SSL + "='false'")), sslConfig);
}
public AMQConnection(String connection) throws AMQException, URLSyntaxException
{
- this(new AMQConnectionURL(connection));
+ this(new AMQConnectionURL(connection), null);
+ }
+
+ public AMQConnection(String connection, SSLConfiguration sslConfig) throws AMQException, URLSyntaxException
+ {
+ this(new AMQConnectionURL(connection), sslConfig);
}
/**
* @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.
*/
- public AMQConnection(ConnectionURL connectionURL) throws AMQException
+ public AMQConnection(ConnectionURL connectionURL, SSLConfiguration sslConfig) throws AMQException
{
- if (connectionURL == null)
- {
- throw new IllegalArgumentException("Connection must be specified");
- }
-
// set this connection maxPrefetch
if (connectionURL.getOption(ConnectionURL.OPTIONS_MAXPREFETCH) != null)
{
@@ -225,7 +264,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
else
{
- // use the default value set for all connections
+ // use the defaul value set for all connections
_maxPrefetch = Integer.parseInt(System.getProperties().getProperty(ClientProperties.MAX_PREFETCH_PROP_NAME,
ClientProperties.MAX_PREFETCH_DEFAULT));
}
@@ -239,7 +278,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
else
{
- // use the default value set for all connections
+ // use the defaul value set for all connections
_syncPersistence = Boolean.getBoolean(ClientProperties.SYNC_PERSISTENT_PROP_NAME);
if (_syncPersistence)
{
@@ -254,7 +293,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
else
{
- // use the default value set for all connections
+ // use the defaul value set for all connections
_syncAck = Boolean.getBoolean(ClientProperties.SYNC_ACK_PROP_NAME);
}
@@ -267,7 +306,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
// use the default value set for all connections
_syncPublish = System.getProperty((ClientProperties.SYNC_PUBLISH_PROP_NAME),_syncPublish);
}
-
+
if (connectionURL.getOption(ConnectionURL.OPTIONS_USE_LEGACY_MAP_MESSAGE_FORMAT) != null)
{
_useLegacyMapMessageFormat = Boolean.parseBoolean(
@@ -278,16 +317,16 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
// use the default value set for all connections
_useLegacyMapMessageFormat = Boolean.getBoolean(ClientProperties.USE_LEGACY_MAP_MESSAGE_FORMAT);
}
-
+
String amqpVersion = System.getProperty((ClientProperties.AMQP_VERSION), "0-10");
_logger.debug("AMQP version " + amqpVersion);
-
+
_failoverPolicy = new FailoverPolicy(connectionURL, this);
BrokerDetails brokerDetails = _failoverPolicy.getCurrentBrokerDetails();
- if ("0-8".equals(amqpVersion))
+ if (brokerDetails.getTransport().equals(BrokerDetails.VM) || "0-8".equals(amqpVersion))
{
_delegate = new AMQConnectionDelegate_8_0(this);
- }
+ }
else if ("0-9".equals(amqpVersion))
{
_delegate = new AMQConnectionDelegate_0_9(this);
@@ -306,6 +345,12 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
_logger.info("Connection:" + connectionURL);
}
+ _sslConfiguration = sslConfig;
+ if (connectionURL == null)
+ {
+ throw new IllegalArgumentException("Connection must be specified");
+ }
+
_connectionURL = connectionURL;
_clientName = connectionURL.getClientName();
@@ -373,7 +418,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
brokerDetails = _failoverPolicy.getNextBrokerDetails();
}
}
- verifyClientID();
if (_logger.isDebugEnabled())
{
@@ -460,7 +504,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
Class partypes[] = new Class[1];
partypes[0] = AMQConnection.class;
_delegate = (AMQConnectionDelegate) c.getConstructor(partypes).newInstance(this);
- //Update our session to use this new protocol version
+ //Update our session to use this new protocol version
_protocolHandler.getProtocolSession().setProtocolVersion(_delegate.getProtocolVersion());
}
@@ -491,6 +535,14 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
}
+ protected AMQConnection(String username, String password, String clientName, String virtualHost)
+ {
+ _clientName = clientName;
+ _username = username;
+ _password = password;
+ setVirtualHost(virtualHost);
+ }
+
private void setVirtualHost(String virtualHost)
{
if (virtualHost != null && virtualHost.startsWith("/"))
@@ -503,7 +555,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
public boolean attemptReconnection(String host, int port)
{
- BrokerDetails bd = new AMQBrokerDetails(host, port);
+ BrokerDetails bd = new AMQBrokerDetails(host, port, _sslConfiguration);
_failoverPolicy.setBroker(bd);
@@ -644,6 +696,20 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
}
+ private void reopenChannel(int channelId, int prefetchHigh, int prefetchLow, boolean transacted)
+ throws AMQException, FailoverException
+ {
+ try
+ {
+ createChannelOverWire(channelId, prefetchHigh, prefetchLow, transacted);
+ }
+ catch (AMQException e)
+ {
+ deregisterSession(channelId);
+ throw new AMQException(null, "Error reopening channel " + channelId + " after failover: " + e, e);
+ }
+ }
+
public void setFailoverPolicy(FailoverPolicy policy)
{
_failoverPolicy = policy;
@@ -1030,7 +1096,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
_username = id;
}
-
+
public String getPassword()
{
return _password;
@@ -1183,7 +1249,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
if (code != null)
{
- je = new JMSException("Exception thrown against " + toString() + ": " + cause, Integer.toString(code.getCode()));
+ je = new JMSException(Integer.toString(code.getCode()), "Exception thrown against " + toString() + ": " + cause);
}
else
{
@@ -1206,7 +1272,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
je.setLinkedException((Exception) cause);
}
-
+
je.initCause(cause);
}
@@ -1239,7 +1305,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
_logger.info("Not a hard-error connection not closing: " + cause);
}
-
+
// deliver the exception if there is a listener
if (_exceptionListener != null)
{
@@ -1249,7 +1315,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
_logger.error("Throwable Received but no listener set: " + cause);
}
-
+
// if we are closing the connection, close sessions first
if (closer)
{
@@ -1306,20 +1372,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
return buf.toString();
}
- /**
- * Returns connection url.
- * @return connection url
- */
- public ConnectionURL getConnectionURL()
- {
- return _connectionURL;
- }
-
- /**
- * Returns stringified connection url. This url is suitable only for display
- * as {@link AMQConnectionURL#toString()} converts any password to asterisks.
- * @return connection url
- */
public String toURL()
{
return _connectionURL.toString();
@@ -1331,6 +1383,11 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
AMQConnectionFactory.class.getName(), null); // factory location
}
+ public SSLConfiguration getSSLConfiguration()
+ {
+ return _sslConfiguration;
+ }
+
public AMQShortString getDefaultTopicExchangeName()
{
return _defaultTopicExchangeName;
@@ -1385,18 +1442,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
return _delegate.getProtocolVersion();
}
-
- public String getBrokerUUID()
- {
- if(getProtocolVersion().equals(ProtocolVersion.v0_10))
- {
- return ((AMQConnectionDelegate_0_10)_delegate).getUUID();
- }
- else
- {
- return null;
- }
- }
+
public boolean isFailingOver()
{
return (_protocolHandler.getFailoverLatch() != null);
@@ -1439,27 +1485,9 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
return _sessions.getNextChannelId();
}
-
+
public boolean isUseLegacyMapMessageFormat()
{
return _useLegacyMapMessageFormat;
}
-
- private void verifyClientID() throws AMQException
- {
- if (Boolean.getBoolean(ClientProperties.QPID_VERIFY_CLIENT_ID))
- {
- try
- {
- if (!_delegate.verifyClientID())
- {
- throw new AMQException(AMQConstant.ALREADY_EXISTS,"ClientID must be unique");
- }
- }
- catch(JMSException e)
- {
- throw new AMQException(e.getMessage(),e);
- }
- }
- }
}
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 8768f93c8c..9560bd5c7c 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
@@ -57,12 +57,10 @@ public interface AMQConnectionDelegate
void closeConnection(long timeout) throws JMSException, AMQException;
<T, E extends Exception> T executeRetrySupport(FailoverProtectedOperation<T,E> operation) throws E;
-
+
int getMaxChannelID();
int getMinChannelID();
ProtocolVersion getProtocolVersion();
-
- boolean verifyClientID() throws JMSException, AMQException;
}
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 0ed3db6ecb..b0bd8f8e97 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
@@ -1,6 +1,6 @@
package org.apache.qpid.client;
/*
- *
+ *
* 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
@@ -8,16 +8,16 @@ package org.apache.qpid.client;
* 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.
- *
+ *
*/
@@ -35,7 +35,6 @@ import javax.jms.XASession;
import org.apache.qpid.AMQException;
import org.apache.qpid.client.failover.FailoverException;
import org.apache.qpid.client.failover.FailoverProtectedOperation;
-import org.apache.qpid.client.transport.ClientConnectionDelegate;
import org.apache.qpid.configuration.ClientProperties;
import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.jms.BrokerDetails;
@@ -44,13 +43,10 @@ import org.apache.qpid.jms.Session;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.transport.Connection;
import org.apache.qpid.transport.ConnectionClose;
-import org.apache.qpid.transport.ConnectionCloseCode;
import org.apache.qpid.transport.ConnectionException;
import org.apache.qpid.transport.ConnectionListener;
import org.apache.qpid.transport.ConnectionSettings;
import org.apache.qpid.transport.ProtocolVersionException;
-import org.apache.qpid.transport.SessionDetachCode;
-import org.apache.qpid.transport.SessionException;
import org.apache.qpid.transport.TransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -63,10 +59,6 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
private static final Logger _logger = LoggerFactory.getLogger(AMQConnectionDelegate_0_10.class);
/**
- * The name of the UUID property
- */
- private static final String UUID_NAME = "qpid.federation_tag";
- /**
* The AMQ Connection.
*/
private AMQConnection _conn;
@@ -77,12 +69,6 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
org.apache.qpid.transport.Connection _qpidConnection;
private ConnectionException exception = null;
- static
- {
- // Register any configured SASL client factories.
- org.apache.qpid.client.security.DynamicSaslRegistrar.registerSaslProviders();
- }
-
//--- constructor
public AMQConnectionDelegate_0_10(AMQConnection conn)
{
@@ -94,14 +80,7 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
/**
* create a Session and start it if required.
*/
-
public Session createSession(boolean transacted, int acknowledgeMode, int prefetchHigh, int prefetchLow)
- throws JMSException
- {
- return createSession(transacted,acknowledgeMode,prefetchHigh,prefetchLow,null);
- }
-
- public Session createSession(boolean transacted, int acknowledgeMode, int prefetchHigh, int prefetchLow, String name)
throws JMSException
{
_conn.checkNotClosed();
@@ -116,7 +95,7 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
try
{
session = new AMQSession_0_10(_qpidConnection, _conn, channelId, transacted, acknowledgeMode, prefetchHigh,
- prefetchLow,name);
+ prefetchLow);
_conn.registerSession(channelId, session);
if (_conn._started)
{
@@ -194,8 +173,8 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
+ _conn.getPassword());
}
- ConnectionSettings conSettings = retriveConnectionSettings(brokerDetail);
- _qpidConnection.setConnectionDelegate(new ClientConnectionDelegate(conSettings, _conn.getConnectionURL()));
+ ConnectionSettings conSettings = new ConnectionSettings();
+ retriveConnectionSettings(conSettings,brokerDetail);
_qpidConnection.connect(conSettings);
_conn._connected = true;
@@ -232,8 +211,6 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
public void resubscribeSessions() throws JMSException, AMQException, FailoverException
{
- _logger.info("Resuming connection");
- getQpidConnection().resume();
List<AMQSession> sessions = new ArrayList<AMQSession>(_conn.getSessions().values());
_logger.info(String.format("Resubscribing sessions = %s sessions.size=%d", sessions, sessions.size()));
for (AMQSession s : sessions)
@@ -277,10 +254,10 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
}
ConnectionClose close = exc.getClose();
- if (close == null || close.getReplyCode() == ConnectionCloseCode.CONNECTION_FORCED)
+ if (close == null)
{
_conn.getProtocolHandler().setFailoverLatch(new CountDownLatch(1));
-
+
try
{
if (_conn.firePreFailover(false) && _conn.attemptReconnection())
@@ -349,20 +326,78 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
{
return ProtocolVersion.v0_10;
}
-
- public String getUUID()
- {
- return (String)_qpidConnection.getServerProperties().get(UUID_NAME);
- }
-
- private ConnectionSettings retriveConnectionSettings(BrokerDetails brokerDetail)
+
+ private void retriveConnectionSettings(ConnectionSettings conSettings, BrokerDetails brokerDetail)
{
- ConnectionSettings conSettings = brokerDetail.buildConnectionSettings();
+ conSettings.setHost(brokerDetail.getHost());
+ conSettings.setPort(brokerDetail.getPort());
conSettings.setVhost(_conn.getVirtualHost());
conSettings.setUsername(_conn.getUsername());
conSettings.setPassword(_conn.getPassword());
+
+ // ------------ sasl options ---------------
+ if (brokerDetail.getProperty(BrokerDetails.OPTIONS_SASL_MECHS) != null)
+ {
+ conSettings.setSaslMechs(
+ brokerDetail.getProperty(BrokerDetails.OPTIONS_SASL_MECHS));
+ }
+ // Sun SASL Kerberos client uses the
+ // protocol + servername as the service key.
+
+ if (brokerDetail.getProperty(BrokerDetails.OPTIONS_SASL_PROTOCOL_NAME) != null)
+ {
+ conSettings.setSaslProtocol(
+ brokerDetail.getProperty(BrokerDetails.OPTIONS_SASL_PROTOCOL_NAME));
+ }
+
+
+ if (brokerDetail.getProperty(BrokerDetails.OPTIONS_SASL_SERVER_NAME) != null)
+ {
+ conSettings.setSaslServerName(
+ brokerDetail.getProperty(BrokerDetails.OPTIONS_SASL_SERVER_NAME));
+ }
+
+ conSettings.setUseSASLEncryption(
+ brokerDetail.getBooleanProperty(BrokerDetails.OPTIONS_SASL_ENCRYPTION));
+
+ // ------------- ssl options ---------------------
+ conSettings.setUseSSL(brokerDetail.getBooleanProperty(BrokerDetails.OPTIONS_SSL));
+
+ if (brokerDetail.getProperty(BrokerDetails.OPTIONS_TRUST_STORE) != null)
+ {
+ conSettings.setTrustStorePath(
+ brokerDetail.getProperty(BrokerDetails.OPTIONS_TRUST_STORE));
+ }
+
+ if (brokerDetail.getProperty(BrokerDetails.OPTIONS_TRUST_STORE_PASSWORD) != null)
+ {
+ conSettings.setTrustStorePassword(
+ brokerDetail.getProperty(BrokerDetails.OPTIONS_TRUST_STORE_PASSWORD));
+ }
+
+ if (brokerDetail.getProperty(BrokerDetails.OPTIONS_KEY_STORE) != null)
+ {
+ conSettings.setKeyStorePath(
+ brokerDetail.getProperty(BrokerDetails.OPTIONS_KEY_STORE));
+ }
+
+ if (brokerDetail.getProperty(BrokerDetails.OPTIONS_KEY_STORE_PASSWORD) != null)
+ {
+ conSettings.setKeyStorePassword(
+ brokerDetail.getProperty(BrokerDetails.OPTIONS_KEY_STORE_PASSWORD));
+ }
+
+ if (brokerDetail.getProperty(BrokerDetails.OPTIONS_SSL_CERT_ALIAS) != null)
+ {
+ conSettings.setCertAlias(
+ brokerDetail.getProperty(BrokerDetails.OPTIONS_SSL_CERT_ALIAS));
+ }
+ // ----------------------------
+
+ conSettings.setVerifyHostname(brokerDetail.getBooleanProperty(BrokerDetails.OPTIONS_SSL_VERIFY_HOSTNAME));
+
// Pass client name from connection URL
Map<String, Object> clientProps = new HashMap<String, Object>();
try
@@ -374,12 +409,16 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
{
// Ignore
}
-
+
+ if (brokerDetail.getProperty(BrokerDetails.OPTIONS_TCP_NO_DELAY) != null)
+ {
+ conSettings.setTcpNodelay(
+ brokerDetail.getBooleanProperty(BrokerDetails.OPTIONS_TCP_NO_DELAY));
+ }
+
conSettings.setHeartbeatInterval(getHeartbeatInterval(brokerDetail));
-
- return conSettings;
}
-
+
// The idle_timeout prop is in milisecs while
// the new heartbeat prop is in secs
private int getHeartbeatInterval(BrokerDetails brokerDetail)
@@ -394,7 +433,7 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
{
heartbeat = Integer.parseInt(brokerDetail.getProperty(BrokerDetails.OPTIONS_HEARTBEAT));
}
- else if (Integer.getInteger(ClientProperties.IDLE_TIMEOUT_PROP_NAME) != null)
+ else if (Integer.getInteger(ClientProperties.IDLE_TIMEOUT_PROP_NAME) != null)
{
heartbeat = Integer.getInteger(ClientProperties.IDLE_TIMEOUT_PROP_NAME)/1000;
_logger.warn("JVM arg -Didle_timeout=<mili_secs> is deprecated, please use -Dqpid.heartbeat=<secs>");
@@ -402,37 +441,12 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
else
{
heartbeat = Integer.getInteger(ClientProperties.HEARTBEAT,ClientProperties.HEARTBEAT_DEFAULT);
- }
+ }
return heartbeat;
}
-
+
protected org.apache.qpid.transport.Connection getQpidConnection()
{
return _qpidConnection;
}
-
- public boolean verifyClientID() throws JMSException, AMQException
- {
- int prefetch = (int)_conn.getMaxPrefetch();
- AMQSession_0_10 ssn = (AMQSession_0_10)createSession(false, 1,prefetch,prefetch,_conn.getClientID());
- org.apache.qpid.transport.Session ssn_0_10 = ssn.getQpidSession();
- try
- {
- ssn_0_10.awaitOpen();
- }
- catch(SessionException se)
- {
- //if due to non unique client id for user return false, otherwise wrap and re-throw.
- if (ssn_0_10.getDetachCode() != null &&
- ssn_0_10.getDetachCode() == SessionDetachCode.SESSION_BUSY)
- {
- return false;
- }
- else
- {
- throw new AMQException(AMQConstant.INTERNAL_ERROR, "Unexpected SessionException thrown while awaiting session opening", se);
- }
- }
- return true;
- }
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
index b1a22155d6..40b332d216 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
@@ -23,8 +23,6 @@ package org.apache.qpid.client;
import java.io.IOException;
import java.net.ConnectException;
import java.nio.channels.UnresolvedAddressException;
-import java.security.GeneralSecurityException;
-import java.security.Security;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.EnumSet;
@@ -33,17 +31,15 @@ import java.util.Set;
import javax.jms.JMSException;
import javax.jms.XASession;
-import javax.net.ssl.SSLContext;
import org.apache.qpid.AMQException;
-import org.apache.qpid.AMQTimeoutException;
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.protocol.AMQProtocolSession;
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.transport.TransportConnection;
import org.apache.qpid.framing.BasicQosBody;
import org.apache.qpid.framing.BasicQosOkBody;
import org.apache.qpid.framing.ChannelOpenBody;
@@ -53,13 +49,6 @@ 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.ssl.SSLContextFactory;
-import org.apache.qpid.transport.ConnectionSettings;
-import org.apache.qpid.transport.network.NetworkConnection;
-import org.apache.qpid.transport.network.OutgoingNetworkTransport;
-import org.apache.qpid.transport.network.Transport;
-import org.apache.qpid.transport.network.security.SecurityLayer;
-import org.apache.qpid.transport.network.security.SecurityLayerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -71,30 +60,8 @@ public class AMQConnectionDelegate_8_0 implements AMQConnectionDelegate
public void closeConnection(long timeout) throws JMSException, AMQException
{
- final AMQStateManager stateManager = _conn.getProtocolHandler().getStateManager();
- final AMQState currentState = stateManager.getCurrentState();
+ _conn.getProtocolHandler().closeConnection(timeout);
- if (currentState.equals(AMQState.CONNECTION_CLOSED))
- {
- _logger.debug("Connection already closed.");
- }
- else if (currentState.equals(AMQState.CONNECTION_CLOSING))
- {
- _logger.debug("Connection already closing, awaiting closed state.");
- final StateWaiter closeWaiter = new StateWaiter(stateManager, currentState, EnumSet.of(AMQState.CONNECTION_CLOSED));
- try
- {
- closeWaiter.await(timeout);
- }
- catch (AMQTimeoutException te)
- {
- throw new AMQTimeoutException("Close did not complete in timely fashion", te);
- }
- }
- else
- {
- _conn.getProtocolHandler().closeConnection(timeout);
- }
}
public AMQConnectionDelegate_8_0(AMQConnection conn)
@@ -122,34 +89,15 @@ public class AMQConnectionDelegate_8_0 implements AMQConnectionDelegate
StateWaiter waiter = _conn._protocolHandler.createWaiter(openOrClosedStates);
- ConnectionSettings settings = brokerDetail.buildConnectionSettings();
- settings.setProtocol(brokerDetail.getTransport());
-
- SSLContext sslContext = null;
- if (settings.isUseSSL())
+ // TODO: use system property thingy for this
+ if (System.getProperty("UseTransportIo", "false").equals("false"))
{
- try
- {
- sslContext = SSLContextFactory.buildClientContext(
- settings.getTrustStorePath(),
- settings.getTrustStorePassword(),
- settings.getTrustStoreCertType(),
- settings.getKeyStorePath(),
- settings.getKeyStorePassword(),
- settings.getKeyStoreCertType(),
- settings.getCertAlias());
- }
- catch (GeneralSecurityException e)
- {
- throw new AMQException("Unable to create SSLContext: " + e.getMessage(), e);
- }
+ TransportConnection.getInstance(brokerDetail).connect(_conn._protocolHandler, brokerDetail);
+ }
+ else
+ {
+ _conn.getProtocolHandler().createIoTransportSession(brokerDetail);
}
-
- SecurityLayer securityLayer = SecurityLayerFactory.newInstance(settings);
-
- OutgoingNetworkTransport transport = Transport.getOutgoingTransportInstance(getProtocolVersion());
- NetworkConnection network = transport.connect(settings, securityLayer.receiver(_conn._protocolHandler), sslContext);
- _conn._protocolHandler.setNetworkConnection(network, securityLayer.sender(network.getSender()));
_conn._protocolHandler.getProtocolSession().init();
// this blocks until the connection has been set up or when an error
// has prevented the connection being set up
@@ -374,9 +322,4 @@ public class AMQConnectionDelegate_8_0 implements AMQConnectionDelegate
{
return ProtocolVersion.v8_0;
}
-
- public boolean verifyClientID() throws JMSException
- {
- return true;
- }
}
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 f0c003e02a..ec4c668d7e 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
@@ -44,34 +44,210 @@ public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionF
ObjectFactory, Referenceable, XATopicConnectionFactory,
XAQueueConnectionFactory, XAConnectionFactory
{
- private final ConnectionURL _connectionDetails;
+ private String _host;
+ private int _port;
+ private String _defaultUsername;
+ private String _defaultPassword;
+ private String _virtualPath;
- public AMQConnectionFactory(final String url) throws URLSyntaxException
+ private ConnectionURL _connectionDetails;
+ private SSLConfiguration _sslConfig;
+
+ public AMQConnectionFactory()
{
- if (url == null)
- {
- throw new IllegalArgumentException("url cannot be null");
- }
+ }
+ /**
+ * This is the Only constructor used!
+ * It is used form the context and from the JNDI objects.
+ */
+ public AMQConnectionFactory(String url) throws URLSyntaxException
+ {
_connectionDetails = new AMQConnectionURL(url);
}
+ /**
+ * This constructor is never used!
+ */
public AMQConnectionFactory(ConnectionURL url)
{
- if (url == null)
+ _connectionDetails = url;
+ }
+
+ /**
+ * This constructor is never used!
+ */
+ public AMQConnectionFactory(String broker, String username, String password, String clientName, String virtualHost)
+ throws URLSyntaxException
+ {
+ this(new AMQConnectionURL(
+ ConnectionURL.AMQ_PROTOCOL + "://" + username + ":" + password + "@" + clientName + "/" + virtualHost + "?brokerlist='" + broker + "'"));
+ }
+
+ /**
+ * This constructor is never used!
+ */
+ public AMQConnectionFactory(String host, int port, String virtualPath)
+ {
+ this(host, port, "guest", "guest", virtualPath);
+ }
+
+ /**
+ * This constructor is never used!
+ */
+ public AMQConnectionFactory(String host, int port, String defaultUsername, String defaultPassword,
+ String virtualPath)
+ {
+ _host = host;
+ _port = port;
+ _defaultUsername = defaultUsername;
+ _defaultPassword = defaultPassword;
+ _virtualPath = virtualPath;
+
+//todo when setting Host/Port has been resolved then we can use this otherwise those methods won't work with the following line.
+// _connectionDetails = new AMQConnectionURL(
+// ConnectionURL.AMQ_PROTOCOL + "://" +
+// _defaultUsername + ":" + _defaultPassword + "@" +
+// virtualPath + "?brokerlist='tcp://" + host + ":" + port + "'");
+ }
+
+ /**
+ * @return The _defaultPassword.
+ */
+ public final String getDefaultPassword(String password)
+ {
+ if (_connectionDetails != null)
{
- throw new IllegalArgumentException("url cannot be null");
+ return _connectionDetails.getPassword();
}
+ else
+ {
+ return _defaultPassword;
+ }
+ }
- _connectionDetails = url;
+ /**
+ * @param password The _defaultPassword to set.
+ */
+ public final void setDefaultPassword(String password)
+ {
+ if (_connectionDetails != null)
+ {
+ _connectionDetails.setPassword(password);
+ }
+ _defaultPassword = password;
+ }
+
+ /**
+ * Getter for SSLConfiguration
+ *
+ * @return SSLConfiguration if set, otherwise null
+ */
+ public final SSLConfiguration getSSLConfiguration()
+ {
+ return _sslConfig;
+ }
+
+ /**
+ * Setter for SSLConfiguration
+ *
+ * @param sslConfig config to store
+ */
+ public final void setSSLConfiguration(SSLConfiguration sslConfig)
+ {
+ _sslConfig = sslConfig;
+ }
+
+ /**
+ * @return The _defaultPassword.
+ */
+ public final String getDefaultUsername(String password)
+ {
+ if (_connectionDetails != null)
+ {
+ return _connectionDetails.getUsername();
+ }
+ else
+ {
+ return _defaultUsername;
+ }
+ }
+
+ /**
+ * @param username The _defaultUsername to set.
+ */
+ public final void setDefaultUsername(String username)
+ {
+ if (_connectionDetails != null)
+ {
+ _connectionDetails.setUsername(username);
+ }
+ _defaultUsername = username;
+ }
+
+ /**
+ * @return The _host .
+ */
+ public final String getHost()
+ {
+ //todo this doesn't make sense in a multi broker URL as we have no current as that is done by AMQConnection
+ return _host;
}
/**
- * @return the virtualPath of the connection details.
+ * @param host The _host to set.
+ */
+ public final void setHost(String host)
+ {
+ //todo if _connectionDetails is set then run _connectionDetails.addBrokerDetails()
+ // Should perhaps have this method changed to setBroker(host,port)
+ _host = host;
+ }
+
+ /**
+ * @return _port The _port to set.
+ */
+ public final int getPort()
+ {
+ //todo see getHost
+ return _port;
+ }
+
+ /**
+ * @param port The port to set.
+ */
+ public final void setPort(int port)
+ {
+ //todo see setHost
+ _port = port;
+ }
+
+ /**
+ * @return he _virtualPath.
*/
public final String getVirtualPath()
{
- return _connectionDetails.getVirtualHost();
+ if (_connectionDetails != null)
+ {
+ return _connectionDetails.getVirtualHost();
+ }
+ else
+ {
+ return _virtualPath;
+ }
+ }
+
+ /**
+ * @param path The _virtualPath to set.
+ */
+ public final void setVirtualPath(String path)
+ {
+ if (_connectionDetails != null)
+ {
+ _connectionDetails.setVirtualHost(path);
+ }
+
+ _virtualPath = path;
}
public static String getUniqueClientID()
@@ -91,11 +267,19 @@ public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionF
{
try
{
- if (_connectionDetails.getClientName() == null || _connectionDetails.getClientName().equals(""))
+ if (_connectionDetails != null)
{
- _connectionDetails.setClientName(getUniqueClientID());
+ if (_connectionDetails.getClientName() == null || _connectionDetails.getClientName().equals(""))
+ {
+ _connectionDetails.setClientName(getUniqueClientID());
+ }
+ return new AMQConnection(_connectionDetails, _sslConfig);
+ }
+ else
+ {
+ return new AMQConnection(_host, _port, _defaultUsername, _defaultPassword, getUniqueClientID(),
+ _virtualPath);
}
- return new AMQConnection(_connectionDetails);
}
catch (Exception e)
{
@@ -104,6 +288,8 @@ public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionF
jmse.initCause(e);
throw jmse;
}
+
+
}
public Connection createConnection(String userName, String password) throws JMSException
@@ -113,35 +299,34 @@ public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionF
public Connection createConnection(String userName, String password, String id) throws JMSException
{
- if (_connectionDetails != null)
+ try
{
- try
+ if (_connectionDetails != null)
{
- ConnectionURL connectionDetails = new AMQConnectionURL(_connectionDetails.toString());
- connectionDetails.setUsername(userName);
- connectionDetails.setPassword(password);
+ _connectionDetails.setUsername(userName);
+ _connectionDetails.setPassword(password);
if (id != null && !id.equals(""))
{
- connectionDetails.setClientName(id);
+ _connectionDetails.setClientName(id);
}
- else if (connectionDetails.getClientName() == null || connectionDetails.getClientName().equals(""))
+ else if (_connectionDetails.getClientName() == null || _connectionDetails.getClientName().equals(""))
{
- connectionDetails.setClientName(getUniqueClientID());
+ _connectionDetails.setClientName(getUniqueClientID());
}
- return new AMQConnection(connectionDetails);
+ return new AMQConnection(_connectionDetails, _sslConfig);
}
- catch (Exception e)
+ else
{
- JMSException jmse = new JMSException("Error creating connection: " + e.getMessage());
- jmse.setLinkedException(e);
- jmse.initCause(e);
- throw jmse;
+ return new AMQConnection(_host, _port, userName, password, (id != null ? id : getUniqueClientID()), _virtualPath);
}
}
- else
+ catch (Exception e)
{
- throw new JMSException("The connection factory wasn't created with a proper URL, the connection details are empty");
+ JMSException jmse = new JMSException("Error creating connection: " + e.getMessage());
+ jmse.setLinkedException(e);
+ jmse.initCause(e);
+ throw jmse;
}
}
@@ -176,6 +361,12 @@ public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionF
return _connectionDetails.toString();
}
+
+ public final void setConnectionURLString(String url) throws URLSyntaxException
+ {
+ _connectionDetails = new AMQConnectionURL(url);
+ }
+
/**
* JNDI interface to create objects from References.
*
@@ -266,7 +457,7 @@ public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionF
{
try
{
- return new XAConnectionImpl(_connectionDetails);
+ return new XAConnectionImpl(_connectionDetails, _sslConfig);
}
catch (Exception e)
{
@@ -293,30 +484,19 @@ public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionF
{
if (_connectionDetails != null)
{
- try
- {
- ConnectionURL connectionDetails = new AMQConnectionURL(_connectionDetails.toString());
- connectionDetails.setUsername(username);
- connectionDetails.setPassword(password);
-
- if (connectionDetails.getClientName() == null || connectionDetails.getClientName().equals(""))
- {
- connectionDetails.setClientName(getUniqueClientID());
- }
- return new XAConnectionImpl(connectionDetails);
- }
- catch (Exception e)
+ _connectionDetails.setUsername(username);
+ _connectionDetails.setPassword(password);
+
+ if (_connectionDetails.getClientName() == null || _connectionDetails.getClientName().equals(""))
{
- JMSException jmse = new JMSException("Error creating XA Connection: " + e.getMessage());
- jmse.setLinkedException(e);
- jmse.initCause(e);
- throw jmse;
+ _connectionDetails.setClientName(getUniqueClientID());
}
}
else
{
- throw new JMSException("The connection factory wasn't created with a proper URL, the connection details are empty");
- }
+ throw new JMSException("A URL must be specified to access XA connections");
+ }
+ return createXAConnection();
}
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 f9f50d9150..93b4c51a8f 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
@@ -27,14 +27,18 @@ import java.util.Map;
import org.apache.qpid.client.url.URLParser;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.jms.BrokerDetails;
import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.url.URLHelper;
import org.apache.qpid.url.URLSyntaxException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class AMQConnectionURL implements ConnectionURL
{
-
+ private static final Logger _logger = LoggerFactory.getLogger(AMQConnectionURL.class);
+
private String _url;
private String _failoverMethod;
private Map<String, String> _failoverOptions;
@@ -291,4 +295,17 @@ public class AMQConnectionURL implements ConnectionURL
return sb.toString();
}
+
+ public static void main(String[] args) throws URLSyntaxException
+ {
+ String url2 =
+ "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);
+
+ System.out.println(url2);
+ System.out.println(connectionurl2);
+
+ }
}
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 acd46da11a..eb9682a3cf 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
@@ -21,6 +21,8 @@
package org.apache.qpid.client;
import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import javax.jms.Destination;
@@ -32,6 +34,8 @@ import javax.naming.StringRefAddr;
import org.apache.qpid.client.messaging.address.AddressHelper;
import org.apache.qpid.client.messaging.address.Link;
import org.apache.qpid.client.messaging.address.Node;
+import org.apache.qpid.client.messaging.address.QpidExchangeOptions;
+import org.apache.qpid.client.messaging.address.QpidQueueOptions;
import org.apache.qpid.configuration.ClientProperties;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
@@ -74,6 +78,11 @@ public abstract class AMQDestination implements Destination, Referenceable
private boolean _exchangeExistsChecked;
+ private byte[] _byteEncoding;
+ private static final int IS_DURABLE_MASK = 0x1;
+ private static final int IS_EXCLUSIVE_MASK = 0x2;
+ private static final int IS_AUTODELETE_MASK = 0x4;
+
public static final int QUEUE_TYPE = 1;
public static final int TOPIC_TYPE = 2;
public static final int UNKNOWN_TYPE = 3;
@@ -314,11 +323,7 @@ public abstract class AMQDestination implements Destination, Referenceable
{
if(_urlAsShortString == null)
{
- if (_url == null)
- {
- toURL();
- }
- _urlAsShortString = new AMQShortString(_url);
+ toURL();
}
return _urlAsShortString;
}
@@ -365,6 +370,7 @@ public abstract class AMQDestination implements Destination, Referenceable
// calculated URL now out of date
_url = null;
_urlAsShortString = null;
+ _byteEncoding = null;
}
public AMQShortString getRoutingKey()
@@ -502,10 +508,59 @@ public abstract class AMQDestination implements Destination, Referenceable
sb.deleteCharAt(sb.length() - 1);
url = sb.toString();
_url = url;
+ _urlAsShortString = new AMQShortString(url);
}
return url;
}
+ public byte[] toByteEncoding()
+ {
+ byte[] encoding = _byteEncoding;
+ if(encoding == null)
+ {
+ int size = _exchangeClass.length() + 1 +
+ _exchangeName.length() + 1 +
+ 0 + // in place of the destination name
+ (_queueName == null ? 0 : _queueName.length()) + 1 +
+ 1;
+ encoding = new byte[size];
+ int pos = 0;
+
+ pos = _exchangeClass.writeToByteArray(encoding, pos);
+ pos = _exchangeName.writeToByteArray(encoding, pos);
+
+ encoding[pos++] = (byte)0;
+
+ if(_queueName == null)
+ {
+ encoding[pos++] = (byte)0;
+ }
+ else
+ {
+ pos = _queueName.writeToByteArray(encoding,pos);
+ }
+ byte options = 0;
+ if(_isDurable)
+ {
+ options |= IS_DURABLE_MASK;
+ }
+ if(_isExclusive)
+ {
+ options |= IS_EXCLUSIVE_MASK;
+ }
+ if(_isAutoDelete)
+ {
+ options |= IS_AUTODELETE_MASK;
+ }
+ encoding[pos] = options;
+
+
+ _byteEncoding = encoding;
+
+ }
+ return encoding;
+ }
+
public boolean equals(Object o)
{
if (this == o)
@@ -559,6 +614,53 @@ public abstract class AMQDestination implements Destination, Referenceable
null); // factory location
}
+
+ public static Destination createDestination(byte[] byteEncodedDestination)
+ {
+ AMQShortString exchangeClass;
+ AMQShortString exchangeName;
+ AMQShortString routingKey;
+ AMQShortString queueName;
+ boolean isDurable;
+ boolean isExclusive;
+ boolean isAutoDelete;
+
+ int pos = 0;
+ exchangeClass = AMQShortString.readFromByteArray(byteEncodedDestination, pos);
+ pos+= exchangeClass.length() + 1;
+ exchangeName = AMQShortString.readFromByteArray(byteEncodedDestination, pos);
+ pos+= exchangeName.length() + 1;
+ routingKey = AMQShortString.readFromByteArray(byteEncodedDestination, pos);
+ pos+= (routingKey == null ? 0 : routingKey.length()) + 1;
+ queueName = AMQShortString.readFromByteArray(byteEncodedDestination, pos);
+ pos+= (queueName == null ? 0 : queueName.length()) + 1;
+ int options = byteEncodedDestination[pos];
+ isDurable = (options & IS_DURABLE_MASK) != 0;
+ isExclusive = (options & IS_EXCLUSIVE_MASK) != 0;
+ isAutoDelete = (options & IS_AUTODELETE_MASK) != 0;
+
+ if (exchangeClass.equals(ExchangeDefaults.DIRECT_EXCHANGE_CLASS))
+ {
+ return new AMQQueue(exchangeName,routingKey,queueName,isExclusive,isAutoDelete,isDurable);
+ }
+ else if (exchangeClass.equals(ExchangeDefaults.TOPIC_EXCHANGE_CLASS))
+ {
+ return new AMQTopic(exchangeName,routingKey,isAutoDelete,queueName,isDurable);
+ }
+ else if (exchangeClass.equals(ExchangeDefaults.HEADERS_EXCHANGE_CLASS))
+ {
+ return new AMQHeadersExchange(routingKey);
+ }
+ else
+ {
+ return new AMQAnyDestination(exchangeName,exchangeClass,
+ routingKey,isExclusive,
+ isAutoDelete,queueName,
+ isDurable, new AMQShortString[0]);
+ }
+
+ }
+
public static Destination createDestination(BindingURL binding)
{
AMQShortString type = binding.getExchangeClass();
@@ -793,7 +895,7 @@ public abstract class AMQDestination implements Destination, Referenceable
return _browseOnly;
}
- private void setBrowseOnly(boolean b)
+ public void setBrowseOnly(boolean b)
{
_browseOnly = b;
}
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 d34290e007..1f940b62f0 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
@@ -70,6 +70,7 @@ import org.apache.qpid.AMQDisconnectedException;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQInvalidArgumentException;
import org.apache.qpid.AMQInvalidRoutingKeyException;
+import org.apache.qpid.client.AMQDestination.AddressOption;
import org.apache.qpid.client.AMQDestination.DestSyntax;
import org.apache.qpid.client.failover.FailoverException;
import org.apache.qpid.client.failover.FailoverNoopSupport;
@@ -87,6 +88,8 @@ import org.apache.qpid.client.message.JMSTextMessage;
import org.apache.qpid.client.message.MessageFactoryRegistry;
import org.apache.qpid.client.message.UnprocessedMessage;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
+import org.apache.qpid.client.state.AMQState;
+import org.apache.qpid.client.state.AMQStateManager;
import org.apache.qpid.client.util.FlowControllingBlockingQueue;
import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.framing.AMQShortString;
@@ -94,10 +97,7 @@ 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.thread.Threading;
-import org.apache.qpid.transport.SessionException;
-import org.apache.qpid.transport.TransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -213,6 +213,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
*/
protected final boolean DEFAULT_MANDATORY = Boolean.parseBoolean(System.getProperty("qpid.default_mandatory", "true"));
+ protected final boolean DEFAULT_WAIT_ON_SEND = Boolean.parseBoolean(System.getProperty("qpid.default_wait_on_send", "false"));
+
/**
* The period to wait while flow controlled before sending a log message confirming that the session is still
* waiting on flow control being revoked
@@ -308,7 +310,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
protected final FlowControllingBlockingQueue _queue;
/** Holds the highest received delivery tag. */
- protected final AtomicLong _highestDeliveryTag = new AtomicLong(-1);
+ private final AtomicLong _highestDeliveryTag = new AtomicLong(-1);
private final AtomicLong _rollbackMark = new AtomicLong(-1);
/** All the not yet acknowledged message tags */
@@ -362,13 +364,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
* Set when recover is called. This is to handle the case where recover() is called by application code during
* onMessage() processing to ensure that an auto ack is not sent.
*/
- private volatile boolean _sessionInRecovery;
-
- /**
- * Set when the dispatcher should direct incoming messages straight into the UnackedMessage list instead of
- * to the syncRecieveQueue or MessageListener. Used during cleanup, e.g. in Session.recover().
- */
- private volatile boolean _usingDispatcherForCleanup;
+ private boolean _inRecovery;
/** Used to indicates that the connection to which this session belongs, has been stopped. */
private boolean _connectionStopped;
@@ -571,8 +567,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
close(-1);
}
- public abstract AMQException getLastException();
-
public void checkNotClosed() throws JMSException
{
try
@@ -581,20 +575,16 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
}
catch (IllegalStateException ise)
{
- AMQException ex = getLastException();
- if (ex != null)
- {
- IllegalStateException ssnClosed = new IllegalStateException(
- "Session has been closed", ex.getErrorCode().toString());
+ // if the Connection has closed then we should throw any exception that has occurred that we were not waiting for
+ AMQStateManager manager = _connection.getProtocolHandler().getStateManager();
- ssnClosed.setLinkedException(ex);
- ssnClosed.initCause(ex);
- throw ssnClosed;
- }
- else
+ if (manager.getCurrentState().equals(AMQState.CONNECTION_CLOSED) && manager.getLastException() != null)
{
- throw ise;
+ ise.setLinkedException(manager.getLastException());
+ ise.initCause(ise.getLinkedException());
}
+
+ throw ise;
}
}
@@ -610,36 +600,29 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
* Acknowledges all unacknowledged messages on the session, for all message consumers on the session.
*
* @throws IllegalStateException If the session is closed.
- * @throws JMSException if there is a problem during acknowledge process.
*/
- public void acknowledge() throws IllegalStateException, JMSException
+ public void acknowledge() throws IllegalStateException
{
if (isClosed())
{
throw new IllegalStateException("Session is already closed");
}
- else if (hasFailedOverDirty())
+ else if (hasFailedOver())
{
- //perform an implicit recover in this scenario
- recover();
-
- //notify the consumer
throw new IllegalStateException("has failed over");
}
- try
- {
- acknowledgeImpl();
- markClean();
- }
- catch (TransportException e)
+ while (true)
{
- throw toJMSException("Exception while acknowledging message(s):" + e.getMessage(), e);
+ Long tag = _unacknowledgedMessageTags.poll();
+ if (tag == null)
+ {
+ break;
+ }
+ acknowledgeMessage(tag, false);
}
}
- protected abstract void acknowledgeImpl() throws JMSException;
-
/**
* Acknowledge one or many messages.
*
@@ -774,10 +757,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
_logger.debug(
"Got FailoverException during channel close, ignored as channel already marked as closed.");
}
- catch (TransportException e)
- {
- throw toJMSException("Error closing session:" + e.getMessage(), e);
- }
finally
{
_connection.deregisterSession(_channelId);
@@ -848,44 +827,51 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
* @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();
- //Check that we are clean to commit.
- if (_failedOverDirty)
+ try
{
- if (_logger.isDebugEnabled())
+ //Check that we are clean to commit.
+ if (_failedOverDirty)
{
- _logger.debug("Session " + _channelId + " was dirty whilst failing over. Rolling back.");
+ rollback();
+
+ throw new TransactionRolledBackException("Connection failover has occured since last send. " +
+ "Forced rollback");
}
- rollback();
- throw new TransactionRolledBackException("Connection failover has occured with uncommitted transaction activity." +
- "The session transaction was rolled back.");
- }
- try
- {
- commitImpl();
+ // Acknowledge all delivered messages
+ while (true)
+ {
+ Long tag = _deliveredMessageTags.poll();
+ if (tag == null)
+ {
+ break;
+ }
+
+ acknowledgeMessage(tag, false);
+ }
+ // Commits outstanding messages and acknowledgments
+ sendCommit();
markClean();
}
catch (AMQException e)
{
- throw new JMSAMQException("Exception during commit: " + e.getMessage() + ":" + e.getCause(), e);
+ throw new JMSAMQException("Failed to commit: " + e.getMessage() + ":" + e.getCause(), e);
}
catch (FailoverException e)
{
throw new JMSAMQException("Fail-over interrupted commit. Status of the commit is uncertain.", e);
}
- catch(TransportException e)
- {
- throw toJMSException("Session exception occured while trying to commit: " + e.getMessage(), e);
- }
}
- protected abstract void commitImpl() throws AMQException, FailoverException, TransportException;
+ public abstract void sendCommit() throws AMQException, FailoverException;
+
public void confirmConsumerCancelled(int consumerTag)
{
@@ -963,7 +949,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
return new AMQQueueBrowser(this, (AMQQueue) queue, messageSelector);
}
- protected MessageConsumer createBrowserConsumer(Destination destination, String messageSelector, boolean noLocal)
+ public MessageConsumer createBrowserConsumer(Destination destination, String messageSelector, boolean noLocal)
throws JMSException
{
checkValidDestination(destination);
@@ -977,7 +963,15 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
checkValidDestination(destination);
return createConsumerImpl(destination, _prefetchHighMark, _prefetchLowMark, false, (destination instanceof Topic), null, null,
- isBrowseOnlyDestination(destination), false);
+ ((destination instanceof AMQDestination) && ((AMQDestination)destination).isBrowseOnly()), false);
+ }
+
+ public C createExclusiveConsumer(Destination destination) throws JMSException
+ {
+ checkValidDestination(destination);
+
+ return createConsumerImpl(destination, _prefetchHighMark, _prefetchLowMark, false, true, null, null,
+ ((destination instanceof AMQDestination) && ((AMQDestination)destination).isBrowseOnly()), false);
}
public MessageConsumer createConsumer(Destination destination, String messageSelector) throws JMSException
@@ -985,7 +979,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
checkValidDestination(destination);
return createConsumerImpl(destination, _prefetchHighMark, _prefetchLowMark, false, (destination instanceof Topic),
- messageSelector, null, isBrowseOnlyDestination(destination), false);
+ messageSelector, null, ((destination instanceof AMQDestination) && ((AMQDestination)destination).isBrowseOnly()), false);
}
public MessageConsumer createConsumer(Destination destination, String messageSelector, boolean noLocal)
@@ -994,7 +988,16 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
checkValidDestination(destination);
return createConsumerImpl(destination, _prefetchHighMark, _prefetchLowMark, noLocal, (destination instanceof Topic),
- messageSelector, null, isBrowseOnlyDestination(destination), false);
+ messageSelector, null, ((destination instanceof AMQDestination) && ((AMQDestination)destination).isBrowseOnly()), false);
+ }
+
+ public MessageConsumer createExclusiveConsumer(Destination destination, String messageSelector, boolean noLocal)
+ throws JMSException
+ {
+ checkValidDestination(destination);
+
+ return createConsumerImpl(destination, _prefetchHighMark, _prefetchLowMark, noLocal, true,
+ messageSelector, null, false, false);
}
public MessageConsumer createConsumer(Destination destination, int prefetch, boolean noLocal, boolean exclusive,
@@ -1002,15 +1005,23 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
checkValidDestination(destination);
- return createConsumerImpl(destination, prefetch, prefetch / 2, noLocal, exclusive, selector, null, isBrowseOnlyDestination(destination), false);
+ return createConsumerImpl(destination, prefetch, prefetch / 2, noLocal, exclusive, selector, null, ((destination instanceof AMQDestination) && ((AMQDestination)destination).isBrowseOnly()), false);
}
public MessageConsumer createConsumer(Destination destination, int prefetchHigh, int prefetchLow, boolean noLocal,
- boolean exclusive, String selector) throws JMSException
+ boolean exclusive, String selector) throws JMSException
{
checkValidDestination(destination);
- return createConsumerImpl(destination, prefetchHigh, prefetchLow, noLocal, exclusive, selector, null, isBrowseOnlyDestination(destination), false);
+ return createConsumerImpl(destination, prefetchHigh, prefetchLow, noLocal, exclusive, selector, null, ((destination instanceof AMQDestination) && ((AMQDestination)destination).isBrowseOnly()), false);
+ }
+
+ public MessageConsumer createConsumer(Destination destination, int prefetch, boolean noLocal, boolean exclusive,
+ String selector, FieldTable rawSelector) throws JMSException
+ {
+ checkValidDestination(destination);
+
+ return createConsumerImpl(destination, prefetch, prefetch / 2, noLocal, exclusive, selector, rawSelector, ((destination instanceof AMQDestination) && ((AMQDestination)destination).isBrowseOnly()), false);
}
public MessageConsumer createConsumer(Destination destination, int prefetchHigh, int prefetchLow, boolean noLocal,
@@ -1018,7 +1029,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
checkValidDestination(destination);
- return createConsumerImpl(destination, prefetchHigh, prefetchLow, noLocal, exclusive, selector, rawSelector, isBrowseOnlyDestination(destination),
+ return createConsumerImpl(destination, prefetchHigh, prefetchLow, noLocal, exclusive, selector, rawSelector, ((destination instanceof AMQDestination) && ((AMQDestination)destination).isBrowseOnly()),
false);
}
@@ -1032,33 +1043,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
throws JMSException
{
checkNotClosed();
- Topic origTopic = checkValidTopic(topic, true);
-
+ AMQTopic origTopic = checkValidTopic(topic, true);
AMQTopic dest = AMQTopic.createDurableTopic(origTopic, name, _connection);
- if (dest.getDestSyntax() == DestSyntax.ADDR &&
- !dest.isAddressResolved())
- {
- try
- {
- handleAddressBasedDestination(dest,false,true);
- if (dest.getAddressType() != AMQDestination.TOPIC_TYPE)
- {
- throw new JMSException("Durable subscribers can only be created for Topics");
- }
- dest.getSourceNode().setDurable(true);
- }
- catch(AMQException e)
- {
- JMSException ex = new JMSException("Error when verifying destination");
- ex.initCause(e);
- ex.setLinkedException(e);
- throw ex;
- }
- catch(TransportException e)
- {
- throw toJMSException("Error when verifying destination", e);
- }
- }
String messageSelector = ((selector == null) || (selector.trim().length() == 0)) ? null : selector;
@@ -1070,9 +1056,15 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
// Not subscribed to this name in the current session
if (subscriber == null)
{
- // After the address is resolved routing key will not be null.
- AMQShortString topicName = dest.getRoutingKey();
-
+ AMQShortString topicName;
+ if (topic instanceof AMQTopic)
+ {
+ topicName = ((AMQTopic) topic).getRoutingKey();
+ } else
+ {
+ topicName = new AMQShortString(topic.getTopicName());
+ }
+
if (_strictAMQP)
{
if (_strictAMQPFATAL)
@@ -1143,10 +1135,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
return subscriber;
}
- catch (TransportException e)
- {
- throw toJMSException("Exception while creating durable subscriber:" + e.getMessage(), e);
- }
finally
{
_subscriberDetails.unlock();
@@ -1207,6 +1195,12 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
return createProducerImpl(destination, mandatory, immediate);
}
+ public P createProducer(Destination destination, boolean mandatory, boolean immediate,
+ boolean waitUntilSent) throws JMSException
+ {
+ return createProducerImpl(destination, mandatory, immediate, waitUntilSent);
+ }
+
public TopicPublisher createPublisher(Topic topic) throws JMSException
{
checkNotClosed();
@@ -1231,6 +1225,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
else
{
AMQQueue queue = new AMQQueue(queueName);
+ queue.setCreate(AddressOption.ALWAYS);
return queue;
}
@@ -1312,8 +1307,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public QueueReceiver createQueueReceiver(Destination destination) throws JMSException
{
checkValidDestination(destination);
- Queue dest = validateQueue(destination);
- C consumer = (C) createConsumer(dest);
+ AMQQueue dest = (AMQQueue) destination;
+ C consumer = (C) createConsumer(destination);
return new QueueReceiverAdaptor(dest, consumer);
}
@@ -1331,8 +1326,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public QueueReceiver createQueueReceiver(Destination destination, String messageSelector) throws JMSException
{
checkValidDestination(destination);
- Queue dest = validateQueue(destination);
- C consumer = (C) createConsumer(dest, messageSelector);
+ AMQQueue dest = (AMQQueue) destination;
+ C consumer = (C) createConsumer(destination, messageSelector);
return new QueueReceiverAdaptor(dest, consumer);
}
@@ -1349,7 +1344,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public QueueReceiver createReceiver(Queue queue) throws JMSException
{
checkNotClosed();
- Queue dest = validateQueue(queue);
+ AMQQueue dest = (AMQQueue) queue;
C consumer = (C) createConsumer(dest);
return new QueueReceiverAdaptor(dest, consumer);
@@ -1368,28 +1363,17 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public QueueReceiver createReceiver(Queue queue, String messageSelector) throws JMSException
{
checkNotClosed();
- Queue dest = validateQueue(queue);
+ AMQQueue dest = (AMQQueue) queue;
C consumer = (C) createConsumer(dest, messageSelector);
return new QueueReceiverAdaptor(dest, consumer);
}
-
- private Queue validateQueue(Destination dest) throws InvalidDestinationException
- {
- if (dest instanceof AMQDestination && dest instanceof javax.jms.Queue)
- {
- return (Queue)dest;
- }
- else
- {
- throw new InvalidDestinationException("The destination object used is not from this provider or of type javax.jms.Queue");
- }
- }
public QueueSender createSender(Queue queue) throws JMSException
{
checkNotClosed();
+ // return (QueueSender) createProducer(queue);
return new QueueSenderAdapter(createProducer(queue), queue);
}
@@ -1424,10 +1408,10 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public TopicSubscriber createSubscriber(Topic topic) throws JMSException
{
checkNotClosed();
- checkValidTopic(topic);
+ AMQTopic dest = checkValidTopic(topic);
- return new TopicSubscriberAdaptor<C>(topic,
- createConsumerImpl(topic, _prefetchHighMark, _prefetchLowMark, false, true, null, null, false, false));
+ // AMQTopic dest = new AMQTopic(topic.getTopicName());
+ return new TopicSubscriberAdaptor(dest, (C) createExclusiveConsumer(dest));
}
/**
@@ -1444,11 +1428,10 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public TopicSubscriber createSubscriber(Topic topic, String messageSelector, boolean noLocal) throws JMSException
{
checkNotClosed();
- checkValidTopic(topic);
+ AMQTopic dest = checkValidTopic(topic);
- return new TopicSubscriberAdaptor<C>(topic,
- createConsumerImpl(topic, _prefetchHighMark, _prefetchLowMark, noLocal,
- true, messageSelector, null, false, false));
+ // AMQTopic dest = new AMQTopic(topic.getTopicName());
+ return new TopicSubscriberAdaptor(dest, (C) createExclusiveConsumer(dest, messageSelector, noLocal));
}
public TemporaryQueue createTemporaryQueue() throws JMSException
@@ -1550,8 +1533,10 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
abstract public void sync() throws AMQException;
- public int getAcknowledgeMode()
+ public int getAcknowledgeMode() throws JMSException
{
+ checkNotClosed();
+
return _acknowledgeMode;
}
@@ -1611,8 +1596,10 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
return _ticket;
}
- public boolean getTransacted()
+ public boolean getTransacted() throws JMSException
{
+ checkNotClosed();
+
return _transacted;
}
@@ -1708,14 +1695,13 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
// Ensure that the session is not transacted.
checkNotTransacted();
-
+ // flush any acks we are holding in the buffer.
+ flushAcknowledgments();
+
+ // this is set only here, and the before the consumer's onMessage is called it is set to false
+ _inRecovery = true;
try
{
- // flush any acks we are holding in the buffer.
- flushAcknowledgments();
-
- // this is only set true here, and only set false when the consumers preDeliver method is called
- _sessionInRecovery = true;
boolean isSuspended = isSuspended();
@@ -1723,18 +1709,9 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
suspendChannel(true);
}
-
- // Set to true to short circuit delivery of anything currently
- //in the pre-dispatch queue.
- _usingDispatcherForCleanup = true;
-
+
syncDispatchQueue();
-
- // Set to false before sending the recover as 0-8/9/9-1 will
- //send messages back before the recover completes, and we
- //probably shouldn't clean those! ;-)
- _usingDispatcherForCleanup = false;
-
+
if (_dispatcher != null)
{
_dispatcher.recover();
@@ -1743,7 +1720,10 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
sendRecover();
markClean();
-
+
+ // Set inRecovery to false before you start message flow again again.
+ _inRecovery = false;
+
if (!isSuspended)
{
suspendChannel(false);
@@ -1757,10 +1737,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
throw new JMSAMQException("Recovery was interrupted by fail-over. Recovery status is not known.", e);
}
- catch(TransportException e)
- {
- throw toJMSException("Recover failed: " + e.getMessage(), e);
- }
+
}
protected abstract void sendRecover() throws AMQException, FailoverException;
@@ -1818,7 +1795,9 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
suspendChannel(true);
}
- setRollbackMark();
+ // Let the dispatcher know that all the incomming messages
+ // should be rolled back(reject/release)
+ _rollbackMark.set(_highestDeliveryTag.get());
syncDispatchQueue();
@@ -1843,10 +1822,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
throw new JMSAMQException("Fail-over interrupted rollback. Status of the rollback is uncertain.", e);
}
- catch (TransportException e)
- {
- throw toJMSException("Failure to rollback:" + e.getMessage(), e);
- }
}
}
@@ -1893,14 +1868,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
*/
public void unsubscribe(String name) throws JMSException
{
- try
- {
- unsubscribe(name, false);
- }
- catch (TransportException e)
- {
- throw toJMSException("Exception while unsubscribing:" + e.getMessage(), e);
- }
+ unsubscribe(name, false);
}
/**
@@ -1977,12 +1945,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
checkTemporaryDestination(destination);
- if(!noConsume && isBrowseOnlyDestination(destination))
- {
- throw new InvalidDestinationException("The consumer being created is not 'noConsume'," +
- "but a 'browseOnly' Destination has been supplied.");
- }
-
final String messageSelector;
if (_strictAMQP && !((selector == null) || selector.equals("")))
@@ -2027,16 +1989,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
// argument, as specifying null for the arguments when querying means they should not be checked at all
ft.put(AMQPFilterTypes.JMS_SELECTOR.getValue(), messageSelector == null ? "" : messageSelector);
- C consumer;
- try
- {
- consumer = createMessageConsumer(amqd, prefetchHigh, prefetchLow,
- noLocal, exclusive, messageSelector, ft, noConsume, autoClose);
- }
- catch(TransportException e)
- {
- throw toJMSException("Exception while creating consumer: " + e.getMessage(), e);
- }
+ C consumer = createMessageConsumer(amqd, prefetchHigh, prefetchLow,
+ noLocal, exclusive, messageSelector, ft, noConsume, autoClose);
if (_messageListener != null)
{
@@ -2073,10 +2027,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
ex.initCause(e);
throw ex;
}
- catch (TransportException e)
- {
- throw toJMSException("Exception while registering consumer:" + e.getMessage(), e);
- }
+
return consumer;
}
}, _connection).execute();
@@ -2141,7 +2092,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
boolean isInRecovery()
{
- return _sessionInRecovery;
+ return _inRecovery;
}
boolean isQueueBound(AMQShortString exchangeName, AMQShortString queueName) throws JMSException
@@ -2263,7 +2214,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
void setInRecovery(boolean inRecovery)
{
- _sessionInRecovery = inRecovery;
+ _inRecovery = inRecovery;
}
boolean isStarted()
@@ -2444,7 +2395,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
/*
* I could have combined the last 3 methods, but this way it improves readability
*/
- protected Topic checkValidTopic(Topic topic, boolean durable) throws JMSException
+ protected AMQTopic checkValidTopic(Topic topic, boolean durable) throws JMSException
{
if (topic == null)
{
@@ -2463,17 +2414,17 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
("Cannot create a durable subscription with a temporary topic: " + topic);
}
- if (!(topic instanceof AMQDestination && topic instanceof javax.jms.Topic))
+ if (!(topic instanceof AMQTopic))
{
throw new javax.jms.InvalidDestinationException(
"Cannot create a subscription on topic created for another JMS Provider, class of topic provided is: "
+ topic.getClass().getName());
}
- return topic;
+ return (AMQTopic) topic;
}
- protected Topic checkValidTopic(Topic topic) throws JMSException
+ protected AMQTopic checkValidTopic(Topic topic) throws JMSException
{
return checkValidTopic(topic, false);
}
@@ -2602,9 +2553,15 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public abstract void sendConsume(C consumer, AMQShortString queueName,
AMQProtocolHandler protocolHandler, boolean nowait, String messageSelector, int tag) throws AMQException, FailoverException;
- private P createProducerImpl(final Destination destination, final boolean mandatory, final boolean immediate)
+ private P createProducerImpl(Destination destination, boolean mandatory, boolean immediate)
throws JMSException
{
+ return createProducerImpl(destination, mandatory, immediate, DEFAULT_WAIT_ON_SEND);
+ }
+
+ private P createProducerImpl(final Destination destination, final boolean mandatory,
+ final boolean immediate, final boolean waitUntilSent) throws JMSException
+ {
return new FailoverRetrySupport<P, JMSException>(
new FailoverProtectedOperation<P, JMSException>()
{
@@ -2612,18 +2569,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
checkNotClosed();
long producerId = getNextProducerId();
-
- P producer;
- try
- {
- producer = createMessageProducer(destination, mandatory,
- immediate, producerId);
- }
- catch (TransportException e)
- {
- throw toJMSException("Exception while creating producer:" + e.getMessage(), e);
- }
-
+ P producer = createMessageProducer(destination, mandatory,
+ immediate, waitUntilSent, producerId);
registerProducer(producerId, producer);
return producer;
@@ -2632,7 +2579,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
}
public abstract P createMessageProducer(final Destination destination, final boolean mandatory,
- final boolean immediate, final long producerId) throws JMSException;
+ final boolean immediate, final boolean waitUntilSent, long producerId) throws JMSException;
private void declareExchange(AMQDestination amqd, AMQProtocolHandler protocolHandler, boolean nowait) throws AMQException
{
@@ -2775,21 +2722,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
}
}
- /**
- * Undeclares the specified temporary queue/topic.
- *
- * <p/>Note that this operation automatically retries in the event of fail-over.
- *
- * @param amqQueue The name of the temporary destination 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 deleteTemporaryDestination(final TemporaryDestination amqQueue) throws JMSException
- {
- deleteQueue(amqQueue.getAMQQueueName());
- }
-
public abstract void sendQueueDelete(final AMQShortString queueName) throws AMQException, FailoverException;
private long getNextProducerId()
@@ -2887,7 +2819,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
declareQueue(amqd, protocolHandler, consumer.isNoLocal(), nowait);
}
- bindQueue(amqd.getAMQQueueName(), amqd.getRoutingKey(), consumer.getArguments(), amqd.getExchangeName(), amqd, nowait);
}
AMQShortString queueName = amqd.getAMQQueueName();
@@ -2895,6 +2826,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
// store the consumer queue name
consumer.setQueuename(queueName);
+ bindQueue(queueName, amqd.getRoutingKey(), consumer.getArguments(), amqd.getExchangeName(), amqd, nowait);
+
// If IMMEDIATE_PREFETCH is not required then suspsend the channel to delay prefetch
if (!_immediatePrefetch)
{
@@ -3045,10 +2978,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
throw new AMQException(null, "Fail-over interrupted suspend/unsuspend channel.", e);
}
- catch (TransportException e)
- {
- throw new AMQException(AMQConstant.getConstant(getErrorCode(e)), e.getMessage(), e);
- }
}
}
@@ -3087,11 +3016,21 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
*
* @return boolean true if failover has occured.
*/
- public boolean hasFailedOverDirty()
+ public boolean hasFailedOver()
{
return _failedOverDirty;
}
+ /**
+ * Check to see if any message have been sent in this transaction and have not been commited.
+ *
+ * @return boolean true if a message has been sent but not commited
+ */
+ public boolean isDirty()
+ {
+ return _dirty;
+ }
+
public void setTicket(int ticket)
{
_ticket = ticket;
@@ -3204,7 +3143,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
setConnectionStopped(true);
}
- setRollbackMark();
+ _rollbackMark.set(_highestDeliveryTag.get());
_dispatcherLogger.debug("Session Pre Dispatch Queue cleared");
@@ -3353,14 +3292,9 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
if (!(message instanceof CloseConsumerMessage)
&& tagLE(deliveryTag, _rollbackMark.get()))
{
- if (_logger.isDebugEnabled())
- {
- _logger.debug("Rejecting message because delivery tag " + deliveryTag
- + " <= rollback mark " + _rollbackMark.get());
- }
rejectMessage(message, true);
}
- else if (_usingDispatcherForCleanup)
+ else if (isInRecovery())
{
_unacknowledgedMessageTags.add(deliveryTag);
}
@@ -3419,11 +3353,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
// Don't reject if we're already closing
if (!_closed.get())
{
- if (_logger.isDebugEnabled())
- {
- _logger.debug("Rejecting message with delivery tag " + message.getDeliveryTag()
- + " for closing consumer " + String.valueOf(consumer == null? null: consumer._consumerTag));
- }
rejectMessage(message, true);
}
}
@@ -3521,48 +3450,4 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
return _closing.get()|| _connection.isClosing();
}
-
- public boolean isDeclareExchanges()
- {
- return DECLARE_EXCHANGES;
- }
-
- JMSException toJMSException(String message, TransportException e)
- {
- int code = getErrorCode(e);
- JMSException jmse = new JMSException(message, Integer.toString(code));
- jmse.setLinkedException(e);
- jmse.initCause(e);
- return jmse;
- }
-
- private int getErrorCode(TransportException e)
- {
- int code = AMQConstant.INTERNAL_ERROR.getCode();
- if (e instanceof SessionException)
- {
- SessionException se = (SessionException) e;
- if(se.getException() != null && se.getException().getErrorCode() != null)
- {
- code = se.getException().getErrorCode().getValue();
- }
- }
- return code;
- }
-
- private boolean isBrowseOnlyDestination(Destination destination)
- {
- return ((destination instanceof AMQDestination) && ((AMQDestination)destination).isBrowseOnly());
- }
-
- private void setRollbackMark()
- {
- // Let the dispatcher know that all the incomming messages
- // should be rolled back(reject/release)
- _rollbackMark.set(_highestDeliveryTag.get());
- if (_logger.isDebugEnabled())
- {
- _logger.debug("Rollback mark is set to " + _rollbackMark.get());
- }
- }
}
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 c6a64ec894..517a7a5ce8 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
@@ -47,8 +47,6 @@ import org.apache.qpid.client.message.AMQMessageDelegateFactory;
import org.apache.qpid.client.message.FieldTableSupport;
import org.apache.qpid.client.message.MessageFactoryRegistry;
import org.apache.qpid.client.message.UnprocessedMessage_0_10;
-import org.apache.qpid.client.messaging.address.Link;
-import org.apache.qpid.client.messaging.address.Link.Reliability;
import org.apache.qpid.client.messaging.address.Node.ExchangeNode;
import org.apache.qpid.client.messaging.address.Node.QueueNode;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
@@ -58,7 +56,6 @@ import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.transport.ExchangeBoundResult;
import org.apache.qpid.transport.ExchangeQueryResult;
-import org.apache.qpid.transport.ExecutionErrorCode;
import org.apache.qpid.transport.ExecutionException;
import org.apache.qpid.transport.MessageAcceptMode;
import org.apache.qpid.transport.MessageAcquireMode;
@@ -72,7 +69,6 @@ import org.apache.qpid.transport.RangeSet;
import org.apache.qpid.transport.Session;
import org.apache.qpid.transport.SessionException;
import org.apache.qpid.transport.SessionListener;
-import org.apache.qpid.transport.TransportException;
import org.apache.qpid.util.Serial;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -160,20 +156,13 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
*/
AMQSession_0_10(org.apache.qpid.transport.Connection qpidConnection, AMQConnection con, int channelId,
boolean transacted, int acknowledgeMode, MessageFactoryRegistry messageFactoryRegistry,
- int defaultPrefetchHighMark, int defaultPrefetchLowMark,String name)
+ int defaultPrefetchHighMark, int defaultPrefetchLowMark)
{
super(con, channelId, transacted, acknowledgeMode, messageFactoryRegistry, defaultPrefetchHighMark,
defaultPrefetchLowMark);
_qpidConnection = qpidConnection;
- if (name == null)
- {
- _qpidSession = _qpidConnection.createSession(1);
- }
- else
- {
- _qpidSession = _qpidConnection.createSession(name,1);
- }
+ _qpidSession = _qpidConnection.createSession(1);
_qpidSession.setSessionListener(this);
if (_transacted)
{
@@ -200,12 +189,11 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
* @param qpidConnection The connection
*/
AMQSession_0_10(org.apache.qpid.transport.Connection qpidConnection, AMQConnection con, int channelId,
- boolean transacted, int acknowledgeMode, int defaultPrefetchHigh, int defaultPrefetchLow,
- String name)
+ boolean transacted, int acknowledgeMode, int defaultPrefetchHigh, int defaultPrefetchLow)
{
this(qpidConnection, con, channelId, transacted, acknowledgeMode, MessageFactoryRegistry.newDefaultRegistry(),
- defaultPrefetchHigh, defaultPrefetchLow,name);
+ defaultPrefetchHigh, defaultPrefetchLow);
}
private void addUnacked(int id)
@@ -270,7 +258,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
long prefetch = getAMQConnection().getMaxPrefetch();
- if (unackedCount >= prefetch/2 || maxAckDelay <= 0 || _acknowledgeMode == javax.jms.Session.AUTO_ACKNOWLEDGE)
+ if (unackedCount >= prefetch/2 || maxAckDelay <= 0)
{
flushAcknowledgments();
}
@@ -294,34 +282,23 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
}
}
- void messageAcknowledge(final RangeSet ranges, final boolean accept)
+ void messageAcknowledge(RangeSet ranges, boolean accept)
{
messageAcknowledge(ranges,accept,false);
}
- void messageAcknowledge(final RangeSet ranges, final boolean accept, final boolean setSyncBit)
+ void messageAcknowledge(RangeSet ranges, boolean accept,boolean setSyncBit)
{
- final Session ssn = getQpidSession();
- flushProcessed(ranges,accept);
- if (accept)
+ Session ssn = getQpidSession();
+ for (Range range : ranges)
{
- ssn.messageAccept(ranges, UNRELIABLE, setSyncBit ? SYNC : NONE);
+ ssn.processed(range);
}
- }
-
- /**
- * Flush any outstanding commands. This causes session complete to be sent.
- * @param ranges the range of command ids.
- * @param batch true if batched.
- */
- void flushProcessed(final RangeSet ranges, final boolean batch)
- {
- final Session ssn = getQpidSession();
- for (final Range range : ranges)
+ ssn.flushProcessed(accept ? BATCH : NONE);
+ if (accept)
{
- ssn.processed(range);
+ ssn.messageAccept(ranges, UNRELIABLE,setSyncBit? SYNC : NONE);
}
- ssn.flushProcessed(batch ? BATCH : NONE);
}
/**
@@ -337,7 +314,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
public void sendQueueBind(final AMQShortString queueName, final AMQShortString routingKey,
final FieldTable arguments, final AMQShortString exchangeName,
final AMQDestination destination, final boolean nowait)
- throws AMQException
+ throws AMQException, FailoverException
{
if (destination.getDestSyntax() == DestSyntax.BURL)
{
@@ -423,6 +400,25 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
}
}
+
+ /**
+ * Commit the receipt and the delivery of all messages exchanged by this session resources.
+ */
+ public void sendCommit() throws AMQException, FailoverException
+ {
+ getQpidSession().setAutoSync(true);
+ try
+ {
+ getQpidSession().txCommit();
+ }
+ finally
+ {
+ getQpidSession().setAutoSync(false);
+ }
+ // We need to sync so that we get notify of an error.
+ sync();
+ }
+
/**
* Create a queue with a given name.
*
@@ -455,14 +451,6 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
public void sendRecover() throws AMQException, FailoverException
{
// release all unacked messages
- RangeSet ranges = gatherUnackedRangeSet();
- getQpidSession().messageRelease(ranges, Option.SET_REDELIVERED);
- // We need to sync so that we get notify of an error.
- sync();
- }
-
- private RangeSet gatherUnackedRangeSet()
- {
RangeSet ranges = new RangeSet();
while (true)
{
@@ -471,11 +459,11 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
{
break;
}
-
- ranges.add(tag.intValue());
+ ranges.add((int) (long) tag);
}
-
- return ranges;
+ getQpidSession().messageRelease(ranges, Option.SET_REDELIVERED);
+ // We need to sync so that we get notify of an error.
+ sync();
}
@@ -549,6 +537,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
}
public boolean isQueueBound(final String exchangeName, final String queueName, final String bindingKey,Map<String,Object> args)
+ throws JMSException
{
boolean res;
ExchangeBoundResult bindingQueryResult =
@@ -611,16 +600,10 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
(Map<? extends String, ? extends Object>) consumer.getDestination().getLink().getSubscription().getArgs());
}
- boolean acceptModeNone = getAcknowledgeMode() == NO_ACKNOWLEDGE;
-
- if (consumer.getDestination().getLink() != null)
- {
- acceptModeNone = consumer.getDestination().getLink().getReliability() == Link.Reliability.UNRELIABLE;
- }
getQpidSession().messageSubscribe
(queueName.toString(), String.valueOf(tag),
- acceptModeNone ? MessageAcceptMode.NONE : MessageAcceptMode.EXPLICIT,
+ getAcknowledgeMode() == NO_ACKNOWLEDGE ? MessageAcceptMode.NONE : MessageAcceptMode.EXPLICIT,
preAcquire ? MessageAcquireMode.PRE_ACQUIRED : MessageAcquireMode.NOT_ACQUIRED, null, 0, arguments,
consumer.isExclusive() ? Option.EXCLUSIVE : Option.NONE);
}
@@ -676,12 +659,13 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
* Create an 0_10 message producer
*/
public BasicMessageProducer_0_10 createMessageProducer(final Destination destination, final boolean mandatory,
- final boolean immediate, final long producerId) throws JMSException
+ final boolean immediate, final boolean waitUntilSent,
+ long producerId) throws JMSException
{
try
{
return new BasicMessageProducer_0_10(_connection, (AMQDestination) destination, _transacted, _channelId, this,
- getProtocolHandler(), producerId, immediate, mandatory);
+ getProtocolHandler(), producerId, immediate, mandatory, waitUntilSent);
}
catch (AMQException e)
{
@@ -691,10 +675,6 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
throw ex;
}
- catch(TransportException e)
- {
- throw toJMSException("Exception while creating message producer:" + e.getMessage(), e);
- }
}
@@ -787,7 +767,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
else
{
QueueNode node = (QueueNode)amqd.getSourceNode();
- getQpidSession().queueDeclare(queueName.toString(), node.getAlternateExchange() ,
+ getQpidSession().queueDeclare(queueName.toString(), "" ,
node.getDeclareArgs(),
node.isAutoDelete() ? Option.AUTO_DELETE : Option.NONE,
node.isDurable() ? Option.DURABLE : Option.NONE,
@@ -924,26 +904,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
setCurrentException(exc);
}
- public void closed(Session ssn)
- {
- try
- {
- super.closed(null);
- if (flushTask != null)
- {
- flushTask.cancel();
- flushTask = null;
- }
- } catch (Exception e)
- {
- _logger.error("Error closing JMS session", e);
- }
- }
-
- public AMQException getLastException()
- {
- return getCurrentException();
- }
+ public void closed(Session ssn) {}
protected AMQShortString declareQueue(final AMQDestination amqd, final AMQProtocolHandler protocolHandler,
final boolean noLocal, final boolean nowait)
@@ -997,26 +958,27 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
}
}
- public void commitImpl() throws AMQException, FailoverException, TransportException
+ @Override public void commit() throws JMSException
{
- if( _txSize > 0 )
+ checkTransacted();
+ try
{
- messageAcknowledge(_txRangeSet, true);
- _txRangeSet.clear();
- _txSize = 0;
+ if( _txSize > 0 )
+ {
+ messageAcknowledge(_txRangeSet, true);
+ _txRangeSet.clear();
+ _txSize = 0;
+ }
+ sendCommit();
}
-
- getQpidSession().setAutoSync(true);
- try
+ catch (AMQException e)
{
- getQpidSession().txCommit();
+ throw new JMSAMQException("Failed to commit: " + e.getMessage(), e);
}
- finally
+ catch (FailoverException e)
{
- getQpidSession().setAutoSync(false);
+ throw new JMSAMQException("Fail-over interrupted commit. Status of the commit is uncertain.", e);
}
- // We need to sync so that we get notify of an error.
- sync();
}
protected final boolean tagLE(long tag1, long tag2)
@@ -1058,9 +1020,11 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
code = ee.getErrorCode().getValue();
}
AMQException amqe = new AMQException(AMQConstant.getConstant(code), se.getMessage(), se.getCause());
+
+ _connection.exceptionReceived(amqe);
+
_currentException = amqe;
}
- _connection.exceptionReceived(_currentException);
}
public AMQMessageDelegateFactory getMessageDelegateFactory()
@@ -1104,37 +1068,22 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
return match;
}
- public boolean isQueueExist(AMQDestination dest,QueueNode node,boolean assertNode) throws AMQException
+ public boolean isQueueExist(AMQDestination dest,QueueNode node,boolean assertNode)
{
boolean match = true;
- try
+ QueueQueryResult result = getQpidSession().queueQuery(dest.getAddressName(), Option.NONE).get();
+ match = dest.getAddressName().equals(result.getQueue());
+
+ if (match && assertNode)
{
- QueueQueryResult result = getQpidSession().queueQuery(dest.getAddressName(), Option.NONE).get();
- match = dest.getAddressName().equals(result.getQueue());
-
- if (match && assertNode)
- {
- match = (result.getDurable() == node.isDurable()) &&
- (result.getAutoDelete() == node.isAutoDelete()) &&
- (result.getExclusive() == node.isExclusive()) &&
- (matchProps(result.getArguments(),node.getDeclareArgs()));
- }
- else if (match)
- {
- // should I use the queried details to update the local data structure.
- }
+ match = (result.getDurable() == node.isDurable()) &&
+ (result.getAutoDelete() == node.isAutoDelete()) &&
+ (result.getExclusive() == node.isExclusive()) &&
+ (matchProps(result.getArguments(),node.getDeclareArgs()));
}
- catch(SessionException e)
+ else if (match)
{
- if (e.getException().getErrorCode() == ExecutionErrorCode.RESOURCE_DELETED)
- {
- match = false;
- }
- else
- {
- throw new AMQException(AMQConstant.getConstant(e.getException().getErrorCode().getValue()),
- "Error querying queue",e);
- }
+ // should I use the queried details to update the local data structure.
}
return match;
@@ -1200,22 +1149,6 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
int type = resolveAddressType(dest);
- if (type == AMQDestination.QUEUE_TYPE &&
- dest.getLink().getReliability() == Reliability.UNSPECIFIED)
- {
- dest.getLink().setReliability(Reliability.AT_LEAST_ONCE);
- }
- else if (type == AMQDestination.TOPIC_TYPE &&
- dest.getLink().getReliability() == Reliability.UNSPECIFIED)
- {
- dest.getLink().setReliability(Reliability.UNRELIABLE);
- }
- else if (type == AMQDestination.TOPIC_TYPE &&
- dest.getLink().getReliability() == Reliability.AT_LEAST_ONCE)
- {
- throw new AMQException("AT-LEAST-ONCE is not yet supported for Topics");
- }
-
switch (type)
{
case AMQDestination.QUEUE_TYPE:
@@ -1229,8 +1162,6 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
{
setLegacyFiledsForQueueType(dest);
send0_10QueueDeclare(dest,null,false,noWait);
- sendQueueBind(dest.getAMQQueueName(), dest.getRoutingKey(),
- null,dest.getExchangeName(),dest, false);
break;
}
}
@@ -1339,8 +1270,6 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
dest.getQueueName(),// should have one by now
dest.getSubject(),
Collections.<String,Object>emptyMap()));
- sendQueueBind(dest.getAMQQueueName(), dest.getRoutingKey(),
- null,dest.getExchangeName(),dest, false);
}
public void setLegacyFiledsForQueueType(AMQDestination dest)
@@ -1378,26 +1307,5 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
sb.append(">");
return sb.toString();
}
-
- protected void acknowledgeImpl()
- {
- RangeSet range = gatherUnackedRangeSet();
-
- if(range.size() > 0 )
- {
- messageAcknowledge(range, true);
- getQpidSession().sync();
- }
- }
-
- @Override
- void resubscribe() throws AMQException
- {
- // Also reset the delivery tag tracker, to insure we dont
- // return the first <total number of msgs received on session>
- // messages sent by the brokers following the first rollback
- // after failover
- _highestDeliveryTag.set(-1);
- super.resubscribe();
- }
+
}
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 369c8a6e9d..f41b1c94fa 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
@@ -38,7 +38,6 @@ import org.apache.qpid.client.message.ReturnMessage;
import org.apache.qpid.client.message.UnprocessedMessage;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.client.state.AMQState;
-import org.apache.qpid.client.state.AMQStateManager;
import org.apache.qpid.client.state.listener.SpecificMethodFrameListener;
import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.framing.AMQFrame;
@@ -76,12 +75,12 @@ import org.apache.qpid.framing.amqp_0_91.MethodRegistry_0_91;
import org.apache.qpid.jms.Session;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.protocol.AMQMethodEvent;
-import org.apache.qpid.transport.TransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, BasicMessageProducer_0_8>
{
+
/** Used for debugging. */
private static final Logger _logger = LoggerFactory.getLogger(AMQSession.class);
@@ -91,7 +90,7 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
* @param con The connection on which to create the session.
* @param channelId The unique identifier for the session.
* @param transacted Indicates whether or not the session is transactional.
- * @param acknowledgeMode The acknowledgement mode for the session.
+ * @param acknowledgeMode The acknoledgement mode for the session.
* @param messageFactoryRegistry The message factory factory for the session.
* @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.
@@ -109,7 +108,7 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
* @param con The connection on which to create the session.
* @param channelId The unique identifier for the session.
* @param transacted Indicates whether or not the session is transactional.
- * @param acknowledgeMode The acknowledgement mode for the session.
+ * @param acknowledgeMode The acknoledgement mode for the session.
* @param defaultPrefetchHigh The maximum number of messages to prefetched before suspending the session.
* @param defaultPrefetchLow The number of prefetched messages at which to resume the session.
*/
@@ -125,20 +124,6 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
return getProtocolHandler().getProtocolVersion();
}
- protected void acknowledgeImpl()
- {
- while (true)
- {
- Long tag = _unacknowledgedMessageTags.poll();
- if (tag == null)
- {
- break;
- }
-
- acknowledgeMessage(tag, false);
- }
- }
-
public void acknowledgeMessage(long deliveryTag, boolean multiple)
{
BasicAckBody body = getMethodRegistry().createBasicAckBody(deliveryTag, multiple);
@@ -168,7 +153,7 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
// we also need to check the state manager for 08/09 as the
// _connection variable may not be updated in time by the error receiving
// thread.
- // We can't close the session if we are already in the process of
+ // We can't close the session if we are alreadying in the process of
// closing/closed the connection.
if (!(getProtocolHandler().getStateManager().getCurrentState().equals(AMQState.CONNECTION_CLOSED)
@@ -184,20 +169,8 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
}
}
- public void commitImpl() throws AMQException, FailoverException, TransportException
+ public void sendCommit() throws AMQException, FailoverException
{
- // Acknowledge all delivered messages
- while (true)
- {
- Long tag = _deliveredMessageTags.poll();
- if (tag == null)
- {
- break;
- }
-
- acknowledgeMessage(tag, false);
- }
-
final AMQProtocolHandler handler = getProtocolHandler();
handler.syncWrite(getProtocolHandler().getMethodRegistry().createTxCommitBody().generateFrame(_channelId), TxCommitOkBody.class);
@@ -427,12 +400,12 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
public BasicMessageProducer_0_8 createMessageProducer(final Destination destination, final boolean mandatory,
- final boolean immediate, long producerId) throws JMSException
+ final boolean immediate, final boolean waitUntilSent, long producerId) throws JMSException
{
try
{
return new BasicMessageProducer_0_8(_connection, (AMQDestination) destination, _transacted, _channelId,
- this, getProtocolHandler(), producerId, immediate, mandatory);
+ this, getProtocolHandler(), producerId, immediate, mandatory, waitUntilSent);
}
catch (AMQException e)
{
@@ -604,18 +577,6 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
}
- @Override
- protected void deleteTemporaryDestination(final TemporaryDestination amqQueue)
- throws JMSException
- {
- // Currently TemporaryDestination is set to be auto-delete which, for 0-8..0-9-1, means that the queue will be deleted
- // by the server when there are no more subscriptions to that queue/topic (rather than when the client disconnects).
- // This is not quite right for JMSCompliance as the queue/topic should remain until the connection closes, or the
- // client explicitly deletes it.
-
- /* intentional no-op */
- }
-
public boolean isQueueBound(String exchangeName, String queueName,
String bindingKey, Map<String, Object> args) throws JMSException
{
@@ -623,34 +584,4 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
queueName == null ? null : new AMQShortString(queueName),
bindingKey == null ? null : new AMQShortString(bindingKey));
}
-
-
- public AMQException getLastException()
- {
- // if the Connection has closed then we should throw any exception that
- // has occurred that we were not waiting for
- AMQStateManager manager = _connection.getProtocolHandler()
- .getStateManager();
-
- Exception e = manager.getLastException();
- if (manager.getCurrentState().equals(AMQState.CONNECTION_CLOSED)
- && e != null)
- {
- if (e instanceof AMQException)
- {
- return (AMQException) e;
- }
- else
- {
- AMQException amqe = new AMQException(AMQConstant
- .getConstant(AMQConstant.INTERNAL_ERROR.getCode()),
- e.getMessage(), e.getCause());
- return amqe;
- }
- }
- else
- {
- return null;
- }
- }
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQTemporaryQueue.java b/java/client/src/main/java/org/apache/qpid/client/AMQTemporaryQueue.java
index 28f838057e..f54cb782c8 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQTemporaryQueue.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQTemporaryQueue.java
@@ -20,13 +20,14 @@
*/
package org.apache.qpid.client;
-import java.util.UUID;
-
import javax.jms.JMSException;
import javax.jms.TemporaryQueue;
import org.apache.qpid.framing.AMQShortString;
+import java.util.Random;
+import java.util.UUID;
+
/** AMQ implementation of a TemporaryQueue. */
final class AMQTemporaryQueue extends AMQQueue implements TemporaryQueue, TemporaryDestination
{
@@ -49,15 +50,11 @@ final class AMQTemporaryQueue extends AMQQueue implements TemporaryQueue, Tempor
{
throw new JMSException("Temporary Queue has consumers so cannot be deleted");
}
+ _deleted = true;
- try
- {
- _session.deleteTemporaryDestination(this);
- }
- finally
- {
- _deleted = true;
- }
+ // Currently TemporaryQueue is set to be auto-delete which means that the queue will be deleted
+ // by the server when there are no more subscriptions to that queue. This is probably not
+ // quite right for JMSCompliance.
}
public AMQSession getSession()
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQTemporaryTopic.java b/java/client/src/main/java/org/apache/qpid/client/AMQTemporaryTopic.java
index db54b320dc..7b5781530b 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQTemporaryTopic.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQTemporaryTopic.java
@@ -53,14 +53,10 @@ class AMQTemporaryTopic extends AMQTopic implements TemporaryTopic, TemporaryDes
throw new JMSException("Temporary Topic has consumers so cannot be deleted");
}
- try
- {
- _session.deleteTemporaryDestination(this);
- }
- finally
- {
- _deleted = true;
- }
+ _deleted = true;
+ // Currently TemporaryQueue is set to be auto-delete which means that the queue will be deleted
+ // by the server when there are no more subscriptions to that queue. This is probably not
+ // quite right for JMSCompliance.
}
public AMQSession getSession()
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java b/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java
index 780dbcafc2..6217cb534a 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java
@@ -22,7 +22,6 @@ package org.apache.qpid.client;
import java.net.URISyntaxException;
-import javax.jms.InvalidDestinationException;
import javax.jms.JMSException;
import javax.jms.Topic;
@@ -96,47 +95,39 @@ public class AMQTopic extends AMQDestination implements Topic
super(exchangeName, exchangeClass, routingKey, isExclusive, isAutoDelete, queueName, isDurable,bindingKeys);
}
- public static AMQTopic createDurableTopic(Topic topic, String subscriptionName, AMQConnection connection)
+ public static AMQTopic createDurableTopic(AMQTopic topic, String subscriptionName, AMQConnection connection)
throws JMSException
{
- if (topic instanceof AMQDestination && topic instanceof javax.jms.Topic)
+ if (topic.getDestSyntax() == DestSyntax.ADDR)
{
- AMQDestination qpidTopic = (AMQDestination)topic;
- if (qpidTopic.getDestSyntax() == DestSyntax.ADDR)
+ try
{
- try
- {
- AMQTopic t = new AMQTopic(qpidTopic.getAddress());
- AMQShortString queueName = getDurableTopicQueueName(subscriptionName, connection);
- // link is never null if dest was created using an address string.
- t.getLink().setName(queueName.asString());
- t.getSourceNode().setAutoDelete(false);
- t.getSourceNode().setDurable(true);
-
- // The legacy fields are also populated just in case.
- t.setQueueName(queueName);
- t.setAutoDelete(false);
- t.setDurable(true);
- return t;
- }
- catch(Exception e)
- {
- JMSException ex = new JMSException("Error creating durable topic");
- ex.initCause(e);
- ex.setLinkedException(e);
- throw ex;
- }
+ AMQTopic t = new AMQTopic(topic.getAddress());
+ AMQShortString queueName = getDurableTopicQueueName(subscriptionName, connection);
+ // link is never null if dest was created using an address string.
+ t.getLink().setName(queueName.asString());
+ t.getSourceNode().setAutoDelete(false);
+ t.getSourceNode().setDurable(true);
+
+ // The legacy fields are also populated just in case.
+ t.setQueueName(queueName);
+ t.setAutoDelete(false);
+ t.setDurable(true);
+ return t;
}
- else
+ catch(Exception e)
{
- return new AMQTopic(qpidTopic.getExchangeName(), qpidTopic.getRoutingKey(), false,
- getDurableTopicQueueName(subscriptionName, connection),
- true);
+ JMSException ex = new JMSException("Error creating durable topic");
+ ex.initCause(e);
+ ex.setLinkedException(e);
+ throw ex;
}
}
else
{
- throw new InvalidDestinationException("The destination object used is not from this provider or of type javax.jms.Topic");
+ return new AMQTopic(topic.getExchangeName(), topic.getRoutingKey(), false,
+ getDurableTopicQueueName(subscriptionName, connection),
+ true);
}
}
@@ -147,17 +138,13 @@ public class AMQTopic extends AMQDestination implements Topic
public String getTopicName() throws JMSException
{
- if (getRoutingKey() != null)
+ if (super.getRoutingKey() == null && super.getSubject() != null)
{
- return getRoutingKey().asString();
- }
- else if (getSubject() != null)
- {
- return getSubject();
+ return super.getSubject();
}
else
{
- return null;
+ return super.getRoutingKey().toString();
}
}
@@ -176,18 +163,12 @@ public class AMQTopic extends AMQDestination implements Topic
public AMQShortString getRoutingKey()
{
- if (super.getRoutingKey() != null)
- {
- return super.getRoutingKey();
- }
- else if (getSubject() != null)
+ if (super.getRoutingKey() == null && super.getSubject() != null)
{
- return new AMQShortString(getSubject());
+ return new AMQShortString(super.getSubject());
}
else
{
- setRoutingKey(new AMQShortString(""));
- setSubject("");
return super.getRoutingKey();
}
}
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 3b807591b0..0a78403268 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
@@ -27,7 +27,6 @@ import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.framing.*;
import org.apache.qpid.jms.MessageConsumer;
import org.apache.qpid.jms.Session;
-import org.apache.qpid.transport.TransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -37,7 +36,10 @@ import javax.jms.MessageListener;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
+import java.util.SortedSet;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.TreeSet;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingQueue;
@@ -115,10 +117,29 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
protected final int _acknowledgeMode;
/**
+ * Number of messages unacknowledged in DUPS_OK_ACKNOWLEDGE mode
+ */
+ private int _outstanding;
+
+ /**
+ * Switch to enable sending of acknowledgements when using DUPS_OK_ACKNOWLEDGE mode. Enabled when _outstannding
+ * number of msgs >= _prefetchHigh and disabled at < _prefetchLow
+ */
+ private boolean _dups_ok_acknowledge_send;
+
+ /**
* List of tags delievered, The last of which which should be acknowledged on commit in transaction mode.
*/
private ConcurrentLinkedQueue<Long> _receivedDeliveryTags = new ConcurrentLinkedQueue<Long>();
+ /** The last tag that was "multiple" acknowledged on this session (if transacted) */
+ private long _lastAcked;
+
+ /** set of tags which have previously been acked; but not part of the multiple ack (transacted mode only) */
+ private final SortedSet<Long> _previouslyAcked = new TreeSet<Long>();
+
+ private final Object _commitLock = new Object();
+
/**
* The thread that was used to call receive(). This is important for being able to interrupt that thread if a
* receive() is in progress.
@@ -268,6 +289,17 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
}
}
+ protected void preApplicationProcessing(AbstractJMSMessage jmsMsg) throws JMSException
+ {
+ if (_session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE)
+ {
+ _session.addUnacknowledgedMessage(jmsMsg.getDeliveryTag());
+ }
+
+ _session.setInRecovery(false);
+ preDeliver(jmsMsg);
+ }
+
/**
* @param immediate if true then return immediately if the connection is failing over
*
@@ -290,14 +322,14 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
}
}
- if (isMessageListenerSet())
+ if (!_receiving.compareAndSet(false, true))
{
- throw new javax.jms.IllegalStateException("A listener has already been set.");
+ throw new javax.jms.IllegalStateException("Another thread is already receiving.");
}
- if (!_receiving.compareAndSet(false, true))
+ if (isMessageListenerSet())
{
- throw new javax.jms.IllegalStateException("Another thread is already receiving.");
+ throw new javax.jms.IllegalStateException("A listener has already been set.");
}
_receivingThread = Thread.currentThread();
@@ -376,7 +408,7 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
final AbstractJMSMessage m = returnMessageOrThrow(o);
if (m != null)
{
- preDeliver(m);
+ preApplicationProcessing(m);
postDeliver(m);
}
return m;
@@ -387,10 +419,6 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
return null;
}
- catch(TransportException e)
- {
- throw _session.toJMSException("Exception while receiving:" + e.getMessage(), e);
- }
finally
{
releaseReceiving();
@@ -449,7 +477,7 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
final AbstractJMSMessage m = returnMessageOrThrow(o);
if (m != null)
{
- preDeliver(m);
+ preApplicationProcessing(m);
postDeliver(m);
}
@@ -461,10 +489,6 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
return null;
}
- catch(TransportException e)
- {
- throw _session.toJMSException("Exception while receiving:" + e.getMessage(), e);
- }
finally
{
releaseReceiving();
@@ -547,7 +571,6 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
if (!_session.isClosed() || _session.isClosing())
{
sendCancel();
- cleanupQueue();
}
}
catch (AMQException e)
@@ -558,10 +581,6 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
{
throw new JMSAMQException("FailoverException interrupted basic cancel.", e);
}
- catch (TransportException e)
- {
- throw _session.toJMSException("Exception while closing consumer: " + e.getMessage(), e);
- }
}
}
else
@@ -589,8 +608,6 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
}
abstract void sendCancel() throws AMQException, FailoverException;
-
- abstract void cleanupQueue() throws AMQException, FailoverException;
/**
* Called when you need to invalidate a consumer. Used for example when failover has occurred and the client has
@@ -701,7 +718,7 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
{
if (isMessageListenerSet())
{
- preDeliver(jmsMessage);
+ preApplicationProcessing(jmsMessage);
getMessageListener().onMessage(jmsMessage);
postDeliver(jmsMessage);
}
@@ -725,42 +742,49 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
}
}
- protected void preDeliver(AbstractJMSMessage msg)
+ void preDeliver(AbstractJMSMessage msg)
{
- _session.setInRecovery(false);
-
switch (_acknowledgeMode)
{
+
case Session.PRE_ACKNOWLEDGE:
_session.acknowledgeMessage(msg.getDeliveryTag(), false);
break;
- case Session.AUTO_ACKNOWLEDGE:
- //fall through
- case Session.DUPS_OK_ACKNOWLEDGE:
- _session.addUnacknowledgedMessage(msg.getDeliveryTag());
- break;
+
case Session.CLIENT_ACKNOWLEDGE:
// we set the session so that when the user calls acknowledge() it can call the method on session
// to send out the appropriate frame
msg.setAMQSession(_session);
- _session.addUnacknowledgedMessage(msg.getDeliveryTag());
- _session.markDirty();
break;
case Session.SESSION_TRANSACTED:
- _session.addDeliveredMessage(msg.getDeliveryTag());
- _session.markDirty();
- break;
- case Session.NO_ACKNOWLEDGE:
- //do nothing.
- //path used for NO-ACK consumers, and browsers (see constructor).
+ if (isNoConsume())
+ {
+ _session.acknowledgeMessage(msg.getDeliveryTag(), false);
+ }
+ else
+ {
+ _session.addDeliveredMessage(msg.getDeliveryTag());
+ _session.markDirty();
+ }
+
break;
}
+
}
- void postDeliver(AbstractJMSMessage msg)
+ void postDeliver(AbstractJMSMessage msg) throws JMSException
{
switch (_acknowledgeMode)
{
+
+ case Session.CLIENT_ACKNOWLEDGE:
+ if (isNoConsume())
+ {
+ _session.acknowledgeMessage(msg.getDeliveryTag(), false);
+ }
+ _session.markDirty();
+ break;
+
case Session.DUPS_OK_ACKNOWLEDGE:
case Session.AUTO_ACKNOWLEDGE:
// we do not auto ack a message if the application code called recover()
@@ -798,6 +822,63 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
return null;
}
+ /**
+ * Acknowledge up to last message delivered (if any). Used when commiting.
+ */
+ void acknowledgeDelivered()
+ {
+ synchronized(_commitLock)
+ {
+ ArrayList<Long> tagsToAck = new ArrayList<Long>();
+
+ while (!_receivedDeliveryTags.isEmpty())
+ {
+ tagsToAck.add(_receivedDeliveryTags.poll());
+ }
+
+ Collections.sort(tagsToAck);
+
+ long prevAcked = _lastAcked;
+ long oldAckPoint = -1;
+
+ while(oldAckPoint != prevAcked)
+ {
+ oldAckPoint = prevAcked;
+
+ Iterator<Long> tagsToAckIterator = tagsToAck.iterator();
+
+ while(tagsToAckIterator.hasNext() && tagsToAckIterator.next() == prevAcked+1)
+ {
+ tagsToAckIterator.remove();
+ prevAcked++;
+ }
+
+ Iterator<Long> previousAckIterator = _previouslyAcked.iterator();
+ while(previousAckIterator.hasNext() && previousAckIterator.next() == prevAcked+1)
+ {
+ previousAckIterator.remove();
+ prevAcked++;
+ }
+
+ }
+ if(prevAcked != _lastAcked)
+ {
+ _session.acknowledgeMessage(prevAcked, true);
+ _lastAcked = prevAcked;
+ }
+
+ Iterator<Long> tagsToAckIterator = tagsToAck.iterator();
+
+ while(tagsToAckIterator.hasNext())
+ {
+ Long tag = tagsToAckIterator.next();
+ _session.acknowledgeMessage(tag, false);
+ _previouslyAcked.add(tag);
+ }
+ }
+ }
+
+
void notifyError(Throwable cause)
{
// synchronized (_closed)
@@ -876,7 +957,7 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
public boolean isNoConsume()
{
- return _noConsume;
+ return _noConsume || _destination.isBrowseOnly() ;
}
public void rollback()
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 548e274571..b5f3501e5a 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
@@ -19,11 +19,10 @@ package org.apache.qpid.client;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.qpid.client.AMQDestination.AddressOption;
import org.apache.qpid.client.AMQDestination.DestSyntax;
-import org.apache.qpid.client.failover.FailoverException;
import org.apache.qpid.client.message.*;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
+import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQInternalException;
@@ -66,13 +65,19 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
private boolean _preAcquire = true;
/**
+ * Indicate whether this consumer is started.
+ */
+ private boolean _isStarted = false;
+
+ /**
* Specify whether this consumer is performing a sync receive
*/
private final AtomicBoolean _syncReceive = new AtomicBoolean(false);
private String _consumerTagString;
private long capacity = 0;
-
+
+ //--- constructor
protected BasicMessageConsumer_0_10(int channelId, AMQConnection connection, AMQDestination destination,
String messageSelector, boolean noLocal, MessageFactoryRegistry messageFactory,
AMQSession session, AMQProtocolHandler protocolHandler,
@@ -98,6 +103,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
_preAcquire = false;
}
}
+ _isStarted = connection.started();
// Destination setting overrides connection defaults
if (destination.getDestSyntax() == DestSyntax.ADDR &&
@@ -150,20 +156,13 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
{
if (isMessageListenerSet() && capacity == 0)
{
- messageFlow();
+ _0_10session.getQpidSession().messageFlow(getConsumerTagString(),
+ MessageCreditUnit.MESSAGE, 1,
+ Option.UNRELIABLE);
}
_logger.debug("messageOk, trying to notify");
super.notifyMessage(jmsMessage);
}
- else
- {
- // if we are synchronously waiting for a message
- // and messages are not pre-fetched we then need to request another one
- if(capacity == 0)
- {
- messageFlow();
- }
- }
}
catch (AMQException e)
{
@@ -172,6 +171,8 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
}
}
+ //----- overwritten methods
+
/**
* This method is invoked when this consumer is stopped.
* It tells the broker to stop delivering messages to this consumer.
@@ -201,18 +202,11 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
super.notifyMessage(messageFrame);
}
- @Override
- protected void preDeliver(AbstractJMSMessage jmsMsg)
+ @Override protected void preApplicationProcessing(AbstractJMSMessage jmsMsg) throws JMSException
{
- super.preDeliver(jmsMsg);
-
- if (_acknowledgeMode == org.apache.qpid.jms.Session.NO_ACKNOWLEDGE)
+ super.preApplicationProcessing(jmsMsg);
+ if (!_session.getTransacted() && _session.getAcknowledgeMode() != org.apache.qpid.jms.Session.CLIENT_ACKNOWLEDGE)
{
- //For 0-10 we need to ensure that all messages are indicated processed in some way to
- //ensure their AMQP command-id is marked completed, and so we must send a completion
- //even for no-ack messages even though there isnt actually an 'acknowledgement' occurring.
- //Add message to the unacked message list to ensure we dont lose record of it before
- //sending a completion of some sort.
_session.addUnacknowledgedMessage(jmsMsg.getDeliveryTag());
}
}
@@ -224,6 +218,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
return _messageFactory.createMessage(msg.getMessageTransfer());
}
+ // private methods
/**
* Check whether a message can be delivered to this consumer.
*
@@ -252,7 +247,6 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
_logger.debug("messageOk " + messageOk);
_logger.debug("_preAcquire " + _preAcquire);
}
-
if (!messageOk)
{
if (_preAcquire)
@@ -269,12 +263,19 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
{
if (_logger.isDebugEnabled())
{
- _logger.debug("filterMessage - not ack'ing message as not acquired");
+ _logger.debug("Message not OK, releasing");
}
- flushUnwantedMessage(message);
+ releaseMessage(message);
+ }
+ // if we are syncrhonously waiting for a message
+ // and messages are not prefetched we then need to request another one
+ if(capacity == 0)
+ {
+ _0_10session.getQpidSession().messageFlow(getConsumerTagString(),
+ MessageCreditUnit.MESSAGE, 1,
+ Option.UNRELIABLE);
}
}
-
// now we need to acquire this message if needed
// this is the case of queue with a message selector set
if (!_preAcquire && messageOk && !isNoConsume())
@@ -286,7 +287,6 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
messageOk = acquireMessage(message);
_logger.debug("filterMessage - message acquire status : " + messageOk);
}
-
return messageOk;
}
@@ -297,38 +297,38 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
* @param message The message to be acknowledged
* @throws AMQException If the message cannot be acquired due to some internal error.
*/
- private void acknowledgeMessage(final AbstractJMSMessage message) throws AMQException
+ private void acknowledgeMessage(AbstractJMSMessage message) throws AMQException
{
- final RangeSet ranges = new RangeSet();
- ranges.add((int) message.getDeliveryTag());
- _0_10session.messageAcknowledge
- (ranges,
- _acknowledgeMode != org.apache.qpid.jms.Session.NO_ACKNOWLEDGE);
-
- final AMQException amqe = _0_10session.getCurrentException();
- if (amqe != null)
+ if (!_preAcquire)
{
- throw amqe;
+ RangeSet ranges = new RangeSet();
+ ranges.add((int) message.getDeliveryTag());
+ _0_10session.messageAcknowledge
+ (ranges,
+ _acknowledgeMode != org.apache.qpid.jms.Session.NO_ACKNOWLEDGE);
+
+ AMQException amqe = _0_10session.getCurrentException();
+ if (amqe != null)
+ {
+ throw amqe;
+ }
}
}
/**
- * Flush an unwanted message. For 0-10 we need to ensure that all messages are indicated
- * processed to ensure their AMQP command-id is marked completed.
+ * Release a message
*
- * @param message The unwanted message to be flushed
- * @throws AMQException If the unwanted message cannot be flushed due to some internal error.
+ * @param message The message to be released
+ * @throws AMQException If the message cannot be released due to some internal error.
*/
- private void flushUnwantedMessage(final AbstractJMSMessage message) throws AMQException
+ private void releaseMessage(AbstractJMSMessage message) throws AMQException
{
- final RangeSet ranges = new RangeSet();
- ranges.add((int) message.getDeliveryTag());
- _0_10session.flushProcessed(ranges,false);
-
- final AMQException amqe = _0_10session.getCurrentException();
- if (amqe != null)
+ if (_preAcquire)
{
- throw amqe;
+ RangeSet ranges = new RangeSet();
+ ranges.add((int) message.getDeliveryTag());
+ _0_10session.getQpidSession().messageRelease(ranges);
+ _0_10session.sync();
}
}
@@ -339,52 +339,44 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
* @return true if the message has been acquired, false otherwise.
* @throws AMQException If the message cannot be acquired due to some internal error.
*/
- private boolean acquireMessage(final AbstractJMSMessage message) throws AMQException
+ private boolean acquireMessage(AbstractJMSMessage message) throws AMQException
{
boolean result = false;
- final RangeSet ranges = new RangeSet();
- ranges.add((int) message.getDeliveryTag());
+ if (!_preAcquire)
+ {
+ RangeSet ranges = new RangeSet();
+ ranges.add((int) message.getDeliveryTag());
- final Acquired acq = _0_10session.getQpidSession().messageAcquire(ranges).get();
+ Acquired acq = _0_10session.getQpidSession().messageAcquire(ranges).get();
- final RangeSet acquired = acq.getTransfers();
- if (acquired != null && acquired.size() > 0)
- {
- result = true;
+ RangeSet acquired = acq.getTransfers();
+ if (acquired != null && acquired.size() > 0)
+ {
+ result = true;
+ }
}
return result;
}
- private void messageFlow()
- {
- _0_10session.getQpidSession().messageFlow(getConsumerTagString(),
- MessageCreditUnit.MESSAGE, 1,
- Option.UNRELIABLE);
- }
public void setMessageListener(final MessageListener messageListener) throws JMSException
{
super.setMessageListener(messageListener);
- try
+ if (messageListener != null && capacity == 0)
{
- if (messageListener != null && capacity == 0)
- {
- messageFlow();
- }
- if (messageListener != null && !_synchronousQueue.isEmpty())
- {
- Iterator messages=_synchronousQueue.iterator();
- while (messages.hasNext())
- {
- AbstractJMSMessage message=(AbstractJMSMessage) messages.next();
- messages.remove();
- _session.rejectMessage(message, true);
- }
- }
+ _0_10session.getQpidSession().messageFlow(getConsumerTagString(),
+ MessageCreditUnit.MESSAGE, 1,
+ Option.UNRELIABLE);
}
- catch(TransportException e)
+ if (messageListener != null && !_synchronousQueue.isEmpty())
{
- throw _session.toJMSException("Exception while setting message listener:"+ e.getMessage(), e);
+ Iterator messages=_synchronousQueue.iterator();
+ while (messages.hasNext())
+ {
+ AbstractJMSMessage message=(AbstractJMSMessage) messages.next();
+ messages.remove();
+ _session.rejectMessage(message, true);
+ }
}
}
@@ -392,7 +384,9 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
{
if (_0_10session.isStarted() && _syncReceive.get())
{
- messageFlow();
+ _0_10session.getQpidSession().messageFlow
+ (getConsumerTagString(), MessageCreditUnit.MESSAGE, 1,
+ Option.UNRELIABLE);
}
}
@@ -413,7 +407,9 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
}
if (_0_10session.isStarted() && capacity == 0 && _synchronousQueue.isEmpty())
{
- messageFlow();
+ _0_10session.getQpidSession().messageFlow(getConsumerTagString(),
+ MessageCreditUnit.MESSAGE, 1,
+ Option.UNRELIABLE);
}
Object o = super.getMessageFromQueue(l);
if (o == null && _0_10session.isStarted())
@@ -444,7 +440,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
return o;
}
- void postDeliver(AbstractJMSMessage msg)
+ void postDeliver(AbstractJMSMessage msg) throws JMSException
{
super.postDeliver(msg);
if (_acknowledgeMode == org.apache.qpid.jms.Session.NO_ACKNOWLEDGE && !_session.isInRecovery())
@@ -453,8 +449,10 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
}
if (_acknowledgeMode == org.apache.qpid.jms.Session.AUTO_ACKNOWLEDGE &&
- !_session.isInRecovery() && _session.getAMQConnection().getSyncAck())
+ !_session.isInRecovery() &&
+ _session.getAMQConnection().getSyncAck())
{
+ ((AMQSession_0_10) getSession()).flushAcknowledgments();
((AMQSession_0_10) getSession()).getQpidSession().sync();
}
}
@@ -511,18 +509,4 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
return _exclusive;
}
}
-
- void cleanupQueue() throws AMQException, FailoverException
- {
- AMQDestination dest = this.getDestination();
- if (dest != null && dest.getDestSyntax() == AMQDestination.DestSyntax.ADDR)
- {
- if (dest.getDelete() == AddressOption.ALWAYS ||
- dest.getDelete() == AddressOption.RECEIVER )
- {
- ((AMQSession_0_10) getSession()).getQpidSession().queueDelete(
- this.getDestination().getQueueName());
- }
- }
- }
}
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 00acd5e866..cdbf57769d 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
@@ -88,8 +88,4 @@ public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<UnprocessedMe
return receive();
}
- void cleanupQueue() throws AMQException, FailoverException
- {
-
- }
}
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 bf4de782a5..8756ac4d05 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
@@ -39,7 +39,6 @@ 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.ContentBody;
-import org.apache.qpid.transport.TransportException;
import org.apache.qpid.util.UUIDGen;
import org.apache.qpid.util.UUIDs;
import org.slf4j.Logger;
@@ -114,6 +113,8 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
private final boolean _mandatory;
+ private final boolean _waitUntilSent;
+
private boolean _disableMessageId;
private UUIDGen _messageIdGenerator = UUIDs.newGenerator();
@@ -125,7 +126,8 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
protected PublishMode publishMode = PublishMode.ASYNC_PUBLISH_ALL;
protected BasicMessageProducer(AMQConnection connection, AMQDestination destination, boolean transacted, int channelId,
- AMQSession session, AMQProtocolHandler protocolHandler, long producerId, boolean immediate, boolean mandatory) throws AMQException
+ AMQSession session, AMQProtocolHandler protocolHandler, long producerId, boolean immediate, boolean mandatory,
+ boolean waitUntilSent) throws AMQException
{
_connection = connection;
_destination = destination;
@@ -141,6 +143,7 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
_immediate = immediate;
_mandatory = mandatory;
+ _waitUntilSent = waitUntilSent;
_userID = connection.getUsername();
setPublishMode();
}
@@ -263,7 +266,7 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
return _destination;
}
- public void close() throws JMSException
+ public void close()
{
_closed.set(true);
_session.deregisterProducer(_producerId);
@@ -360,6 +363,19 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
}
}
+ public void send(Destination destination, Message message, int deliveryMode, int priority, long timeToLive,
+ boolean mandatory, boolean immediate, boolean waitUntilSent) throws JMSException
+ {
+ checkPreConditions();
+ checkDestination(destination);
+ synchronized (_connection.getFailoverMutex())
+ {
+ validateDestination(destination);
+ sendImpl((AMQDestination) destination, message, deliveryMode, priority, timeToLive, mandatory, immediate,
+ waitUntilSent);
+ }
+ }
+
private AbstractJMSMessage convertToNativeMessage(Message message) throws JMSException
{
if (message instanceof AbstractJMSMessage)
@@ -434,6 +450,12 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
}
}
+ protected void sendImpl(AMQDestination destination, Message message, int deliveryMode, int priority, long timeToLive,
+ boolean mandatory, boolean immediate) throws JMSException
+ {
+ sendImpl(destination, message, deliveryMode, priority, timeToLive, mandatory, immediate, _waitUntilSent);
+ }
+
/**
* The caller of this method must hold the failover mutex.
*
@@ -448,13 +470,23 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
* @throws JMSException
*/
protected void sendImpl(AMQDestination destination, Message origMessage, int deliveryMode, int priority, long timeToLive,
- boolean mandatory, boolean immediate) throws JMSException
+ boolean mandatory, boolean immediate, boolean wait) throws JMSException
{
checkTemporaryDestination(destination);
origMessage.setJMSDestination(destination);
AbstractJMSMessage message = convertToNativeMessage(origMessage);
+ if (_transacted)
+ {
+ if (_session.hasFailedOver() && _session.isDirty())
+ {
+ throw new JMSAMQException("Failover has occurred and session is dirty so unable to send.",
+ new AMQSessionDirtyException("Failover has occurred and session is dirty " +
+ "so unable to send."));
+ }
+ }
+
UUID messageId = null;
if (_disableMessageId)
{
@@ -466,14 +498,7 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
message.setJMSMessageID(messageId);
}
- try
- {
- sendMessage(destination, origMessage, message, messageId, deliveryMode, priority, timeToLive, mandatory, immediate);
- }
- catch (TransportException e)
- {
- throw getSession().toJMSException("Exception whilst sending:" + e.getMessage(), e);
- }
+ sendMessage(destination, origMessage, message, messageId, deliveryMode, priority, timeToLive, mandatory, immediate, wait);
if (message != origMessage)
{
@@ -493,7 +518,7 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
abstract void sendMessage(AMQDestination destination, Message origMessage, AbstractJMSMessage message,
UUID messageId, int deliveryMode, int priority, long timeToLive, boolean mandatory,
- boolean immediate) throws JMSException;
+ boolean immediate, boolean wait) throws JMSException;
private void checkTemporaryDestination(AMQDestination destination) throws JMSException
{
@@ -571,13 +596,6 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
public boolean isBound(AMQDestination destination) throws JMSException
{
- try
- {
- return _session.isQueueBound(destination.getExchangeName(), null, destination.getRoutingKey());
- }
- catch (TransportException e)
- {
- throw getSession().toJMSException("Exception whilst checking destination binding:" + e.getMessage(), e);
- }
+ return _session.isQueueBound(destination.getExchangeName(), null, destination.getRoutingKey());
}
}
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 57f64c2f92..53c0457120 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
@@ -19,7 +19,6 @@ package org.apache.qpid.client;
import static org.apache.qpid.transport.Option.NONE;
import static org.apache.qpid.transport.Option.SYNC;
-import static org.apache.qpid.transport.Option.UNRELIABLE;
import java.nio.ByteBuffer;
import java.util.HashMap;
@@ -31,12 +30,9 @@ import javax.jms.JMSException;
import javax.jms.Message;
import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQDestination.AddressOption;
import org.apache.qpid.client.AMQDestination.DestSyntax;
import org.apache.qpid.client.message.AMQMessageDelegate_0_10;
import org.apache.qpid.client.message.AbstractJMSMessage;
-import org.apache.qpid.client.message.QpidMessageProperties;
-import org.apache.qpid.client.messaging.address.Link.Reliability;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.transport.DeliveryProperties;
import org.apache.qpid.transport.Header;
@@ -46,7 +42,6 @@ import org.apache.qpid.transport.MessageDeliveryMode;
import org.apache.qpid.transport.MessageDeliveryPriority;
import org.apache.qpid.transport.MessageProperties;
import org.apache.qpid.transport.Option;
-import org.apache.qpid.transport.TransportException;
import org.apache.qpid.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -61,9 +56,10 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
BasicMessageProducer_0_10(AMQConnection connection, AMQDestination destination, boolean transacted, int channelId,
AMQSession session, AMQProtocolHandler protocolHandler, long producerId,
- boolean immediate, boolean mandatory) throws AMQException
+ boolean immediate, boolean mandatory, boolean waitUntilSent) throws AMQException
{
- super(connection, destination, transacted, channelId, session, protocolHandler, producerId, immediate, mandatory);
+ super(connection, destination, transacted, channelId, session, protocolHandler, producerId, immediate,
+ mandatory, waitUntilSent);
userIDBytes = Strings.toUTF8(_userID);
}
@@ -72,15 +68,12 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
{
if (destination.getDestSyntax() == DestSyntax.BURL)
{
- if (getSession().isDeclareExchanges())
- {
- String name = destination.getExchangeName().toString();
- ((AMQSession_0_10) getSession()).getQpidSession().exchangeDeclare
- (name,
- destination.getExchangeClass().toString(),
- null, null,
- name.startsWith("amq.") ? Option.PASSIVE : Option.NONE);
- }
+ String name = destination.getExchangeName().toString();
+ ((AMQSession_0_10) getSession()).getQpidSession().exchangeDeclare
+ (name,
+ destination.getExchangeClass().toString(),
+ null, null,
+ name.startsWith("amq.") ? Option.PASSIVE : Option.NONE);
}
else
{
@@ -103,7 +96,7 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
*/
void sendMessage(AMQDestination destination, Message origMessage, AbstractJMSMessage message,
UUID messageId, int deliveryMode, int priority, long timeToLive, boolean mandatory,
- boolean immediate) throws JMSException
+ boolean immediate, boolean wait) throws JMSException
{
message.prepareForSending();
@@ -178,7 +171,7 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
if (destination.getDestSyntax() == AMQDestination.DestSyntax.ADDR &&
(destination.getSubject() != null ||
- (messageProps.getApplicationHeaders() != null && messageProps.getApplicationHeaders().get(QpidMessageProperties.QPID_SUBJECT) != null))
+ (messageProps.getApplicationHeaders() != null && messageProps.getApplicationHeaders().get("qpid.subject") != null))
)
{
Map<String,Object> appProps = messageProps.getApplicationHeaders();
@@ -188,21 +181,20 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
messageProps.setApplicationHeaders(appProps);
}
- if (appProps.get(QpidMessageProperties.QPID_SUBJECT) == null)
+ if (appProps.get("qpid.subject") == null)
{
// use default subject in address string
- appProps.put(QpidMessageProperties.QPID_SUBJECT,destination.getSubject());
+ appProps.put("qpid.subject",destination.getSubject());
}
- if (destination.getAddressType() == AMQDestination.TOPIC_TYPE)
+ if (destination.getTargetNode().getType() == AMQDestination.TOPIC_TYPE)
{
deliveryProp.setRoutingKey((String)
- messageProps.getApplicationHeaders().get(QpidMessageProperties.QPID_SUBJECT));
+ messageProps.getApplicationHeaders().get("qpid.subject"));
}
}
-
- ByteBuffer data = message.getData();
- messageProps.setContentLength(data.remaining());
+
+ messageProps.setContentLength(message.getContentLength());
// send the message
try
@@ -218,17 +210,14 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
deliveryMode == DeliveryMode.PERSISTENT)
);
- boolean unreliable = (destination.getDestSyntax() == DestSyntax.ADDR) &&
- (destination.getLink().getReliability() == Reliability.UNRELIABLE);
-
-
- ByteBuffer buffer = data == null ? ByteBuffer.allocate(0) : data.slice();
+ org.apache.mina.common.ByteBuffer data = message.getData();
+ ByteBuffer buffer = data == null ? ByteBuffer.allocate(0) : data.buf().slice();
ssn.messageTransfer(destination.getExchangeName() == null ? "" : destination.getExchangeName().toString(),
MessageAcceptMode.NONE,
MessageAcquireMode.PRE_ACQUIRED,
new Header(deliveryProp, messageProps),
- buffer, sync ? SYNC : NONE, unreliable ? UNRELIABLE : NONE);
+ buffer, sync ? SYNC : NONE);
if (sync)
{
ssn.sync();
@@ -245,34 +234,10 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
}
}
- @Override
+
public boolean isBound(AMQDestination destination) throws JMSException
{
return _session.isQueueBound(destination);
}
-
- @Override
- public void close() throws JMSException
- {
- super.close();
- AMQDestination dest = _destination;
- if (dest != null && dest.getDestSyntax() == AMQDestination.DestSyntax.ADDR)
- {
- if (dest.getDelete() == AddressOption.ALWAYS ||
- dest.getDelete() == AddressOption.SENDER )
- {
- try
- {
- ((AMQSession_0_10) getSession()).getQpidSession().queueDelete(
- _destination.getQueueName());
- }
- catch(TransportException e)
- {
- throw getSession().toJMSException("Exception while closing producer:" + e.getMessage(), e);
- }
- }
- }
- }
-
}
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 34d2ade723..27f7486890 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
@@ -27,13 +27,14 @@ import javax.jms.Message;
import javax.jms.Topic;
import javax.jms.Queue;
-import java.nio.ByteBuffer;
-
+import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.AMQException;
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;
import org.apache.qpid.framing.BasicContentHeaderProperties;
import org.apache.qpid.framing.BasicPublishBody;
import org.apache.qpid.framing.CompositeAMQDataBlock;
@@ -45,9 +46,10 @@ public class BasicMessageProducer_0_8 extends BasicMessageProducer
{
BasicMessageProducer_0_8(AMQConnection connection, AMQDestination destination, boolean transacted, int channelId,
- AMQSession session, AMQProtocolHandler protocolHandler, long producerId, boolean immediate, boolean mandatory) throws AMQException
+ AMQSession session, AMQProtocolHandler protocolHandler, long producerId, boolean immediate, boolean mandatory,
+ boolean waitUntilSent) throws AMQException
{
- super(connection, destination,transacted,channelId,session, protocolHandler, producerId, immediate, mandatory);
+ super(connection, destination,transacted,channelId,session, protocolHandler, producerId, immediate, mandatory,waitUntilSent);
}
void declareDestination(AMQDestination destination)
@@ -72,7 +74,7 @@ public class BasicMessageProducer_0_8 extends BasicMessageProducer
void sendMessage(AMQDestination destination, Message origMessage, AbstractJMSMessage message,
UUID messageId, int deliveryMode,int priority, long timeToLive, boolean mandatory,
- boolean immediate) throws JMSException
+ boolean immediate, boolean wait) throws JMSException
{
BasicPublishBody body = getSession().getMethodRegistry().createBasicPublishBody(_session.getTicket(),
destination.getExchangeName(),
@@ -167,7 +169,7 @@ public class BasicMessageProducer_0_8 extends BasicMessageProducer
throw jmse;
}
- _protocolHandler.writeFrame(compositeFrame);
+ _protocolHandler.writeFrame(compositeFrame, wait);
}
/**
@@ -184,9 +186,7 @@ public class BasicMessageProducer_0_8 extends BasicMessageProducer
if (frames.length == (offset + 1))
{
- byte[] data = new byte[payload.remaining()];
- payload.get(data);
- frames[offset] = ContentBody.createAMQFrame(channelId, new ContentBody(data));
+ frames[offset] = ContentBody.createAMQFrame(channelId, new ContentBody(payload));
}
else
{
@@ -198,10 +198,7 @@ public class BasicMessageProducer_0_8 extends BasicMessageProducer
payload.position((int) framePayloadMax * (i - offset));
int length = (remaining >= framePayloadMax) ? (int) framePayloadMax : (int) remaining;
payload.limit(payload.position() + length);
- byte[] data = new byte[payload.remaining()];
- payload.get(data);
-
- frames[i] = ContentBody.createAMQFrame(channelId, new ContentBody(data));
+ frames[i] = ContentBody.createAMQFrame(channelId, new ContentBody(payload.slice()));
remaining -= length;
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/ChannelToSessionMap.java b/java/client/src/main/java/org/apache/qpid/client/ChannelToSessionMap.java
index 2fdb35de49..2b7e3d44da 100644
--- a/java/client/src/main/java/org/apache/qpid/client/ChannelToSessionMap.java
+++ b/java/client/src/main/java/org/apache/qpid/client/ChannelToSessionMap.java
@@ -1,23 +1,3 @@
-/*
- *
- * 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 java.util.ArrayList;
diff --git a/java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java b/java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java
index e81e754da2..7cc548915c 100644
--- a/java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java
+++ b/java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java
@@ -23,7 +23,6 @@ package org.apache.qpid.client;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
-import java.util.List;
import org.apache.qpid.framing.AMQShortString;
@@ -35,18 +34,6 @@ public enum CustomJMSXProperty
JMSXGroupSeq,
JMSXUserID;
- private static List<String> _names;
-
- static
- {
- CustomJMSXProperty[] properties = values();
- _names = new ArrayList<String>(properties.length);
- for(CustomJMSXProperty property : properties)
- {
- _names.add(property.toString());
- }
-
- }
private final AMQShortString _nameAsShortString;
@@ -60,8 +47,20 @@ public enum CustomJMSXProperty
return _nameAsShortString;
}
- public static Enumeration asEnumeration()
+ private static Enumeration _names;
+
+ public static synchronized Enumeration asEnumeration()
{
- return Collections.enumeration(_names);
+ if(_names == null)
+ {
+ CustomJMSXProperty[] properties = values();
+ ArrayList<String> nameList = new ArrayList<String>(properties.length);
+ for(CustomJMSXProperty property : properties)
+ {
+ nameList.add(property.toString());
+ }
+ _names = Collections.enumeration(nameList);
+ }
+ return _names;
}
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java b/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java
index 5cf767ac35..3bb5707417 100644
--- a/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java
+++ b/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java
@@ -30,11 +30,9 @@ import org.apache.qpid.common.QpidProperties;
public class QpidConnectionMetaData implements ConnectionMetaData
{
- private AMQConnection con;
QpidConnectionMetaData(AMQConnection conn)
{
- this.con = conn;
}
public int getJMSMajorVersion() throws JMSException
@@ -64,12 +62,12 @@ public class QpidConnectionMetaData implements ConnectionMetaData
public int getProviderMajorVersion() throws JMSException
{
- return con.getProtocolVersion().getMajorVersion();
+ return 0;
}
public int getProviderMinorVersion() throws JMSException
{
- return con.getProtocolVersion().getMinorVersion();
+ return 8;
}
public String getProviderVersion() throws JMSException
@@ -80,7 +78,8 @@ public class QpidConnectionMetaData implements ConnectionMetaData
private String getProtocolVersion()
{
- return con.getProtocolVersion().toString();
+ // TODO - Implement based on connection negotiated protocol
+ return "0.8";
}
public String getBrokerVersion()
diff --git a/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java b/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java
index 295c6a4091..27783bcacf 100644
--- a/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java
+++ b/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java
@@ -50,25 +50,25 @@ public class QueueSenderAdapter implements QueueSender
public void send(Message msg) throws JMSException
{
- checkQueuePreConditions(_queue);
+ checkPreConditions();
_delegate.send(msg);
}
public void send(Queue queue, Message msg) throws JMSException
{
- checkQueuePreConditions(queue);
+ checkPreConditions(queue);
_delegate.send(queue, msg);
}
public void publish(Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException
{
- checkQueuePreConditions(_queue);
+ checkPreConditions();
_delegate.send(msg, deliveryMode, priority, timeToLive);
}
public void send(Queue queue, Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException
{
- checkQueuePreConditions(queue);
+ checkPreConditions(queue);
_delegate.send(queue, msg, deliveryMode, priority, timeToLive);
}
@@ -122,19 +122,19 @@ public class QueueSenderAdapter implements QueueSender
public void send(Destination dest, Message msg) throws JMSException
{
- checkQueuePreConditions((Queue) dest);
+ checkPreConditions((Queue) dest);
_delegate.send(dest, msg);
}
public void send(Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException
{
- checkQueuePreConditions(_queue);
+ checkPreConditions();
_delegate.send(msg, deliveryMode, priority, timeToLive);
}
public void send(Destination dest, Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException
{
- checkQueuePreConditions((Queue) dest);
+ checkPreConditions((Queue) dest);
_delegate.send(dest, msg, deliveryMode, priority, timeToLive);
}
@@ -170,6 +170,11 @@ public class QueueSenderAdapter implements QueueSender
private void checkPreConditions() throws JMSException
{
+ checkPreConditions(_queue);
+ }
+
+ private void checkPreConditions(Queue queue) throws JMSException
+ {
if (closed)
{
throw new javax.jms.IllegalStateException("Publisher is closed");
@@ -181,43 +186,39 @@ public class QueueSenderAdapter implements QueueSender
{
throw new javax.jms.IllegalStateException("Invalid Session");
}
- }
- private void checkQueuePreConditions(Queue queue) throws JMSException
- {
- checkPreConditions() ;
-
- if (queue == null)
- {
- throw new UnsupportedOperationException("Queue is null.");
- }
-
- if (!(queue instanceof AMQDestination))
- {
- throw new InvalidDestinationException("Queue: " + queue + " is not a valid Qpid queue");
- }
-
- AMQDestination destination = (AMQDestination) queue;
- if (!destination.isCheckedForQueueBinding() && checkQueueBeforePublish())
- {
- if (_delegate.getSession().isStrictAMQP())
- {
- _delegate._logger.warn("AMQP does not support destination validation before publish, ");
- destination.setCheckedForQueueBinding(true);
- }
- else
- {
- if (_delegate.isBound(destination))
- {
- destination.setCheckedForQueueBinding(true);
- }
- else
- {
- throw new InvalidDestinationException("Queue: " + queue
- + " is not a valid destination (no bindings on server");
- }
- }
- }
+ if (queue == null)
+ {
+ throw new UnsupportedOperationException("Queue is null.");
+ }
+
+ if (!(queue instanceof AMQDestination))
+ {
+ throw new InvalidDestinationException("Queue: " + queue + " is not a valid Qpid queue");
+ }
+
+ AMQDestination destination = (AMQDestination) queue;
+ if (!destination.isCheckedForQueueBinding() && checkQueueBeforePublish())
+ {
+
+ if (_delegate.getSession().isStrictAMQP())
+ {
+ _delegate._logger.warn("AMQP does not support destination validation before publish, ");
+ destination.setCheckedForQueueBinding(true);
+ }
+ else
+ {
+ if (_delegate.isBound(destination))
+ {
+ destination.setCheckedForQueueBinding(true);
+ }
+ else
+ {
+ throw new InvalidDestinationException("Queue: " + queue
+ + " is not a valid destination (no bindings on server");
+ }
+ }
+ }
}
private boolean checkQueueBeforePublish()
diff --git a/java/client/src/main/java/org/apache/qpid/client/SSLConfiguration.java b/java/client/src/main/java/org/apache/qpid/client/SSLConfiguration.java
new file mode 100644
index 0000000000..2280cc9870
--- /dev/null
+++ b/java/client/src/main/java/org/apache/qpid/client/SSLConfiguration.java
@@ -0,0 +1,61 @@
+/*
+ *
+ * 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;
+
+public class SSLConfiguration {
+
+ private String _keystorePath;
+
+ private String _keystorePassword;
+
+ private String _certType = "SunX509";
+
+ public void setKeystorePath(String path)
+ {
+ _keystorePath = path;
+ }
+
+ public String getKeystorePath()
+ {
+ return _keystorePath;
+ }
+
+ public void setKeystorePassword(String password)
+ {
+ _keystorePassword = password;
+ }
+
+ public String getKeystorePassword()
+ {
+ return _keystorePassword;
+ }
+
+ public void setCertType(String type)
+ {
+ _certType = type;
+ }
+
+ public String getCertType()
+ {
+ return _certType;
+ }
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/TemporaryDestination.java b/java/client/src/main/java/org/apache/qpid/client/TemporaryDestination.java
index ca137f5a51..7f8e80c73a 100644
--- a/java/client/src/main/java/org/apache/qpid/client/TemporaryDestination.java
+++ b/java/client/src/main/java/org/apache/qpid/client/TemporaryDestination.java
@@ -24,16 +24,13 @@ package org.apache.qpid.client;
import javax.jms.Destination;
import javax.jms.JMSException;
-import org.apache.qpid.framing.AMQShortString;
-
/**
- * Provides support for convenience interface implemented by both AMQTemporaryTopic and AMQTemporaryQueue
+ * Provides support for covenience interface implemented by both AMQTemporaryTopic and AMQTemporaryQueue
* so that operations related to their "temporary-ness" can be abstracted out.
*/
interface TemporaryDestination extends Destination
{
- public AMQShortString getAMQQueueName();
public void delete() throws JMSException;
public AMQSession getSession();
public boolean isDeleted();
diff --git a/java/client/src/main/java/org/apache/qpid/client/XAConnectionImpl.java b/java/client/src/main/java/org/apache/qpid/client/XAConnectionImpl.java
index 97048f39f4..43025bd724 100644
--- a/java/client/src/main/java/org/apache/qpid/client/XAConnectionImpl.java
+++ b/java/client/src/main/java/org/apache/qpid/client/XAConnectionImpl.java
@@ -31,9 +31,9 @@ public class XAConnectionImpl extends AMQConnection implements XAConnection, XAQ
/**
* Create a XAConnection from a connectionURL
*/
- public XAConnectionImpl(ConnectionURL connectionURL) throws AMQException
+ public XAConnectionImpl(ConnectionURL connectionURL, SSLConfiguration sslConfig) throws AMQException
{
- super(connectionURL);
+ super(connectionURL, sslConfig);
}
//-- interface XAConnection
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 5b94b342eb..8a75082202 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,14 +21,10 @@ import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
+import org.apache.qpid.AMQInvalidArgumentException;
import org.apache.qpid.dtx.XidImpl;
-import org.apache.qpid.transport.DtxXaStatus;
-import org.apache.qpid.transport.ExecutionErrorCode;
-import org.apache.qpid.transport.Future;
-import org.apache.qpid.transport.Option;
-import org.apache.qpid.transport.RecoverResult;
-import org.apache.qpid.transport.SessionException;
-import org.apache.qpid.transport.XaResult;
+import org.apache.qpid.transport.*;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -215,28 +211,9 @@ public class XAResourceImpl implements XAResource
* @throws XAException An error has occurred. Possible exception values are XAER_RMERR, XAER_RMFAIL.
*/
public boolean isSameRM(XAResource xaResource) throws XAException
- {
- if(this == xaResource)
- {
- return true;
- }
- if(!(xaResource instanceof XAResourceImpl))
- {
- return false;
- }
-
- XAResourceImpl other = (XAResourceImpl)xaResource;
-
- String myUUID = ((AMQSession_0_10)_xaSession).getAMQConnection().getBrokerUUID();
- String otherUUID = ((AMQSession_0_10)other._xaSession).getAMQConnection().getBrokerUUID();
-
- if(_logger.isDebugEnabled())
- {
- _logger.debug("Comparing my UUID " + myUUID + " with other UUID " + otherUUID);
- }
-
- return (myUUID != null && otherUUID != null && myUUID.equals(otherUUID));
-
+ {
+ // TODO : get the server identity of xaResource and compare it with our own one
+ return false;
}
/**
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 6b9121811d..354b67cd35 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
@@ -52,7 +52,7 @@ public class XASessionImpl extends AMQSession_0_10 implements XASession, XATopic
{
super(qpidConnection, con, channelId, false, // this is not a transacted session
Session.AUTO_ACKNOWLEDGE, // the ack mode is transacted
- MessageFactoryRegistry.newDefaultRegistry(), defaultPrefetchHigh, defaultPrefetchLow,null);
+ MessageFactoryRegistry.newDefaultRegistry(), defaultPrefetchHigh, defaultPrefetchLow);
createSession();
_xaResource = new XAResourceImpl(this);
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/failover/FailoverRetrySupport.java b/java/client/src/main/java/org/apache/qpid/client/failover/FailoverRetrySupport.java
index 28d19ce817..e9e52cc97c 100644
--- a/java/client/src/main/java/org/apache/qpid/client/failover/FailoverRetrySupport.java
+++ b/java/client/src/main/java/org/apache/qpid/client/failover/FailoverRetrySupport.java
@@ -59,8 +59,8 @@ import org.slf4j.LoggerFactory;
* <tr><td> Automatically retry the continuation accross fail-overs until it succeeds, or raises an exception.
* </table>
*
- * @todo Another continuation. Could use an interface Continuation (as described in other todos)
- * Then have a wrapping continuation (this), which blocks on an arbitrary
+ * @todo Another continuation. Could use an interface Continuation (as described in other todos, for example, see
+ * {@link org.apache.qpid.pool.Job}). Then have a wrapping continuation (this), which blocks on an arbitrary
* Condition or Latch (specified in constructor call), that this blocks on before calling the wrapped Continuation.
* Must work on Java 1.4, so check retrotranslator works on Lock/Condition or latch first. Argument and return type
* to match wrapped condition as type parameters. Rename to AsyncConditionalContinuation or something like that.
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 b9d4d6fa95..2cf19bf391 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
@@ -78,7 +78,7 @@ public class ChannelCloseMethodHandler implements StateAwareMethodListener<Chann
{
throw new AMQNoRouteException("Error: " + reason, null, null);
}
- else if (errorCode == AMQConstant.ARGUMENT_INVALID)
+ else if (errorCode == AMQConstant.INVALID_ARGUMENT)
{
_logger.debug("Broker responded with Invalid Argument.");
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 939bd181a3..c81ad6422f 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
@@ -20,13 +20,6 @@
*/
package org.apache.qpid.client.handler;
-import java.io.UnsupportedEncodingException;
-import java.util.StringTokenizer;
-
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslException;
-
import org.apache.qpid.AMQException;
import org.apache.qpid.client.protocol.AMQProtocolSession;
import org.apache.qpid.client.security.AMQCallbackHandler;
@@ -41,9 +34,18 @@ 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.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslException;
+
+import java.io.UnsupportedEncodingException;
+import java.util.HashSet;
+import java.util.StringTokenizer;
+
public class ConnectionStartMethodHandler implements StateAwareMethodListener<ConnectionStartBody>
{
private static final Logger _log = LoggerFactory.getLogger(ConnectionStartMethodHandler.class);
@@ -195,20 +197,40 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener<Co
private String chooseMechanism(byte[] availableMechanisms) throws UnsupportedEncodingException
{
final String mechanisms = new String(availableMechanisms, "utf8");
- return CallbackHandlerRegistry.getInstance().selectMechanism(mechanisms);
+ StringTokenizer tokenizer = new StringTokenizer(mechanisms, " ");
+ HashSet mechanismSet = new HashSet();
+ while (tokenizer.hasMoreTokens())
+ {
+ mechanismSet.add(tokenizer.nextToken());
+ }
+
+ String preferredMechanisms = CallbackHandlerRegistry.getInstance().getMechanisms();
+ StringTokenizer prefTokenizer = new StringTokenizer(preferredMechanisms, " ");
+ while (prefTokenizer.hasMoreTokens())
+ {
+ String mech = prefTokenizer.nextToken();
+ if (mechanismSet.contains(mech))
+ {
+ return mech;
+ }
+ }
+
+ return null;
}
private AMQCallbackHandler createCallbackHandler(String mechanism, AMQProtocolSession protocolSession)
throws AMQException
{
+ Class mechanismClass = CallbackHandlerRegistry.getInstance().getCallbackHandlerClass(mechanism);
try
{
- AMQCallbackHandler instance = CallbackHandlerRegistry.getInstance().createCallbackHandler(mechanism);
- instance.initialise(protocolSession.getAMQConnection().getConnectionURL());
+ Object instance = mechanismClass.newInstance();
+ AMQCallbackHandler cbh = (AMQCallbackHandler) instance;
+ cbh.initialise(protocolSession);
- return instance;
+ return cbh;
}
- catch (IllegalArgumentException e)
+ catch (Exception e)
{
throw new AMQException(null, "Unable to create callback handler: " + e, e);
}
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
index a9434edf49..c2821591d8 100644
--- 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
@@ -26,7 +26,9 @@ import org.apache.qpid.client.AMQSession;
import javax.jms.Destination;
import javax.jms.JMSException;
+import java.nio.ByteBuffer;
import java.util.Enumeration;
+import java.util.Map;
import java.util.UUID;
public interface AMQMessageDelegate
@@ -128,9 +130,9 @@ public interface AMQMessageDelegate
void removeProperty(final String propertyName) throws JMSException;
- void setAMQSession(final AMQSession<?,?> s);
+ void setAMQSession(final AMQSession s);
- AMQSession<?,?> getAMQSession();
+ AMQSession getAMQSession();
long getDeliveryTag();
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
index e5b95f54f4..8c3f2fd08f 100644
--- 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
@@ -21,6 +21,11 @@
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;
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
index f360b546b2..92e61984d2 100644
--- 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
@@ -22,12 +22,10 @@
package org.apache.qpid.client.message;
import java.lang.ref.SoftReference;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@@ -37,10 +35,12 @@ import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageFormatException;
import javax.jms.MessageNotWriteableException;
+import javax.jms.Session;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQPInvalidClassException;
import org.apache.qpid.client.AMQDestination;
+import org.apache.qpid.client.AMQSession;
import org.apache.qpid.client.AMQSession_0_10;
import org.apache.qpid.client.CustomJMSXProperty;
import org.apache.qpid.framing.AMQShortString;
@@ -53,9 +53,6 @@ import org.apache.qpid.transport.MessageDeliveryMode;
import org.apache.qpid.transport.MessageDeliveryPriority;
import org.apache.qpid.transport.MessageProperties;
import org.apache.qpid.transport.ReplyTo;
-import org.apache.qpid.transport.TransportException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* This extends AbstractAMQMessageDelegate which contains common code between
@@ -64,7 +61,6 @@ import org.slf4j.LoggerFactory;
*/
public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
{
- private static final Logger _logger = LoggerFactory.getLogger(AMQMessageDelegate_0_10.class);
private static final Map<ReplyTo, SoftReference<Destination>> _destinationCache = Collections.synchronizedMap(new HashMap<ReplyTo, SoftReference<Destination>>());
public static final String JMS_TYPE = "x-jms-type";
@@ -74,8 +70,13 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
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;
+
protected AMQMessageDelegate_0_10()
{
@@ -85,29 +86,15 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
protected AMQMessageDelegate_0_10(MessageProperties messageProps, DeliveryProperties deliveryProps, long deliveryTag)
{
- super(deliveryTag);
_messageProps = messageProps;
_deliveryProps = deliveryProps;
+ _deliveryTag = deliveryTag;
_readableProperties = (_messageProps != null);
AMQDestination dest;
- if (AMQDestination.getDefaultDestSyntax() == AMQDestination.DestSyntax.BURL)
- {
- dest = generateDestination(new AMQShortString(_deliveryProps.getExchange()),
+ dest = generateDestination(new AMQShortString(_deliveryProps.getExchange()),
new AMQShortString(_deliveryProps.getRoutingKey()));
- }
- else
- {
- String subject = null;
- if (messageProps != null && messageProps.getApplicationHeaders() != null)
- {
- subject = (String)messageProps.getApplicationHeaders().get(QpidMessageProperties.QPID_SUBJECT);
- }
- dest = (AMQDestination) convertToAddressBasedDestination(_deliveryProps.getExchange(),
- _deliveryProps.getRoutingKey(), subject);
- }
-
setJMSDestination(dest);
}
@@ -198,6 +185,7 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
}
}
+
public long getJMSTimestamp() throws JMSException
{
return _deliveryProps.getTimestamp();
@@ -252,50 +240,13 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
String exchange = replyTo.getExchange();
String routingKey = replyTo.getRoutingKey();
- if (AMQDestination.getDefaultDestSyntax() == AMQDestination.DestSyntax.BURL)
- {
-
- dest = generateDestination(new AMQShortString(exchange), new AMQShortString(routingKey));
- }
- else
- {
- dest = convertToAddressBasedDestination(exchange,routingKey,null);
- }
+ dest = generateDestination(new AMQShortString(exchange), new AMQShortString(routingKey));
_destinationCache.put(replyTo, new SoftReference<Destination>(dest));
}
return dest;
}
}
-
- private Destination convertToAddressBasedDestination(String exchange, String routingKey, String subject)
- {
- String addr;
- if ("".equals(exchange)) // type Queue
- {
- subject = (subject == null) ? "" : "/" + subject;
- addr = routingKey + subject;
- }
- else
- {
- addr = exchange + "/" + routingKey;
- }
-
- try
- {
- return AMQDestination.createDestination("ADDR:" + addr);
- }
- catch(Exception e)
- {
- // An exception is only thrown here if the address syntax is invalid.
- // Logging the exception, but not throwing as this is only important to Qpid developers.
- // An exception here means a bug in the code.
- _logger.error("Exception when constructing an address string from the ReplyTo struct");
-
- // falling back to the old way of doing it to ensure the application continues.
- return generateDestination(new AMQShortString(exchange), new AMQShortString(routingKey));
- }
- }
public void setJMSReplyTo(Destination destination) throws JMSException
{
@@ -317,14 +268,14 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
{
try
{
- int type = ((AMQSession_0_10)getAMQSession()).resolveAddressType(amqd);
+ int type = ((AMQSession_0_10)_session).resolveAddressType(amqd);
if (type == AMQDestination.QUEUE_TYPE)
{
- ((AMQSession_0_10)getAMQSession()).setLegacyFiledsForQueueType(amqd);
+ ((AMQSession_0_10)_session).setLegacyFiledsForQueueType(amqd);
}
else
{
- ((AMQSession_0_10)getAMQSession()).setLegacyFiledsForTopicType(amqd);
+ ((AMQSession_0_10)_session).setLegacyFiledsForTopicType(amqd);
}
}
catch(AMQException ex)
@@ -334,14 +285,6 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
e.setLinkedException(ex);
throw e;
}
- catch (TransportException e)
- {
- JMSException jmse = new JMSException("Exception occured while figuring out the node type:" + e.getMessage());
- jmse.initCause(e);
- jmse.setLinkedException(e);
- throw jmse;
- }
-
}
final ReplyTo replyTo = new ReplyTo(amqd.getExchangeName().toString(), amqd.getRoutingKey().toString());
@@ -392,7 +335,7 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
Destination replyTo = getJMSReplyTo();
if(replyTo != null)
{
- return ((AMQDestination)replyTo).toString();
+ return ((AMQDestination)replyTo).toURL();
}
else
{
@@ -689,16 +632,6 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
{
return new String(_messageProps.getUserId());
}
- else if (QpidMessageProperties.AMQP_0_10_APP_ID.equals(propertyName) &&
- _messageProps.getAppId() != null)
- {
- return new String(_messageProps.getAppId());
- }
- else if (QpidMessageProperties.AMQP_0_10_ROUTING_KEY.equals(propertyName) &&
- _deliveryProps.getRoutingKey() != null)
- {
- return _deliveryProps.getRoutingKey();
- }
else
{
checkPropertyName(propertyName);
@@ -737,19 +670,7 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
public Enumeration getPropertyNames() throws JMSException
{
- List<String> props = new ArrayList<String>();
- Map<String, Object> propertyMap = getApplicationHeaders();
- for (String prop: getApplicationHeaders().keySet())
- {
- Object value = propertyMap.get(prop);
- if (value instanceof Boolean || value instanceof Number
- || value instanceof String)
- {
- props.add(prop);
- }
- }
-
- return java.util.Collections.enumeration(props);
+ return java.util.Collections.enumeration(getApplicationHeaders().keySet());
}
public void setBooleanProperty(String propertyName, boolean b) throws JMSException
@@ -805,14 +726,7 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
{
checkPropertyName(propertyName);
checkWritableProperties();
- if (QpidMessageProperties.AMQP_0_10_APP_ID.equals(propertyName))
- {
- _messageProps.setAppId(value.getBytes());
- }
- else
- {
- setApplicationHeader(propertyName, value);
- }
+ setApplicationHeader(propertyName, value);
}
private static final Set<Class> ALLOWED = new HashSet();
@@ -897,6 +811,64 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
_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 && _session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE)
+ {
+ if (_session.getAMQConnection().isClosed())
+ {
+ throw new javax.jms.IllegalStateException("Connection is already closed");
+ }
+
+ // we set multiple to true here since acknowledgment implies acknowledge of all previous messages
+ // received on the session
+ _session.acknowledgeMessage(_deliveryTag, true);
+ }
+ }
+
+ public void acknowledge() throws JMSException
+ {
+ if (_session != null && _session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE)
+ {
+ _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)
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
index 9ab03412fe..cec4268a7b 100644
--- 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
@@ -30,6 +30,7 @@ import java.util.UUID;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageNotWriteableException;
+import javax.jms.Session;
import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.client.AMQQueue;
@@ -59,12 +60,15 @@ public class AMQMessageDelegate_0_8 extends AbstractAMQMessageDelegate
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;
// The base set of items that needs to be set.
private AMQMessageDelegate_0_8(BasicContentHeaderProperties properties, long deliveryTag)
{
- super(deliveryTag);
_contentHeaderProperties = properties;
+ _deliveryTag = deliveryTag;
_readableProperties = (_contentHeaderProperties != null);
_headerAdapter = new JMSHeaderAdapter(_readableProperties ? ((BasicContentHeaderProperties) _contentHeaderProperties).getHeaders()
: (new BasicContentHeaderProperties()).getHeaders() );
@@ -495,6 +499,7 @@ public class AMQMessageDelegate_0_8 extends AbstractAMQMessageDelegate
{
throw new MessageNotWriteableException("You need to call clearProperties() to make the message writable");
}
+ _contentHeaderProperties.updated();
}
@@ -514,4 +519,58 @@ public class AMQMessageDelegate_0_8 extends AbstractAMQMessageDelegate
_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 && _session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE)
+ {
+ 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.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE)
+ {
+ _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/AMQPEncodedMapMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessage.java
index be71c8c657..6e22292ee0 100644
--- a/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessage.java
+++ b/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessage.java
@@ -23,12 +23,11 @@ package org.apache.qpid.client.message;
import java.util.List;
import java.util.Map;
-import java.util.UUID;
-import java.nio.ByteBuffer;
import javax.jms.JMSException;
import javax.jms.MessageFormatException;
+import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.AMQException;
import org.apache.qpid.transport.codec.BBDecoder;
import org.apache.qpid.transport.codec.BBEncoder;
@@ -66,7 +65,7 @@ public class AMQPEncodedMapMessage extends JMSMapMessage
if ((value instanceof Boolean) || (value instanceof Byte) || (value instanceof Short) || (value instanceof Integer)
|| (value instanceof Long) || (value instanceof Character) || (value instanceof Float)
|| (value instanceof Double) || (value instanceof String) || (value instanceof byte[])
- || (value instanceof List) || (value instanceof Map) || (value instanceof UUID) || (value == null))
+ || (value instanceof List) || (value instanceof Map) || (value == null))
{
_map.put(propName, value);
}
@@ -81,19 +80,18 @@ public class AMQPEncodedMapMessage extends JMSMapMessage
@ Override
public ByteBuffer getData()
{
- BBEncoder encoder = new BBEncoder(1024);
- encoder.writeMap(_map);
- return encoder.segment();
+ writeMapToData();
+ return _data;
}
@ Override
- protected void populateMapFromData(ByteBuffer data) throws JMSException
+ protected void populateMapFromData() throws JMSException
{
- if (data != null)
+ if (_data != null)
{
- data.rewind();
+ _data.rewind();
BBDecoder decoder = new BBDecoder();
- decoder.init(data);
+ decoder.init(_data.buf());
_map = decoder.readMap();
}
else
@@ -102,8 +100,16 @@ public class AMQPEncodedMapMessage extends JMSMapMessage
}
}
+ @ Override
+ protected void writeMapToData()
+ {
+ BBEncoder encoder = new BBEncoder(1024);
+ encoder.writeMap(_map);
+ _data = ByteBuffer.wrap(encoder.segment());
+ }
+
// for testing
- public Map<String,Object> getMap()
+ Map<String,Object> getMap()
{
return _map;
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessageFactory.java b/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessageFactory.java
index 2c38f153cb..4978d1ce85 100644
--- a/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessageFactory.java
+++ b/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessageFactory.java
@@ -1,6 +1,6 @@
package org.apache.qpid.client.message;
/*
- *
+ *
* 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
@@ -8,23 +8,22 @@ package org.apache.qpid.client.message;
* 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.
- *
+ *
*/
import javax.jms.JMSException;
-import java.nio.ByteBuffer;
-
+import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.AMQException;
public class AMQPEncodedMapMessageFactory extends AbstractJMSMessageFactory
@@ -37,7 +36,7 @@ public class AMQPEncodedMapMessageFactory extends AbstractJMSMessageFactory
return new AMQPEncodedMapMessage(delegate,data);
}
-
+ @Override
public AbstractJMSMessage createMessage(
AMQMessageDelegateFactory delegateFactory) throws JMSException
{
diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AbstractAMQMessageDelegate.java b/java/client/src/main/java/org/apache/qpid/client/message/AbstractAMQMessageDelegate.java
index 1b6c0c751d..89fbc9722c 100644
--- a/java/client/src/main/java/org/apache/qpid/client/message/AbstractAMQMessageDelegate.java
+++ b/java/client/src/main/java/org/apache/qpid/client/message/AbstractAMQMessageDelegate.java
@@ -23,13 +23,9 @@ package org.apache.qpid.client.message;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import javax.jms.JMSException;
-import javax.jms.Session;
-
import org.apache.qpid.client.AMQAnyDestination;
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.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
@@ -82,25 +78,7 @@ public abstract class AbstractAMQMessageDelegate implements AMQMessageDelegate
new ExchangeInfo(ExchangeDefaults.HEADERS_EXCHANGE_NAME.toString(),
ExchangeDefaults.HEADERS_EXCHANGE_CLASS.toString(),
AMQDestination.QUEUE_TYPE));
- }
-
- /** If the acknowledge mode is CLIENT_ACKNOWLEDGE the session is required */
- private AMQSession<?,?> _session;
- private final long _deliveryTag;
-
- protected AbstractAMQMessageDelegate(long deliveryTag)
- {
- _deliveryTag = deliveryTag;
- }
-
- /**
- * Get the AMQ message number assigned to this message
- *
- * @return the message number
- */
- public long getDeliveryTag()
- {
- return _deliveryTag;
+
}
/**
@@ -179,47 +157,6 @@ public abstract class AbstractAMQMessageDelegate implements AMQMessageDelegate
{
return _exchangeMap.containsKey(exchange);
}
-
- 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 && _session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE)
- {
- 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(getDeliveryTag(), true);
- }
- }
-
- public void acknowledge() throws JMSException
- {
- if (_session != null && _session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE)
- {
- _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;
- }
}
class ExchangeInfo
@@ -265,5 +202,5 @@ class ExchangeInfo
public void setDestType(int destType)
{
this.destType = destType;
- }
+ }
}
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
new file mode 100644
index 0000000000..3846ee043d
--- /dev/null
+++ b/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java
@@ -0,0 +1,124 @@
+/*
+ *
+ * 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.IOException;
+import java.nio.charset.Charset;
+
+import javax.jms.JMSException;
+import javax.jms.MessageEOFException;
+
+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.transport.util.Functions;
+
+/**
+ * @author Apache Software Foundation
+ */
+public abstract class AbstractBytesMessage extends AbstractJMSMessage
+{
+
+ /**
+ * The default initial size of the buffer. The buffer expands automatically.
+ */
+ private static final int DEFAULT_BUFFER_INITIAL_SIZE = 1024;
+
+ AbstractBytesMessage(AMQMessageDelegateFactory delegateFactory)
+ {
+ 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
+ */
+ AbstractBytesMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data)
+ {
+ super(delegateFactory, data); // this instanties a content header
+ setContentType(getMimeType());
+
+ if (_data == null)
+ {
+ allocateInitialBuffer();
+ }
+ }
+
+ protected void allocateInitialBuffer()
+ {
+ _data = ByteBuffer.allocate(DEFAULT_BUFFER_INITIAL_SIZE);
+ _data.setAutoExpand(true);
+ }
+
+ AbstractBytesMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException
+ {
+ super(delegate, data);
+ setContentType(getMimeType());
+ }
+
+
+ public void clearBodyImpl() throws JMSException
+ {
+ allocateInitialBuffer();
+ }
+
+ public String toBodyString() throws JMSException
+ {
+ try
+ {
+ if (_data != null)
+ {
+ return Functions.str(_data.buf(), 100,0);
+ }
+ else
+ {
+ return "";
+ }
+
+ }
+ catch (Exception e)
+ {
+ JMSException jmse = new JMSException(e.toString());
+ jmse.setLinkedException(e);
+ jmse.initCause(e);
+ throw jmse;
+ }
+
+ }
+
+ /**
+ * Check that there is at least a certain number of bytes available to read
+ *
+ * @param len the number of bytes
+ * @throws javax.jms.MessageEOFException if there are less than len bytes available to read
+ */
+ protected void checkAvailable(int len) throws MessageEOFException
+ {
+ if (_data.remaining() < len)
+ {
+ throw new MessageEOFException("Unable to read " + len + " bytes");
+ }
+ }
+}
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 ddeb62fbf6..85818dcd2b 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
@@ -21,96 +21,784 @@
package org.apache.qpid.client.message;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
-import java.nio.ByteBuffer;
import javax.jms.JMSException;
+import javax.jms.MessageEOFException;
+import javax.jms.MessageFormatException;
import javax.jms.MessageNotReadableException;
import javax.jms.MessageNotWriteableException;
+import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.AMQException;
-import org.apache.qpid.transport.util.Functions;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
/**
* @author Apache Software Foundation
*/
-public abstract class AbstractBytesTypedMessage extends AbstractJMSMessage
+public abstract class AbstractBytesTypedMessage extends AbstractBytesMessage
{
- protected boolean _readableMessage = false;
- AbstractBytesTypedMessage(AMQMessageDelegateFactory delegateFactory, boolean fromReceivedMessage)
+ protected static final byte BOOLEAN_TYPE = (byte) 1;
+
+ protected static final byte BYTE_TYPE = (byte) 2;
+
+ protected static final byte BYTEARRAY_TYPE = (byte) 3;
+
+ protected static final byte SHORT_TYPE = (byte) 4;
+
+ protected static final byte CHAR_TYPE = (byte) 5;
+
+ protected static final byte INT_TYPE = (byte) 6;
+
+ protected static final byte LONG_TYPE = (byte) 7;
+
+ protected static final byte FLOAT_TYPE = (byte) 8;
+
+ protected static final byte DOUBLE_TYPE = (byte) 9;
+
+ protected static final byte STRING_TYPE = (byte) 10;
+
+ protected static final byte NULL_STRING_TYPE = (byte) 11;
+
+ /**
+ * This is set when reading a byte array. The readBytes(byte[]) method supports multiple calls to read
+ * a byte array in multiple chunks, hence this is used to track how much is left to be read
+ */
+ private int _byteArrayRemaining = -1;
+
+ AbstractBytesTypedMessage(AMQMessageDelegateFactory delegateFactory)
+ {
+
+ 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
+ */
+ AbstractBytesTypedMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data)
{
- super(delegateFactory, fromReceivedMessage); // this instanties a content header
- _readableMessage = fromReceivedMessage;
+ super(delegateFactory, data); // this instanties a content header
}
- AbstractBytesTypedMessage(AMQMessageDelegate delegate, boolean fromReceivedMessage) throws AMQException
+ AbstractBytesTypedMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException
{
- super(delegate, fromReceivedMessage);
- _readableMessage = fromReceivedMessage;
+ super(delegate, data);
+ }
+
+ protected byte readWireType() throws MessageFormatException, MessageEOFException,
+ MessageNotReadableException
+ {
+ checkReadable();
+ checkAvailable(1);
+ return _data.get();
}
- protected void checkReadable() throws MessageNotReadableException
+ protected void writeTypeDiscriminator(byte type) throws MessageNotWriteableException
{
- if (!_readableMessage)
+ checkWritable();
+ _data.put(type);
+ _changedData = true;
+ }
+
+ protected boolean readBoolean() throws JMSException
+ {
+ int position = _data.position();
+ byte wireType = readWireType();
+ boolean result;
+ try
{
- throw new MessageNotReadableException("You need to call reset() to make the message readable");
+ switch (wireType)
+ {
+ case BOOLEAN_TYPE:
+ checkAvailable(1);
+ result = readBooleanImpl();
+ break;
+ case STRING_TYPE:
+ checkAvailable(1);
+ result = Boolean.parseBoolean(readStringImpl());
+ break;
+ default:
+ _data.position(position);
+ throw new MessageFormatException("Unable to convert " + wireType + " to a boolean");
+ }
+ return result;
+ }
+ catch (RuntimeException e)
+ {
+ _data.position(position);
+ throw e;
}
}
- @Override
- protected void checkWritable() throws MessageNotWriteableException
+ private boolean readBooleanImpl()
{
- super.checkWritable();
- if(_readableMessage)
+ return _data.get() != 0;
+ }
+
+ protected byte readByte() throws JMSException
+ {
+ int position = _data.position();
+ byte wireType = readWireType();
+ byte result;
+ try
{
- throw new MessageNotWriteableException("You need to call clearBody() to make the message writable");
+ switch (wireType)
+ {
+ case BYTE_TYPE:
+ checkAvailable(1);
+ result = readByteImpl();
+ break;
+ case STRING_TYPE:
+ checkAvailable(1);
+ result = Byte.parseByte(readStringImpl());
+ break;
+ default:
+ _data.position(position);
+ throw new MessageFormatException("Unable to convert " + wireType + " to a byte");
+ }
}
+ catch (RuntimeException e)
+ {
+ _data.position(position);
+ throw e;
+ }
+ return result;
}
- public void clearBody() throws JMSException
+ private byte readByteImpl()
{
- super.clearBody();
- _readableMessage = false;
+ return _data.get();
}
+ protected short readShort() throws JMSException
+ {
+ int position = _data.position();
+ byte wireType = readWireType();
+ short result;
+ try
+ {
+ switch (wireType)
+ {
+ case SHORT_TYPE:
+ checkAvailable(2);
+ result = readShortImpl();
+ break;
+ case STRING_TYPE:
+ checkAvailable(1);
+ result = Short.parseShort(readStringImpl());
+ break;
+ case BYTE_TYPE:
+ checkAvailable(1);
+ result = readByteImpl();
+ break;
+ default:
+ _data.position(position);
+ throw new MessageFormatException("Unable to convert " + wireType + " to a short");
+ }
+ }
+ catch (RuntimeException e)
+ {
+ _data.position(position);
+ throw e;
+ }
+ return result;
+ }
- public String toBodyString() throws JMSException
+ private short readShortImpl()
{
+ return _data.getShort();
+ }
+
+ /**
+ * Note that this method reads a unicode character as two bytes from the stream
+ *
+ * @return the character read from the stream
+ * @throws javax.jms.JMSException
+ */
+ protected char readChar() throws JMSException
+ {
+ int position = _data.position();
+ byte wireType = readWireType();
try
{
- ByteBuffer data = getData();
- if (data != null)
- {
- return Functions.str(data, 100, 0);
- }
- else
- {
- return "";
+ if(wireType == NULL_STRING_TYPE){
+ throw new NullPointerException();
}
+ if (wireType != CHAR_TYPE)
+ {
+ _data.position(position);
+ throw new MessageFormatException("Unable to convert " + wireType + " to a char");
+ }
+ else
+ {
+ checkAvailable(2);
+ return readCharImpl();
+ }
+ }
+ catch (RuntimeException e)
+ {
+ _data.position(position);
+ throw e;
+ }
+ }
+
+ private char readCharImpl()
+ {
+ return _data.getChar();
+ }
+
+ protected int readInt() throws JMSException
+ {
+ int position = _data.position();
+ byte wireType = readWireType();
+ int result;
+ try
+ {
+ switch (wireType)
+ {
+ case INT_TYPE:
+ checkAvailable(4);
+ result = readIntImpl();
+ break;
+ case SHORT_TYPE:
+ checkAvailable(2);
+ result = readShortImpl();
+ break;
+ case STRING_TYPE:
+ checkAvailable(1);
+ result = Integer.parseInt(readStringImpl());
+ break;
+ case BYTE_TYPE:
+ checkAvailable(1);
+ result = readByteImpl();
+ break;
+ default:
+ _data.position(position);
+ throw new MessageFormatException("Unable to convert " + wireType + " to an int");
+ }
+ return result;
+ }
+ catch (RuntimeException e)
+ {
+ _data.position(position);
+ throw e;
+ }
+ }
+
+ protected int readIntImpl()
+ {
+ return _data.getInt();
+ }
+
+ protected long readLong() throws JMSException
+ {
+ int position = _data.position();
+ byte wireType = readWireType();
+ long result;
+ try
+ {
+ switch (wireType)
+ {
+ case LONG_TYPE:
+ checkAvailable(8);
+ result = readLongImpl();
+ break;
+ case INT_TYPE:
+ checkAvailable(4);
+ result = readIntImpl();
+ break;
+ case SHORT_TYPE:
+ checkAvailable(2);
+ result = readShortImpl();
+ break;
+ case STRING_TYPE:
+ checkAvailable(1);
+ result = Long.parseLong(readStringImpl());
+ break;
+ case BYTE_TYPE:
+ checkAvailable(1);
+ result = readByteImpl();
+ break;
+ default:
+ _data.position(position);
+ throw new MessageFormatException("Unable to convert " + wireType + " to a long");
+ }
+ return result;
+ }
+ catch (RuntimeException e)
+ {
+ _data.position(position);
+ throw e;
+ }
+ }
+
+ private long readLongImpl()
+ {
+ return _data.getLong();
+ }
+
+ protected float readFloat() throws JMSException
+ {
+ int position = _data.position();
+ byte wireType = readWireType();
+ float result;
+ try
+ {
+ switch (wireType)
+ {
+ case FLOAT_TYPE:
+ checkAvailable(4);
+ result = readFloatImpl();
+ break;
+ case STRING_TYPE:
+ checkAvailable(1);
+ result = Float.parseFloat(readStringImpl());
+ break;
+ default:
+ _data.position(position);
+ throw new MessageFormatException("Unable to convert " + wireType + " to a float");
+ }
+ return result;
+ }
+ catch (RuntimeException e)
+ {
+ _data.position(position);
+ throw e;
+ }
+ }
+
+ private float readFloatImpl()
+ {
+ return _data.getFloat();
+ }
+
+ protected double readDouble() throws JMSException
+ {
+ int position = _data.position();
+ byte wireType = readWireType();
+ double result;
+ try
+ {
+ switch (wireType)
+ {
+ case DOUBLE_TYPE:
+ checkAvailable(8);
+ result = readDoubleImpl();
+ break;
+ case FLOAT_TYPE:
+ checkAvailable(4);
+ result = readFloatImpl();
+ break;
+ case STRING_TYPE:
+ checkAvailable(1);
+ result = Double.parseDouble(readStringImpl());
+ break;
+ default:
+ _data.position(position);
+ throw new MessageFormatException("Unable to convert " + wireType + " to a double");
+ }
+ return result;
+ }
+ catch (RuntimeException e)
+ {
+ _data.position(position);
+ throw e;
+ }
+ }
+
+ private double readDoubleImpl()
+ {
+ return _data.getDouble();
+ }
+
+ protected String readString() throws JMSException
+ {
+ int position = _data.position();
+ byte wireType = readWireType();
+ String result;
+ try
+ {
+ switch (wireType)
+ {
+ case STRING_TYPE:
+ checkAvailable(1);
+ result = readStringImpl();
+ break;
+ case NULL_STRING_TYPE:
+ result = null;
+ throw new NullPointerException("data is null");
+ case BOOLEAN_TYPE:
+ checkAvailable(1);
+ result = String.valueOf(readBooleanImpl());
+ break;
+ case LONG_TYPE:
+ checkAvailable(8);
+ result = String.valueOf(readLongImpl());
+ break;
+ case INT_TYPE:
+ checkAvailable(4);
+ result = String.valueOf(readIntImpl());
+ break;
+ case SHORT_TYPE:
+ checkAvailable(2);
+ result = String.valueOf(readShortImpl());
+ break;
+ case BYTE_TYPE:
+ checkAvailable(1);
+ result = String.valueOf(readByteImpl());
+ break;
+ case FLOAT_TYPE:
+ checkAvailable(4);
+ result = String.valueOf(readFloatImpl());
+ break;
+ case DOUBLE_TYPE:
+ checkAvailable(8);
+ result = String.valueOf(readDoubleImpl());
+ break;
+ case CHAR_TYPE:
+ checkAvailable(2);
+ result = String.valueOf(readCharImpl());
+ break;
+ default:
+ _data.position(position);
+ throw new MessageFormatException("Unable to convert " + wireType + " to a String");
+ }
+ return result;
+ }
+ catch (RuntimeException e)
+ {
+ _data.position(position);
+ throw e;
+ }
+ }
+
+ protected String readStringImpl() throws JMSException
+ {
+ try
+ {
+ return _data.getString(Charset.forName("UTF-8").newDecoder());
}
- catch (Exception e)
+ catch (CharacterCodingException e)
{
- JMSException jmse = new JMSException(e.toString());
+ JMSException jmse = new JMSException("Error decoding byte stream as a UTF8 string: " + e);
jmse.setLinkedException(e);
jmse.initCause(e);
throw jmse;
}
+ }
+
+ protected int readBytes(byte[] bytes) throws JMSException
+ {
+ if (bytes == null)
+ {
+ throw new IllegalArgumentException("byte array must not be null");
+ }
+ checkReadable();
+ // first call
+ if (_byteArrayRemaining == -1)
+ {
+ // type discriminator checked separately so you get a MessageFormatException rather than
+ // an EOF even in the case where both would be applicable
+ checkAvailable(1);
+ byte wireType = readWireType();
+ if (wireType != BYTEARRAY_TYPE)
+ {
+ throw new MessageFormatException("Unable to convert " + wireType + " to a byte array");
+ }
+ checkAvailable(4);
+ int size = _data.getInt();
+ // length of -1 indicates null
+ if (size == -1)
+ {
+ return -1;
+ }
+ else
+ {
+ if (size > _data.remaining())
+ {
+ throw new MessageEOFException("Byte array has stated length " + size + " but message only contains " +
+ _data.remaining() + " bytes");
+ }
+ else
+ {
+ _byteArrayRemaining = size;
+ }
+ }
+ }
+ else if (_byteArrayRemaining == 0)
+ {
+ _byteArrayRemaining = -1;
+ return -1;
+ }
+
+ int returnedSize = readBytesImpl(bytes);
+ if (returnedSize < bytes.length)
+ {
+ _byteArrayRemaining = -1;
+ }
+ return returnedSize;
+ }
+
+ private int readBytesImpl(byte[] bytes)
+ {
+ int count = (_byteArrayRemaining >= bytes.length ? bytes.length : _byteArrayRemaining);
+ _byteArrayRemaining -= count;
+
+ if (count == 0)
+ {
+ return 0;
+ }
+ else
+ {
+ _data.get(bytes, 0, count);
+ return count;
+ }
+ }
+
+ protected Object readObject() throws JMSException
+ {
+ int position = _data.position();
+ byte wireType = readWireType();
+ Object result = null;
+ try
+ {
+ switch (wireType)
+ {
+ case BOOLEAN_TYPE:
+ checkAvailable(1);
+ result = readBooleanImpl();
+ break;
+ case BYTE_TYPE:
+ checkAvailable(1);
+ result = readByteImpl();
+ break;
+ case BYTEARRAY_TYPE:
+ checkAvailable(4);
+ int size = _data.getInt();
+ if (size == -1)
+ {
+ result = null;
+ }
+ else
+ {
+ _byteArrayRemaining = size;
+ byte[] bytesResult = new byte[size];
+ readBytesImpl(bytesResult);
+ result = bytesResult;
+ }
+ break;
+ case SHORT_TYPE:
+ checkAvailable(2);
+ result = readShortImpl();
+ break;
+ case CHAR_TYPE:
+ checkAvailable(2);
+ result = readCharImpl();
+ break;
+ case INT_TYPE:
+ checkAvailable(4);
+ result = readIntImpl();
+ break;
+ case LONG_TYPE:
+ checkAvailable(8);
+ result = readLongImpl();
+ break;
+ case FLOAT_TYPE:
+ checkAvailable(4);
+ result = readFloatImpl();
+ break;
+ case DOUBLE_TYPE:
+ checkAvailable(8);
+ result = readDoubleImpl();
+ break;
+ case NULL_STRING_TYPE:
+ result = null;
+ break;
+ case STRING_TYPE:
+ checkAvailable(1);
+ result = readStringImpl();
+ break;
+ }
+ return result;
+ }
+ catch (RuntimeException e)
+ {
+ _data.position(position);
+ throw e;
+ }
+ }
+
+ protected void writeBoolean(boolean b) throws JMSException
+ {
+ writeTypeDiscriminator(BOOLEAN_TYPE);
+ _data.put(b ? (byte) 1 : (byte) 0);
+ }
+
+ protected void writeByte(byte b) throws JMSException
+ {
+ writeTypeDiscriminator(BYTE_TYPE);
+ _data.put(b);
+ }
+
+ protected void writeShort(short i) throws JMSException
+ {
+ writeTypeDiscriminator(SHORT_TYPE);
+ _data.putShort(i);
+ }
+
+ protected void writeChar(char c) throws JMSException
+ {
+ writeTypeDiscriminator(CHAR_TYPE);
+ _data.putChar(c);
+ }
+
+ protected void writeInt(int i) throws JMSException
+ {
+ writeTypeDiscriminator(INT_TYPE);
+ writeIntImpl(i);
+ }
+
+ protected void writeIntImpl(int i)
+ {
+ _data.putInt(i);
+ }
+
+ protected void writeLong(long l) throws JMSException
+ {
+ writeTypeDiscriminator(LONG_TYPE);
+ _data.putLong(l);
+ }
+ protected void writeFloat(float v) throws JMSException
+ {
+ writeTypeDiscriminator(FLOAT_TYPE);
+ _data.putFloat(v);
}
+ protected void writeDouble(double v) throws JMSException
+ {
+ writeTypeDiscriminator(DOUBLE_TYPE);
+ _data.putDouble(v);
+ }
- abstract public void reset();
+ protected void writeString(String string) throws JMSException
+ {
+ if (string == null)
+ {
+ writeTypeDiscriminator(NULL_STRING_TYPE);
+ }
+ else
+ {
+ writeTypeDiscriminator(STRING_TYPE);
+ try
+ {
+ writeStringImpl(string);
+ }
+ catch (CharacterCodingException e)
+ {
+ JMSException jmse = new JMSException("Unable to encode string: " + e);
+ jmse.setLinkedException(e);
+ jmse.initCause(e);
+ throw jmse;
+ }
+ }
+ }
+
+ protected void writeStringImpl(String string)
+ throws CharacterCodingException
+ {
+ _data.putString(string, Charset.forName("UTF-8").newEncoder());
+ // we must write the null terminator ourselves
+ _data.put((byte) 0);
+ }
+ protected void writeBytes(byte[] bytes) throws JMSException
+ {
+ writeBytes(bytes, 0, bytes == null ? 0 : bytes.length);
+ }
+ protected void writeBytes(byte[] bytes, int offset, int length) throws JMSException
+ {
+ writeTypeDiscriminator(BYTEARRAY_TYPE);
+ if (bytes == null)
+ {
+ _data.putInt(-1);
+ }
+ else
+ {
+ _data.putInt(length);
+ _data.put(bytes, offset, length);
+ }
+ }
+ protected void writeObject(Object object) throws JMSException
+ {
+ checkWritable();
+ Class clazz;
+ if (object == null)
+ {
+ // string handles the output of null values
+ clazz = String.class;
+ }
+ else
+ {
+ clazz = object.getClass();
+ }
+
+ if (clazz == Byte.class)
+ {
+ writeByte((Byte) object);
+ }
+ else if (clazz == Boolean.class)
+ {
+ writeBoolean((Boolean) object);
+ }
+ else if (clazz == byte[].class)
+ {
+ writeBytes((byte[]) object);
+ }
+ else if (clazz == Short.class)
+ {
+ writeShort((Short) object);
+ }
+ else if (clazz == Character.class)
+ {
+ writeChar((Character) object);
+ }
+ else if (clazz == Integer.class)
+ {
+ writeInt((Integer) object);
+ }
+ else if (clazz == Long.class)
+ {
+ writeLong((Long) object);
+ }
+ else if (clazz == Float.class)
+ {
+ writeFloat((Float) object);
+ }
+ else if (clazz == Double.class)
+ {
+ writeDouble((Double) object);
+ }
+ else if (clazz == String.class)
+ {
+ writeString((String) object);
+ }
+ else
+ {
+ throw new MessageFormatException("Only primitives plus byte arrays and String are valid types");
+ }
+ }
}
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 f713554bfb..6ba55b207a 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
@@ -20,38 +20,66 @@
*/
package org.apache.qpid.client.message;
-import java.nio.ByteBuffer;
+import java.io.IOException;
import java.util.Enumeration;
import java.util.UUID;
import javax.jms.Destination;
import javax.jms.JMSException;
+import javax.jms.MessageNotReadableException;
import javax.jms.MessageNotWriteableException;
+import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.AMQException;
import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
public abstract class AbstractJMSMessage implements org.apache.qpid.jms.Message
{
+
+ protected ByteBuffer _data;
+ protected boolean _readableMessage = false;
+ protected boolean _changedData = true;
+
/** If the acknowledge mode is CLIENT_ACKNOWLEDGE the session is required */
+
+
+
protected AMQMessageDelegate _delegate;
private boolean _redelivered;
- private boolean _receivedFromServer;
- protected AbstractJMSMessage(AMQMessageDelegateFactory delegateFactory, boolean fromReceivedData)
+ protected AbstractJMSMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data)
{
_delegate = delegateFactory.createDelegate();
- setContentType(getMimeType());
+ _data = data;
+ if (_data != null)
+ {
+ _data.acquire();
+ }
+
+
+ _readableMessage = (data != null);
+ _changedData = (data == null);
+
}
- protected AbstractJMSMessage(AMQMessageDelegate delegate, boolean fromReceivedData) throws AMQException
+ protected AbstractJMSMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException
{
_delegate = delegate;
- setContentType(getMimeType());
+
+ _data = data;
+ if (_data != null)
+ {
+ _data.acquire();
+ }
+
+ _readableMessage = data != null;
+
}
public String getJMSMessageID() throws JMSException
@@ -301,9 +329,12 @@ public abstract class AbstractJMSMessage implements org.apache.qpid.jms.Message
public void clearBody() throws JMSException
{
- _receivedFromServer = false;
+ clearBodyImpl();
+ _readableMessage = false;
+
}
+
public void acknowledgeThis() throws JMSException
{
_delegate.acknowledgeThis();
@@ -314,7 +345,14 @@ public abstract class AbstractJMSMessage implements org.apache.qpid.jms.Message
_delegate.acknowledge();
}
- /*
+ /**
+ * This forces concrete classes to implement clearBody()
+ *
+ * @throws JMSException
+ */
+ public abstract void clearBodyImpl() throws JMSException;
+
+ /**
* Get a String representation of the body of the message. Used in the toString() method which outputs this before
* message properties.
*/
@@ -375,24 +413,63 @@ public abstract class AbstractJMSMessage implements org.apache.qpid.jms.Message
return _delegate;
}
- abstract public ByteBuffer getData() throws JMSException;
+ public ByteBuffer getData()
+ {
+ // make sure we rewind the data just in case any method has moved the
+ // position beyond the start
+ if (_data != null)
+ {
+ reset();
+ }
+ return _data;
+ }
+
+ protected void checkReadable() throws MessageNotReadableException
+ {
+ if (!_readableMessage)
+ {
+ throw new MessageNotReadableException("You need to call reset() to make the message readable");
+ }
+ }
protected void checkWritable() throws MessageNotWriteableException
{
- if (_receivedFromServer)
+ if (_readableMessage)
{
throw new MessageNotWriteableException("You need to call clearBody() to make the message writable");
}
}
-
- public void setReceivedFromServer()
+ public void reset()
{
- _receivedFromServer = true;
+ if (!_changedData)
+ {
+ _data.rewind();
+ }
+ else
+ {
+ _data.flip();
+ _changedData = false;
+ }
}
+ public int getContentLength()
+ {
+ if(_data != null)
+ {
+ return _data.remaining();
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ public void receivedFromServer()
+ {
+ _changedData = false;
+ }
/**
* The session is set when CLIENT_ACKNOWLEDGE mode is used so that the CHANNEL ACK can be sent when the user calls
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 967a1fb49f..e719c9a4b2 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
@@ -20,6 +20,8 @@
*/
package org.apache.qpid.client.message;
+import org.apache.mina.common.ByteBuffer;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.ContentBody;
@@ -36,8 +38,6 @@ import javax.jms.JMSException;
import java.util.Iterator;
import java.util.List;
-import java.nio.ByteBuffer;
-
public abstract class AbstractJMSMessageFactory implements MessageFactory
{
private static final Logger _logger = LoggerFactory.getLogger(AbstractJMSMessageFactory.class);
@@ -57,7 +57,7 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory
_logger.debug("Non-fragmented message body (bodySize=" + contentHeader.bodySize + ")");
}
- data = ByteBuffer.wrap(((ContentBody) bodies.get(0))._payload);
+ data = ((ContentBody) bodies.get(0)).payload;
}
else if (bodies != null)
{
@@ -72,7 +72,7 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory
while (it.hasNext())
{
ContentBody cb = (ContentBody) it.next();
- final ByteBuffer payload = ByteBuffer.wrap(cb._payload);
+ final ByteBuffer payload = cb.payload;
if(payload.isDirect() || payload.isReadOnly())
{
data.put(payload);
@@ -82,6 +82,7 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory
data.put(payload.array(), payload.arrayOffset(), payload.limit());
}
+ payload.release();
}
data.flip();
@@ -98,7 +99,7 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory
}
AMQMessageDelegate delegate = new AMQMessageDelegate_0_8(messageNbr,
- (BasicContentHeaderProperties) contentHeader.getProperties(),
+ (BasicContentHeaderProperties) contentHeader.properties,
exchange, routingKey);
return createMessage(delegate, data);
@@ -108,7 +109,7 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory
protected AbstractJMSMessage create010MessageWithBody(long messageNbr, MessageProperties msgProps,
- DeliveryProperties deliveryProps,
+ DeliveryProperties deliveryProps,
java.nio.ByteBuffer body) throws AMQException
{
ByteBuffer data;
@@ -117,7 +118,7 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory
if (body != null)
{
- data = body;
+ data = ByteBuffer.wrap(body);
}
else // body == null
{
@@ -154,7 +155,7 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory
{
final AbstractJMSMessage msg = create08MessageWithBody(messageNbr, contentHeader, exchange, routingKey, bodies);
msg.setJMSRedelivered(redelivered);
- msg.setReceivedFromServer();
+ msg.receivedFromServer();
return msg;
}
@@ -165,7 +166,7 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory
final AbstractJMSMessage msg =
create010MessageWithBody(messageNbr,msgProps,deliveryProps, body);
msg.setJMSRedelivered(redelivered);
- msg.setReceivedFromServer();
+ msg.receivedFromServer();
return msg;
}
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 e252bdb719..b87275a9ce 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
@@ -20,7 +20,6 @@
*/
package org.apache.qpid.client.message;
-import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
@@ -29,56 +28,47 @@ import java.nio.charset.CharsetEncoder;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
-import javax.jms.MessageEOFException;
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.BasicContentHeaderProperties;
-public class JMSBytesMessage extends AbstractBytesTypedMessage implements BytesMessage
+public class JMSBytesMessage extends AbstractBytesMessage implements BytesMessage
{
public static final String MIME_TYPE = "application/octet-stream";
- private TypedBytesContentReader _typedBytesContentReader;
- private TypedBytesContentWriter _typedBytesContentWriter;
-
public JMSBytesMessage(AMQMessageDelegateFactory delegateFactory)
{
- super(delegateFactory,false);
- _typedBytesContentWriter = new TypedBytesContentWriter();
+ 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
+ */
+ JMSBytesMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data)
+ {
+
+ super(delegateFactory, data); // this instanties a content header
}
JMSBytesMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException
{
- super(delegate, data!=null);
- _typedBytesContentReader = new TypedBytesContentReader(data);
+ super(delegate, data);
}
public void reset()
{
+ super.reset();
_readableMessage = true;
-
- if(_typedBytesContentReader != null)
- {
- _typedBytesContentReader.reset();
- }
- else if (_typedBytesContentWriter != null)
- {
- _typedBytesContentReader = new TypedBytesContentReader(_typedBytesContentWriter.getData());
- }
- }
-
- @Override
- public void clearBody() throws JMSException
- {
- super.clearBody();
- _typedBytesContentReader = null;
- _typedBytesContentWriter = new TypedBytesContentWriter();
-
}
protected String getMimeType()
@@ -86,57 +76,45 @@ public class JMSBytesMessage extends AbstractBytesTypedMessage implements BytesM
return MIME_TYPE;
}
- @Override
- public java.nio.ByteBuffer getData() throws JMSException
- {
- return _typedBytesContentWriter == null ? _typedBytesContentReader.getData() : _typedBytesContentWriter.getData();
- }
-
public long getBodyLength() throws JMSException
{
checkReadable();
- return _typedBytesContentReader.size();
+ return _data.limit();
}
public boolean readBoolean() throws JMSException
{
checkReadable();
checkAvailable(1);
-
- return _typedBytesContentReader.readBooleanImpl();
- }
-
- private void checkAvailable(final int i) throws MessageEOFException
- {
- _typedBytesContentReader.checkAvailable(1);
+ return _data.get() != 0;
}
public byte readByte() throws JMSException
{
checkReadable();
checkAvailable(1);
- return _typedBytesContentReader.readByteImpl();
+ return _data.get();
}
public int readUnsignedByte() throws JMSException
{
checkReadable();
checkAvailable(1);
- return _typedBytesContentReader.readByteImpl() & 0xFF;
+ return _data.getUnsigned();
}
public short readShort() throws JMSException
{
checkReadable();
checkAvailable(2);
- return _typedBytesContentReader.readShortImpl();
+ return _data.getShort();
}
public int readUnsignedShort() throws JMSException
{
checkReadable();
checkAvailable(2);
- return _typedBytesContentReader.readShortImpl() & 0xFFFF;
+ return _data.getUnsignedShort();
}
/**
@@ -149,35 +127,35 @@ public class JMSBytesMessage extends AbstractBytesTypedMessage implements BytesM
{
checkReadable();
checkAvailable(2);
- return _typedBytesContentReader.readCharImpl();
+ return _data.getChar();
}
public int readInt() throws JMSException
{
checkReadable();
checkAvailable(4);
- return _typedBytesContentReader.readIntImpl();
+ return _data.getInt();
}
public long readLong() throws JMSException
{
checkReadable();
checkAvailable(8);
- return _typedBytesContentReader.readLongImpl();
+ return _data.getLong();
}
public float readFloat() throws JMSException
{
checkReadable();
checkAvailable(4);
- return _typedBytesContentReader.readFloatImpl();
+ return _data.getFloat();
}
public double readDouble() throws JMSException
{
checkReadable();
checkAvailable(8);
- return _typedBytesContentReader.readDoubleImpl();
+ return _data.getDouble();
}
public String readUTF() throws JMSException
@@ -186,7 +164,34 @@ public class JMSBytesMessage extends AbstractBytesTypedMessage implements BytesM
// we check only for one byte since theoretically the string could be only a
// single byte when using UTF-8 encoding
- return _typedBytesContentReader.readLengthPrefixedUTF();
+ try
+ {
+ short length = readShort();
+ if(length == 0)
+ {
+ return "";
+ }
+ else
+ {
+ CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
+ ByteBuffer encodedString = _data.slice();
+ encodedString.limit(length);
+ _data.position(_data.position()+length);
+ CharBuffer string = decoder.decode(encodedString.buf());
+
+ return string.toString();
+ }
+
+
+
+ }
+ catch (CharacterCodingException e)
+ {
+ JMSException jmse = new JMSException("Error decoding byte stream as a UTF8 string: " + e);
+ jmse.setLinkedException(e);
+ jmse.initCause(e);
+ throw jmse;
+ }
}
public int readBytes(byte[] bytes) throws JMSException
@@ -196,14 +201,14 @@ public class JMSBytesMessage extends AbstractBytesTypedMessage implements BytesM
throw new IllegalArgumentException("byte array must not be null");
}
checkReadable();
- int count = (_typedBytesContentReader.remaining() >= bytes.length ? bytes.length : _typedBytesContentReader.remaining());
+ int count = (_data.remaining() >= bytes.length ? bytes.length : _data.remaining());
if (count == 0)
{
return -1;
}
else
{
- _typedBytesContentReader.readRawBytes(bytes, 0, count);
+ _data.get(bytes, 0, count);
return count;
}
}
@@ -219,82 +224,110 @@ public class JMSBytesMessage extends AbstractBytesTypedMessage implements BytesM
throw new IllegalArgumentException("maxLength must be <= bytes.length");
}
checkReadable();
- int count = (_typedBytesContentReader.remaining() >= maxLength ? maxLength : _typedBytesContentReader.remaining());
+ int count = (_data.remaining() >= maxLength ? maxLength : _data.remaining());
if (count == 0)
{
return -1;
}
else
{
- _typedBytesContentReader.readRawBytes(bytes, 0, count);
+ _data.get(bytes, 0, count);
return count;
}
}
-
public void writeBoolean(boolean b) throws JMSException
{
checkWritable();
- _typedBytesContentWriter.writeBooleanImpl(b);
+ _changedData = true;
+ _data.put(b ? (byte) 1 : (byte) 0);
}
public void writeByte(byte b) throws JMSException
{
checkWritable();
- _typedBytesContentWriter.writeByteImpl(b);
+ _changedData = true;
+ _data.put(b);
}
public void writeShort(short i) throws JMSException
{
checkWritable();
- _typedBytesContentWriter.writeShortImpl(i);
+ _changedData = true;
+ _data.putShort(i);
}
public void writeChar(char c) throws JMSException
{
checkWritable();
- _typedBytesContentWriter.writeCharImpl(c);
+ _changedData = true;
+ _data.putChar(c);
}
public void writeInt(int i) throws JMSException
{
checkWritable();
- _typedBytesContentWriter.writeIntImpl(i);
+ _changedData = true;
+ _data.putInt(i);
}
public void writeLong(long l) throws JMSException
{
checkWritable();
- _typedBytesContentWriter.writeLongImpl(l);
+ _changedData = true;
+ _data.putLong(l);
}
public void writeFloat(float v) throws JMSException
{
checkWritable();
- _typedBytesContentWriter.writeFloatImpl(v);
+ _changedData = true;
+ _data.putFloat(v);
}
public void writeDouble(double v) throws JMSException
{
checkWritable();
- _typedBytesContentWriter.writeDoubleImpl(v);
+ _changedData = true;
+ _data.putDouble(v);
}
public void writeUTF(String string) throws JMSException
{
checkWritable();
- _typedBytesContentWriter.writeLengthPrefixedUTF(string);
+ try
+ {
+ CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
+ java.nio.ByteBuffer encodedString = encoder.encode(CharBuffer.wrap(string));
+
+ _data.putShort((short)encodedString.limit());
+ _data.put(encodedString);
+ _changedData = true;
+ //_data.putString(string, Charset.forName("UTF-8").newEncoder());
+ // we must add the null terminator manually
+ //_data.put((byte)0);
+ }
+ catch (CharacterCodingException e)
+ {
+ JMSException jmse = new JMSException("Unable to encode string: " + e);
+ jmse.setLinkedException(e);
+ jmse.initCause(e);
+ throw jmse;
+ }
}
public void writeBytes(byte[] bytes) throws JMSException
{
- writeBytes(bytes, 0, bytes.length);
+ checkWritable();
+ _data.put(bytes);
+ _changedData = true;
}
public void writeBytes(byte[] bytes, int offset, int length) throws JMSException
{
checkWritable();
- _typedBytesContentWriter.writeBytesRaw(bytes, offset, length);
+ _data.put(bytes, offset, length);
+ _changedData = true;
}
public void writeObject(Object object) 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 89561b88eb..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
@@ -22,12 +22,11 @@ package org.apache.qpid.client.message;
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.BasicContentHeaderProperties;
-import java.nio.ByteBuffer;
-
public class JMSBytesMessageFactory extends AbstractJMSMessageFactory
{
protected AbstractJMSMessage createMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException
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 52c0eb263b..e295d4a2a0 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
@@ -20,15 +20,12 @@
*/
package org.apache.qpid.client.message;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
import java.util.Enumeration;
import javax.jms.JMSException;
import javax.jms.MessageFormatException;
-import java.nio.ByteBuffer;
+import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.AMQPInvalidClassException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
@@ -285,7 +282,7 @@ public final class JMSHeaderAdapter
s = String.valueOf(o);
}
}
- }//else return s // null;
+ }//else return s // null;
}
return s;
@@ -461,29 +458,9 @@ public final class JMSHeaderAdapter
return getHeaders().isEmpty();
}
- public void writeToBuffer(final ByteBuffer data)
+ public void writeToBuffer(ByteBuffer data)
{
- try
- {
- getHeaders().writeToBuffer(new DataOutputStream(new OutputStream()
- {
- @Override
- public void write(final int b)
- {
- data.put((byte)b);
- }
-
- @Override
- public void write(final byte[] b, final int off, final int len)
- {
- data.put(b, off, len);
- }
- }));
- }
- catch (IOException e)
- {
- throw new IllegalArgumentException("Unexpected IO Exception - should never happen", e);
- }
+ getHeaders().writeToBuffer(data);
}
public Enumeration getMapNames()
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 fad24a968e..306ffeeadf 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
@@ -20,8 +20,11 @@
*/
package org.apache.qpid.client.message;
-import org.apache.qpid.AMQException;
+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.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -29,14 +32,13 @@ import org.slf4j.LoggerFactory;
import javax.jms.JMSException;
import javax.jms.MessageFormatException;
-import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
-public class JMSMapMessage extends AbstractJMSMessage implements javax.jms.MapMessage
+public class JMSMapMessage extends AbstractBytesTypedMessage implements javax.jms.MapMessage
{
private static final Logger _logger = LoggerFactory.getLogger(JMSMapMessage.class);
@@ -52,10 +54,10 @@ public class JMSMapMessage extends AbstractJMSMessage implements javax.jms.MapMe
JMSMapMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data) throws JMSException
{
- super(delegateFactory, data!=null); // this instantiates a content header
+ super(delegateFactory, data); // this instantiates a content header
if(data != null)
{
- populateMapFromData(data);
+ populateMapFromData();
}
}
@@ -63,10 +65,10 @@ public class JMSMapMessage extends AbstractJMSMessage implements javax.jms.MapMe
JMSMapMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException
{
- super(delegate, data != null);
+ super(delegate, data);
try
{
- populateMapFromData(data);
+ populateMapFromData();
}
catch (JMSException je)
{
@@ -87,10 +89,18 @@ public class JMSMapMessage extends AbstractJMSMessage implements javax.jms.MapMe
return MIME_TYPE;
}
+ public ByteBuffer getData()
+ {
+ // What if _data is null?
+ writeMapToData();
+
+ return super.getData();
+ }
+
@Override
- public void clearBody() throws JMSException
+ public void clearBodyImpl() throws JMSException
{
- super.clearBody();
+ super.clearBodyImpl();
_map.clear();
}
@@ -448,18 +458,17 @@ public class JMSMapMessage extends AbstractJMSMessage implements javax.jms.MapMe
return _map.containsKey(propName);
}
- protected void populateMapFromData(ByteBuffer data) throws JMSException
+ protected void populateMapFromData() throws JMSException
{
- TypedBytesContentReader reader = new TypedBytesContentReader(data);
- if (data != null)
+ if (_data != null)
{
- data.rewind();
+ _data.rewind();
- final int entries = reader.readIntImpl();
+ final int entries = readIntImpl();
for (int i = 0; i < entries; i++)
{
- String propName = reader.readStringImpl();
- Object value = reader.readObject();
+ String propName = readStringImpl();
+ Object value = readObject();
_map.put(propName, value);
}
}
@@ -469,21 +478,35 @@ public class JMSMapMessage extends AbstractJMSMessage implements javax.jms.MapMe
}
}
- public ByteBuffer getData()
- throws JMSException
+ protected void writeMapToData()
{
- TypedBytesContentWriter writer = new TypedBytesContentWriter();
-
+ allocateInitialBuffer();
final int size = _map.size();
- writer.writeIntImpl(size);
+ writeIntImpl(size);
for (Map.Entry<String, Object> entry : _map.entrySet())
{
- writer.writeNullTerminatedStringImpl(entry.getKey());
+ try
+ {
+ writeStringImpl(entry.getKey());
+ }
+ catch (CharacterCodingException e)
+ {
+ throw new IllegalArgumentException("Cannot encode property key name " + entry.getKey(), e);
+
+ }
- writer.writeObject(entry.getValue());
+ try
+ {
+ writeObject(entry.getValue());
+ }
+ catch (JMSException e)
+ {
+ Object value = entry.getValue();
+ throw new IllegalArgumentException("Cannot encode property key name " + entry.getKey() + " value : " + value
+ + " (type: " + value.getClass().getName() + ").", e);
+ }
}
- return writer.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 89408a5c3c..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
@@ -14,16 +14,18 @@
* "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.
- *
+ * under the License.
*
+ *
*/
package org.apache.qpid.client.message;
import javax.jms.JMSException;
-import java.nio.ByteBuffer;
+import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
public class JMSMapMessageFactory extends AbstractJMSMessageFactory
{
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 c981c951c3..637d9dd692 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
@@ -20,28 +20,26 @@
*/
package org.apache.qpid.client.message;
-import java.io.*;
-import java.nio.ByteBuffer;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
import javax.jms.JMSException;
import javax.jms.MessageFormatException;
import javax.jms.ObjectMessage;
+import org.apache.mina.common.ByteBuffer;
+
import org.apache.qpid.AMQException;
-import org.apache.qpid.client.util.ClassLoadingAwareObjectInputStream;
public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessage
{
public static final String MIME_TYPE = "application/java-object-stream";
- private static final int DEFAULT_OUTPUT_BUFFER_SIZE = 256;
-
- private Serializable _readData;
- private ByteBuffer _data;
- private Exception _exception;
-
- private static final ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.allocate(0);
+ private static final int DEFAULT_BUFFER_SIZE = 1024;
/**
* Creates empty, writable message for use by producers
@@ -49,57 +47,41 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
*/
public JMSObjectMessage(AMQMessageDelegateFactory delegateFactory)
{
- super(delegateFactory, false);
+ this(delegateFactory, null);
+ }
+
+ private JMSObjectMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data)
+ {
+ super(delegateFactory, data);
+ if (data == null)
+ {
+ _data = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
+ _data.setAutoExpand(true);
+ }
+
+ setContentType(getMimeType());
}
/**
* Creates read only message for delivery to consumers
*/
- JMSObjectMessage(AMQMessageDelegate delegate, final ByteBuffer data) throws AMQException
+ JMSObjectMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException
{
- super(delegate, data!=null);
-
- try
- {
- ClassLoadingAwareObjectInputStream in = new ClassLoadingAwareObjectInputStream(new InputStream()
- {
-
-
- @Override
- public int read() throws IOException
- {
- return data.get();
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException
- {
- len = data.remaining() < len ? data.remaining() : len;
- data.get(b, off, len);
- return len;
- }
- });
-
- _readData = (Serializable) in.readObject();
- }
- catch (IOException e)
- {
- _exception = e;
- }
- catch (ClassNotFoundException e)
- {
- _exception = e;
- }
+ super(delegate, data);
}
- public void clearBody() throws JMSException
+ public void clearBodyImpl() throws JMSException
{
- super.clearBody();
- _exception = null;
- _readData = null;
- _data = null;
+ if (_data != null)
+ {
+ _data.release();
+ _data = null;
+ }
+
+
+
}
public String toBodyString() throws JMSException
@@ -112,116 +94,83 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
return MIME_TYPE;
}
- @Override
- public ByteBuffer getData() throws JMSException
+ public void setObject(Serializable serializable) throws JMSException
{
- if(_exception != null)
- {
- final MessageFormatException messageFormatException =
- new MessageFormatException("Unable to deserialize message");
- messageFormatException.setLinkedException(_exception);
- throw messageFormatException;
- }
- if(_readData == null)
- {
+ checkWritable();
- return _data == null ? EMPTY_BYTE_BUFFER : _data.duplicate();
+ if (_data == null)
+ {
+ _data = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
+ _data.setAutoExpand(true);
}
else
{
- try
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream(DEFAULT_OUTPUT_BUFFER_SIZE);
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(_readData);
- oos.flush();
- return ByteBuffer.wrap(baos.toByteArray());
- }
- catch (IOException e)
- {
- final JMSException jmsException = new JMSException("Unable to encode object of type: " +
- _readData.getClass().getName() + ", value " + _readData);
- jmsException.setLinkedException(e);
- throw jmsException;
- }
+ _data.rewind();
}
- }
-
- public void setObject(Serializable serializable) throws JMSException
- {
- checkWritable();
- clearBody();
try
{
- ByteArrayOutputStream baos = new ByteArrayOutputStream(DEFAULT_OUTPUT_BUFFER_SIZE);
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(serializable);
- oos.flush();
- _data = ByteBuffer.wrap(baos.toByteArray());
+ ObjectOutputStream out = new ObjectOutputStream(_data.asOutputStream());
+ out.writeObject(serializable);
+ out.flush();
+ out.close();
}
catch (IOException e)
{
- final JMSException jmsException = new JMSException("Unable to encode object of type: " +
- serializable.getClass().getName() + ", value " + serializable);
- jmsException.setLinkedException(e);
- throw jmsException;
+ MessageFormatException mfe = new MessageFormatException("Message not serializable: " + e);
+ mfe.setLinkedException(e);
+ mfe.initCause(e);
+ throw mfe;
}
}
public Serializable getObject() throws JMSException
{
- if(_exception != null)
+ ObjectInputStream in = null;
+ if (_data == null)
{
- final MessageFormatException messageFormatException = new MessageFormatException("Unable to deserialize message");
- messageFormatException.setLinkedException(_exception);
- throw messageFormatException;
+ return null;
}
- else if(_readData != null || _data == null)
+
+ try
{
- return _readData;
+ _data.rewind();
+ in = new ObjectInputStream(_data.asInputStream());
+
+ return (Serializable) in.readObject();
}
- else
+ catch (IOException e)
+ {
+ MessageFormatException mfe = new MessageFormatException("Could not deserialize message: " + e);
+ mfe.setLinkedException(e);
+ mfe.initCause(e);
+ throw mfe;
+ }
+ catch (ClassNotFoundException e)
+ {
+ MessageFormatException mfe = new MessageFormatException("Could not deserialize message: " + e);
+ mfe.setLinkedException(e);
+ mfe.initCause(e);
+ throw mfe;
+ }
+ finally
{
- Exception exception = null;
+ // _data.rewind();
+ close(in);
+ }
+ }
- final ByteBuffer data = _data.duplicate();
- try
- {
- ClassLoadingAwareObjectInputStream in = new ClassLoadingAwareObjectInputStream(new InputStream()
- {
- @Override
- public int read() throws IOException
- {
- return data.get();
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException
- {
- len = data.remaining() < len ? data.remaining() : len;
- data.get(b, off, len);
- return len;
- }
- });
-
- return (Serializable) in.readObject();
- }
- catch (ClassNotFoundException e)
- {
- exception = e;
- }
- catch (IOException e)
+ private static void close(InputStream in)
+ {
+ try
+ {
+ if (in != null)
{
- exception = e;
+ in.close();
}
-
- JMSException jmsException = new JMSException("Could not deserialize object");
- jmsException.setLinkedException(exception);
- throw jmsException;
}
-
+ catch (IOException ignore)
+ { }
}
-
}
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 4660c91c1f..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
@@ -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
@@ -22,8 +22,10 @@ package org.apache.qpid.client.message;
import javax.jms.JMSException;
-import java.nio.ByteBuffer;
+import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
public class JMSObjectMessageFactory extends AbstractJMSMessageFactory
{
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 5c93f6b6f0..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
@@ -23,8 +23,7 @@ package org.apache.qpid.client.message;
import javax.jms.JMSException;
import javax.jms.StreamMessage;
-import java.nio.ByteBuffer;
-
+import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicContentHeaderProperties;
@@ -37,76 +36,65 @@ public class JMSStreamMessage extends AbstractBytesTypedMessage implements Strea
public static final String MIME_TYPE="jms/stream-message";
- private TypedBytesContentReader _typedBytesContentReader;
- private TypedBytesContentWriter _typedBytesContentWriter;
+
+ /**
+ * This is set when reading a byte array. The readBytes(byte[]) method supports multiple calls to read
+ * a byte array in multiple chunks, hence this is used to track how much is left to be read
+ */
+ private int _byteArrayRemaining = -1;
public JMSStreamMessage(AMQMessageDelegateFactory delegateFactory)
{
- super(delegateFactory,false);
- _typedBytesContentWriter = new TypedBytesContentWriter();
+ 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
+ */
+ JMSStreamMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data)
+ {
+ super(delegateFactory, data); // this instanties a content header
+ }
JMSStreamMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException
{
- super(delegate, data!=null);
- _typedBytesContentReader = new TypedBytesContentReader(data);
+
+ super(delegate, data);
}
+
public void reset()
{
+ super.reset();
_readableMessage = true;
-
- if(_typedBytesContentReader != null)
- {
- _typedBytesContentReader.reset();
- }
- else if (_typedBytesContentWriter != null)
- {
- _typedBytesContentReader = new TypedBytesContentReader(_typedBytesContentWriter.getData());
- }
- }
-
- @Override
- public void clearBody() throws JMSException
- {
- super.clearBody();
- _typedBytesContentReader = null;
- _typedBytesContentWriter = new TypedBytesContentWriter();
-
}
-
protected String getMimeType()
{
return MIME_TYPE;
}
- @Override
- public java.nio.ByteBuffer getData() throws JMSException
- {
- return _typedBytesContentWriter == null ? _typedBytesContentReader.getData() : _typedBytesContentWriter.getData();
- }
+
public boolean readBoolean() throws JMSException
{
- checkReadable();
- return _typedBytesContentReader.readBoolean();
+ return super.readBoolean();
}
public byte readByte() throws JMSException
{
- checkReadable();
- return _typedBytesContentReader.readByte();
+ return super.readByte();
}
public short readShort() throws JMSException
{
- checkReadable();
- return _typedBytesContentReader.readShort();
+ return super.readShort();
}
/**
@@ -117,127 +105,102 @@ public class JMSStreamMessage extends AbstractBytesTypedMessage implements Strea
*/
public char readChar() throws JMSException
{
- checkReadable();
- return _typedBytesContentReader.readChar();
+ return super.readChar();
}
public int readInt() throws JMSException
{
- checkReadable();
- return _typedBytesContentReader.readInt();
+ return super.readInt();
}
public long readLong() throws JMSException
{
- checkReadable();
- return _typedBytesContentReader.readLong();
+ return super.readLong();
}
public float readFloat() throws JMSException
{
- checkReadable();
- return _typedBytesContentReader.readFloat();
+ return super.readFloat();
}
public double readDouble() throws JMSException
{
- checkReadable();
- return _typedBytesContentReader.readDouble();
+ return super.readDouble();
}
public String readString() throws JMSException
{
- checkReadable();
- return _typedBytesContentReader.readString();
+ return super.readString();
}
public int readBytes(byte[] bytes) throws JMSException
{
- if(bytes == null)
- {
- throw new IllegalArgumentException("Must provide non-null array to read into");
- }
-
- checkReadable();
- return _typedBytesContentReader.readBytes(bytes);
+ return super.readBytes(bytes);
}
public Object readObject() throws JMSException
{
- checkReadable();
- return _typedBytesContentReader.readObject();
+ return super.readObject();
}
public void writeBoolean(boolean b) throws JMSException
{
- checkWritable();
- _typedBytesContentWriter.writeBoolean(b);
+ super.writeBoolean(b);
}
public void writeByte(byte b) throws JMSException
{
- checkWritable();
- _typedBytesContentWriter.writeByte(b);
+ super.writeByte(b);
}
public void writeShort(short i) throws JMSException
{
- checkWritable();
- _typedBytesContentWriter.writeShort(i);
+ super.writeShort(i);
}
public void writeChar(char c) throws JMSException
{
- checkWritable();
- _typedBytesContentWriter.writeChar(c);
+ super.writeChar(c);
}
public void writeInt(int i) throws JMSException
{
- checkWritable();
- _typedBytesContentWriter.writeInt(i);
+ super.writeInt(i);
}
public void writeLong(long l) throws JMSException
{
- checkWritable();
- _typedBytesContentWriter.writeLong(l);
+ super.writeLong(l);
}
public void writeFloat(float v) throws JMSException
{
- checkWritable();
- _typedBytesContentWriter.writeFloat(v);
+ super.writeFloat(v);
}
public void writeDouble(double v) throws JMSException
{
- checkWritable();
- _typedBytesContentWriter.writeDouble(v);
+ super.writeDouble(v);
}
public void writeString(String string) throws JMSException
{
- checkWritable();
- _typedBytesContentWriter.writeString(string);
+ super.writeString(string);
}
public void writeBytes(byte[] bytes) throws JMSException
{
- checkWritable();
- _typedBytesContentWriter.writeBytes(bytes);
+ super.writeBytes(bytes);
}
public void writeBytes(byte[] bytes, int offset, int length) throws JMSException
{
- checkWritable();
- _typedBytesContentWriter.writeBytes(bytes, offset, length);
+ super.writeBytes(bytes,offset,length);
}
public void writeObject(Object object) throws JMSException
{
- checkWritable();
- _typedBytesContentWriter.writeObject(object);
+ super.writeObject(object);
}
}
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 359f5157f3..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
@@ -22,9 +22,10 @@ package org.apache.qpid.client.message;
import javax.jms.JMSException;
-import java.nio.ByteBuffer;
-
+import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
public class JMSStreamMessageFactory extends AbstractJMSMessageFactory
{
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 acf3a0ca14..fc2006a119 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
@@ -20,21 +20,15 @@
*/
package org.apache.qpid.client.message;
-import java.io.DataInputStream;
import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
import javax.jms.JMSException;
-import javax.jms.MessageFormatException;
+import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.AMQException;
import org.apache.qpid.client.CustomJMSXProperty;
-import org.apache.qpid.framing.AMQFrameDecodingException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicContentHeaderProperties;
import org.apache.qpid.util.Strings;
@@ -43,7 +37,6 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text
{
private static final String MIME_TYPE = "text/plain";
- private Exception _exception;
private String _decodedValue;
/**
@@ -52,41 +45,36 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text
private static final String PAYLOAD_NULL_PROPERTY = CustomJMSXProperty.JMS_AMQP_NULL.toString();
private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
- private CharsetDecoder _decoder = DEFAULT_CHARSET.newDecoder();
- private CharsetEncoder _encoder = DEFAULT_CHARSET.newEncoder();
-
- private static final ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.allocate(0);
-
public JMSTextMessage(AMQMessageDelegateFactory delegateFactory) throws JMSException
{
- super(delegateFactory, false); // this instantiates a content header
+ this(delegateFactory, null, null);
+ }
+
+ JMSTextMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data, String encoding) throws JMSException
+ {
+ super(delegateFactory, data); // this instantiates a content header
+ setContentType(getMimeType());
+ setEncoding(encoding);
}
JMSTextMessage(AMQMessageDelegate delegate, ByteBuffer data)
throws AMQException
{
- super(delegate, data!=null);
+ super(delegate, data);
+ setContentType(getMimeType());
+ _data = data;
+ }
- try
- {
- if(propertyExists(PAYLOAD_NULL_PROPERTY))
- {
- _decodedValue = null;
- }
- else
- {
- _decodedValue = _decoder.decode(data).toString();
- }
- }
- catch (CharacterCodingException e)
- {
- _exception = e;
- }
- catch (JMSException e)
+
+ public void clearBodyImpl() throws JMSException
+ {
+ if (_data != null)
{
- _exception = e;
+ _data.release();
+ _data = null;
}
+ _decodedValue = null;
}
public String toBodyString() throws JMSException
@@ -99,62 +87,95 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text
return MIME_TYPE;
}
- @Override
- public ByteBuffer getData() throws JMSException
+ public void setText(String text) throws JMSException
{
- _encoder.reset();
+ checkWritable();
+
+ clearBody();
try
{
- if(_exception != null)
- {
- final MessageFormatException messageFormatException = new MessageFormatException("Cannot decode original message");
- messageFormatException.setLinkedException(_exception);
- throw messageFormatException;
- }
- else if(_decodedValue == null)
- {
- return EMPTY_BYTE_BUFFER;
- }
- else
+ if (text != null)
{
- return _encoder.encode(CharBuffer.wrap(_decodedValue));
+ final String encoding = getEncoding();
+ if (encoding == null || encoding.equalsIgnoreCase("UTF-8"))
+ {
+ _data = ByteBuffer.wrap(Strings.toUTF8(text));
+ setEncoding("UTF-8");
+ }
+ else
+ {
+ _data = ByteBuffer.wrap(text.getBytes(encoding));
+ }
+ _data.position(_data.limit());
+ _changedData=true;
}
+ _decodedValue = text;
}
- catch (CharacterCodingException e)
+ catch (UnsupportedEncodingException e)
{
- final JMSException jmsException = new JMSException("Cannot encode string in UFT-8: " + _decodedValue);
- jmsException.setLinkedException(e);
- throw jmsException;
+ // should never occur
+ JMSException jmse = new JMSException("Unable to decode text data");
+ jmse.setLinkedException(e);
+ jmse.initCause(e);
+ throw jmse;
}
}
- @Override
- public void clearBody() throws JMSException
- {
- super.clearBody();
- _decodedValue = null;
- _exception = null;
- }
-
- public void setText(String text) throws JMSException
- {
- checkWritable();
-
- clearBody();
- _decodedValue = text;
-
- }
-
public String getText() throws JMSException
{
- return _decodedValue;
+ if (_data == null && _decodedValue == null)
+ {
+ return null;
+ }
+ else if (_decodedValue != null)
+ {
+ return _decodedValue;
+ }
+ else
+ {
+ _data.rewind();
+
+ if (propertyExists(PAYLOAD_NULL_PROPERTY) && getBooleanProperty(PAYLOAD_NULL_PROPERTY))
+ {
+ return null;
+ }
+ if (getEncoding() != null)
+ {
+ try
+ {
+ _decodedValue = _data.getString(Charset.forName(getEncoding()).newDecoder());
+ }
+ catch (CharacterCodingException e)
+ {
+ JMSException jmse = new JMSException("Could not decode string data: " + e);
+ jmse.setLinkedException(e);
+ jmse.initCause(e);
+ throw jmse;
+ }
+ }
+ else
+ {
+ try
+ {
+ _decodedValue = _data.getString(DEFAULT_CHARSET.newDecoder());
+ }
+ catch (CharacterCodingException e)
+ {
+ JMSException jmse = new JMSException("Could not decode string data: " + e);
+ jmse.setLinkedException(e);
+ jmse.initCause(e);
+ throw jmse;
+ }
+ }
+ return _decodedValue;
+ }
}
@Override
public void prepareForSending() throws JMSException
{
super.prepareForSending();
- if (_decodedValue == null)
+ if (_data == null)
{
setBooleanProperty(PAYLOAD_NULL_PROPERTY, true);
}
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 d1af32c10a..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
@@ -22,7 +22,7 @@ package org.apache.qpid.client.message;
import javax.jms.JMSException;
-import java.nio.ByteBuffer;
+import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicContentHeaderProperties;
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 cdb75fc9a9..4e4061cf4d 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
@@ -104,7 +104,7 @@ public class MessageFactoryRegistry
AMQShortString routingKey, ContentHeaderBody contentHeader, List bodies)
throws AMQException, JMSException
{
- BasicContentHeaderProperties properties = (BasicContentHeaderProperties) contentHeader.getProperties();
+ BasicContentHeaderProperties properties = (BasicContentHeaderProperties) contentHeader.properties;
// Get the message content type. This may be null for pure AMQP messages, but will always be set for JMS over
// AMQP. When the type is null, it can only be assumed that the message is a byte message.
diff --git a/java/client/src/main/java/org/apache/qpid/client/message/TypedBytesContentReader.java b/java/client/src/main/java/org/apache/qpid/client/message/TypedBytesContentReader.java
deleted file mode 100644
index 1ae25eb1ed..0000000000
--- a/java/client/src/main/java/org/apache/qpid/client/message/TypedBytesContentReader.java
+++ /dev/null
@@ -1,674 +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 javax.jms.MessageEOFException;
-import javax.jms.MessageFormatException;
-import javax.jms.MessageNotReadableException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-
-class TypedBytesContentReader implements TypedBytesCodes
-{
-
- private final ByteBuffer _data;
- private final int _position;
- private final int _limit;
-
-
- private static final Charset UTF8_CHARSET = Charset.forName("UTF-8");
-
- private final CharsetDecoder _charsetDecoder = UTF8_CHARSET.newDecoder();
-
- private int _byteArrayRemaining = -1;
-
-
- public TypedBytesContentReader(final ByteBuffer data)
- {
- _data = data.duplicate();
- _position = _data.position();
- _limit = _data.limit();
- }
-
- /**
- * Check that there is at least a certain number of bytes available to read
- *
- * @param len the number of bytes
- * @throws javax.jms.MessageEOFException if there are less than len bytes available to read
- */
- protected void checkAvailable(int len) throws MessageEOFException
- {
- if (_data.remaining() < len)
- {
- throw new MessageEOFException("Unable to read " + len + " bytes");
- }
- }
-
- protected byte readWireType() throws MessageFormatException, MessageEOFException,
- MessageNotReadableException
- {
- checkAvailable(1);
- return _data.get();
- }
-
- protected boolean readBoolean() throws JMSException
- {
- int position = _data.position();
- byte wireType = readWireType();
- boolean result;
- try
- {
- switch (wireType)
- {
- case BOOLEAN_TYPE:
- checkAvailable(1);
- result = readBooleanImpl();
- break;
- case STRING_TYPE:
- checkAvailable(1);
- result = Boolean.parseBoolean(readStringImpl());
- break;
- default:
- _data.position(position);
- throw new MessageFormatException("Unable to convert " + wireType + " to a boolean");
- }
- return result;
- }
- catch (RuntimeException e)
- {
- _data.position(position);
- throw e;
- }
- }
-
- boolean readBooleanImpl()
- {
- return _data.get() != 0;
- }
-
- protected byte readByte() throws JMSException
- {
- int position = _data.position();
- byte wireType = readWireType();
- byte result;
- try
- {
- switch (wireType)
- {
- case BYTE_TYPE:
- checkAvailable(1);
- result = readByteImpl();
- break;
- case STRING_TYPE:
- checkAvailable(1);
- result = Byte.parseByte(readStringImpl());
- break;
- default:
- _data.position(position);
- throw new MessageFormatException("Unable to convert " + wireType + " to a byte");
- }
- }
- catch (RuntimeException e)
- {
- _data.position(position);
- throw e;
- }
- return result;
- }
-
- byte readByteImpl()
- {
- return _data.get();
- }
-
- protected short readShort() throws JMSException
- {
- int position = _data.position();
- byte wireType = readWireType();
- short result;
- try
- {
- switch (wireType)
- {
- case SHORT_TYPE:
- checkAvailable(2);
- result = readShortImpl();
- break;
- case STRING_TYPE:
- checkAvailable(1);
- result = Short.parseShort(readStringImpl());
- break;
- case BYTE_TYPE:
- checkAvailable(1);
- result = readByteImpl();
- break;
- default:
- _data.position(position);
- throw new MessageFormatException("Unable to convert " + wireType + " to a short");
- }
- }
- catch (RuntimeException e)
- {
- _data.position(position);
- throw e;
- }
- return result;
- }
-
- short readShortImpl()
- {
- return _data.getShort();
- }
-
- /**
- * Note that this method reads a unicode character as two bytes from the stream
- *
- * @return the character read from the stream
- * @throws javax.jms.JMSException
- */
- protected char readChar() throws JMSException
- {
- int position = _data.position();
- byte wireType = readWireType();
- try
- {
- if (wireType == NULL_STRING_TYPE)
- {
- throw new NullPointerException();
- }
-
- if (wireType != CHAR_TYPE)
- {
- _data.position(position);
- throw new MessageFormatException("Unable to convert " + wireType + " to a char");
- }
- else
- {
- checkAvailable(2);
- return readCharImpl();
- }
- }
- catch (RuntimeException e)
- {
- _data.position(position);
- throw e;
- }
- }
-
- char readCharImpl()
- {
- return _data.getChar();
- }
-
- protected int readInt() throws JMSException
- {
- int position = _data.position();
- byte wireType = readWireType();
- int result;
- try
- {
- switch (wireType)
- {
- case INT_TYPE:
- checkAvailable(4);
- result = readIntImpl();
- break;
- case SHORT_TYPE:
- checkAvailable(2);
- result = readShortImpl();
- break;
- case STRING_TYPE:
- checkAvailable(1);
- result = Integer.parseInt(readStringImpl());
- break;
- case BYTE_TYPE:
- checkAvailable(1);
- result = readByteImpl();
- break;
- default:
- _data.position(position);
- throw new MessageFormatException("Unable to convert " + wireType + " to an int");
- }
- return result;
- }
- catch (RuntimeException e)
- {
- _data.position(position);
- throw e;
- }
- }
-
- protected int readIntImpl()
- {
- return _data.getInt();
- }
-
- protected long readLong() throws JMSException
- {
- int position = _data.position();
- byte wireType = readWireType();
- long result;
- try
- {
- switch (wireType)
- {
- case LONG_TYPE:
- checkAvailable(8);
- result = readLongImpl();
- break;
- case INT_TYPE:
- checkAvailable(4);
- result = readIntImpl();
- break;
- case SHORT_TYPE:
- checkAvailable(2);
- result = readShortImpl();
- break;
- case STRING_TYPE:
- checkAvailable(1);
- result = Long.parseLong(readStringImpl());
- break;
- case BYTE_TYPE:
- checkAvailable(1);
- result = readByteImpl();
- break;
- default:
- _data.position(position);
- throw new MessageFormatException("Unable to convert " + wireType + " to a long");
- }
- return result;
- }
- catch (RuntimeException e)
- {
- _data.position(position);
- throw e;
- }
- }
-
- long readLongImpl()
- {
- return _data.getLong();
- }
-
- protected float readFloat() throws JMSException
- {
- int position = _data.position();
- byte wireType = readWireType();
- float result;
- try
- {
- switch (wireType)
- {
- case FLOAT_TYPE:
- checkAvailable(4);
- result = readFloatImpl();
- break;
- case STRING_TYPE:
- checkAvailable(1);
- result = Float.parseFloat(readStringImpl());
- break;
- default:
- _data.position(position);
- throw new MessageFormatException("Unable to convert " + wireType + " to a float");
- }
- return result;
- }
- catch (RuntimeException e)
- {
- _data.position(position);
- throw e;
- }
- }
-
- float readFloatImpl()
- {
- return _data.getFloat();
- }
-
- protected double readDouble() throws JMSException
- {
- int position = _data.position();
- byte wireType = readWireType();
- double result;
- try
- {
- switch (wireType)
- {
- case DOUBLE_TYPE:
- checkAvailable(8);
- result = readDoubleImpl();
- break;
- case FLOAT_TYPE:
- checkAvailable(4);
- result = readFloatImpl();
- break;
- case STRING_TYPE:
- checkAvailable(1);
- result = Double.parseDouble(readStringImpl());
- break;
- default:
- _data.position(position);
- throw new MessageFormatException("Unable to convert " + wireType + " to a double");
- }
- return result;
- }
- catch (RuntimeException e)
- {
- _data.position(position);
- throw e;
- }
- }
-
- double readDoubleImpl()
- {
- return _data.getDouble();
- }
-
- protected String readString() throws JMSException
- {
- int position = _data.position();
- byte wireType = readWireType();
- String result;
- try
- {
- switch (wireType)
- {
- case STRING_TYPE:
- checkAvailable(1);
- result = readStringImpl();
- break;
- case NULL_STRING_TYPE:
- result = null;
- throw new NullPointerException("data is null");
- case BOOLEAN_TYPE:
- checkAvailable(1);
- result = String.valueOf(readBooleanImpl());
- break;
- case LONG_TYPE:
- checkAvailable(8);
- result = String.valueOf(readLongImpl());
- break;
- case INT_TYPE:
- checkAvailable(4);
- result = String.valueOf(readIntImpl());
- break;
- case SHORT_TYPE:
- checkAvailable(2);
- result = String.valueOf(readShortImpl());
- break;
- case BYTE_TYPE:
- checkAvailable(1);
- result = String.valueOf(readByteImpl());
- break;
- case FLOAT_TYPE:
- checkAvailable(4);
- result = String.valueOf(readFloatImpl());
- break;
- case DOUBLE_TYPE:
- checkAvailable(8);
- result = String.valueOf(readDoubleImpl());
- break;
- case CHAR_TYPE:
- checkAvailable(2);
- result = String.valueOf(readCharImpl());
- break;
- default:
- _data.position(position);
- throw new MessageFormatException("Unable to convert " + wireType + " to a String");
- }
- return result;
- }
- catch (RuntimeException e)
- {
- _data.position(position);
- throw e;
- }
- }
-
- protected String readStringImpl() throws JMSException
- {
- try
- {
- _charsetDecoder.reset();
- ByteBuffer dup = _data.duplicate();
- int pos = _data.position();
- byte b;
- while((b = _data.get()) != 0);
- dup.limit(_data.position()-1);
- return _charsetDecoder.decode(dup).toString();
-
- }
- catch (CharacterCodingException e)
- {
- JMSException jmse = new JMSException("Error decoding byte stream as a UTF8 string: " + e);
- jmse.setLinkedException(e);
- jmse.initCause(e);
- throw jmse;
- }
- }
-
- protected int readBytes(byte[] bytes) throws JMSException
- {
- if (bytes == null)
- {
- throw new IllegalArgumentException("byte array must not be null");
- }
- // first call
- if (_byteArrayRemaining == -1)
- {
- // type discriminator checked separately so you get a MessageFormatException rather than
- // an EOF even in the case where both would be applicable
- checkAvailable(1);
- byte wireType = readWireType();
- if (wireType != BYTEARRAY_TYPE)
- {
- throw new MessageFormatException("Unable to convert " + wireType + " to a byte array");
- }
- checkAvailable(4);
- int size = _data.getInt();
- // length of -1 indicates null
- if (size == -1)
- {
- return -1;
- }
- else
- {
- if (size > _data.remaining())
- {
- throw new MessageEOFException("Byte array has stated length "
- + size
- + " but message only contains "
- +
- _data.remaining()
- + " bytes");
- }
- else
- {
- _byteArrayRemaining = size;
- }
- }
- }
- else if (_byteArrayRemaining == 0)
- {
- _byteArrayRemaining = -1;
- return -1;
- }
-
- int returnedSize = readBytesImpl(bytes);
- if (returnedSize < bytes.length)
- {
- _byteArrayRemaining = -1;
- }
- return returnedSize;
- }
-
- private int readBytesImpl(byte[] bytes)
- {
- int count = (_byteArrayRemaining >= bytes.length ? bytes.length : _byteArrayRemaining);
- _byteArrayRemaining -= count;
-
- if (count == 0)
- {
- return 0;
- }
- else
- {
- _data.get(bytes, 0, count);
- return count;
- }
- }
-
- protected Object readObject() throws JMSException
- {
- int position = _data.position();
- byte wireType = readWireType();
- Object result = null;
- try
- {
- switch (wireType)
- {
- case BOOLEAN_TYPE:
- checkAvailable(1);
- result = readBooleanImpl();
- break;
- case BYTE_TYPE:
- checkAvailable(1);
- result = readByteImpl();
- break;
- case BYTEARRAY_TYPE:
- checkAvailable(4);
- int size = _data.getInt();
- if (size == -1)
- {
- result = null;
- }
- else
- {
- _byteArrayRemaining = size;
- byte[] bytesResult = new byte[size];
- readBytesImpl(bytesResult);
- result = bytesResult;
- }
- break;
- case SHORT_TYPE:
- checkAvailable(2);
- result = readShortImpl();
- break;
- case CHAR_TYPE:
- checkAvailable(2);
- result = readCharImpl();
- break;
- case INT_TYPE:
- checkAvailable(4);
- result = readIntImpl();
- break;
- case LONG_TYPE:
- checkAvailable(8);
- result = readLongImpl();
- break;
- case FLOAT_TYPE:
- checkAvailable(4);
- result = readFloatImpl();
- break;
- case DOUBLE_TYPE:
- checkAvailable(8);
- result = readDoubleImpl();
- break;
- case NULL_STRING_TYPE:
- result = null;
- break;
- case STRING_TYPE:
- checkAvailable(1);
- result = readStringImpl();
- break;
- }
- return result;
- }
- catch (RuntimeException e)
- {
- _data.position(position);
- throw e;
- }
- }
-
- public void reset()
- {
- _byteArrayRemaining = -1;
- _data.position(_position);
- _data.limit(_limit);
- }
-
- public ByteBuffer getData()
- {
- ByteBuffer buf = _data.duplicate();
- buf.position(_position);
- buf.limit(_limit);
- return buf;
- }
-
- public long size()
- {
- return _limit - _position;
- }
-
- public int remaining()
- {
- return _data.remaining();
- }
-
- public void readRawBytes(final byte[] bytes, final int offset, final int count)
- {
- _data.get(bytes, offset, count);
- }
-
- public String readLengthPrefixedUTF() throws JMSException
- {
- try
- {
- short length = readShortImpl();
- if(length == 0)
- {
- return "";
- }
- else
- {
- _charsetDecoder.reset();
- ByteBuffer encodedString = _data.slice();
- encodedString.limit(length);
- _data.position(_data.position()+length);
- CharBuffer string = _charsetDecoder.decode(encodedString);
-
- return string.toString();
- }
- }
- catch(CharacterCodingException e)
- {
- JMSException jmse = new JMSException("Error decoding byte stream as a UTF8 string: " + e);
- jmse.setLinkedException(e);
- jmse.initCause(e);
- throw jmse;
- }
- }
-}
diff --git a/java/client/src/main/java/org/apache/qpid/client/message/TypedBytesContentWriter.java b/java/client/src/main/java/org/apache/qpid/client/message/TypedBytesContentWriter.java
deleted file mode 100644
index 7c91db3a32..0000000000
--- a/java/client/src/main/java/org/apache/qpid/client/message/TypedBytesContentWriter.java
+++ /dev/null
@@ -1,370 +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 javax.jms.MessageFormatException;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetEncoder;
-
-class TypedBytesContentWriter implements TypedBytesCodes
-{
- private final ByteArrayOutputStream _baos = new ByteArrayOutputStream();
- private final DataOutputStream _data = new DataOutputStream(_baos);
- private static final Charset UTF8 = Charset.forName("UTF-8");
-
- protected void writeTypeDiscriminator(byte type) throws JMSException
- {
- try
- {
- _data.writeByte(type);
- }
- catch (IOException e)
- {
- throw handle(e);
- }
- }
-
- private JMSException handle(final IOException e)
- {
- JMSException jmsEx = new JMSException("Unable to write value: " + e.getMessage());
- jmsEx.setLinkedException(e);
- return jmsEx;
- }
-
-
- protected void writeBoolean(boolean b) throws JMSException
- {
- writeTypeDiscriminator(BOOLEAN_TYPE);
- writeBooleanImpl(b);
- }
-
- public void writeBooleanImpl(final boolean b) throws JMSException
- {
- try
- {
- _data.writeByte(b ? (byte) 1 : (byte) 0);
- }
- catch (IOException e)
- {
- throw handle(e);
- }
- }
-
- protected void writeByte(byte b) throws JMSException
- {
- writeTypeDiscriminator(BYTE_TYPE);
- writeByteImpl(b);
- }
-
- public void writeByteImpl(final byte b) throws JMSException
- {
- try
- {
- _data.writeByte(b);
- }
- catch (IOException e)
- {
- throw handle(e);
- }
- }
-
- protected void writeShort(short i) throws JMSException
- {
- writeTypeDiscriminator(SHORT_TYPE);
- writeShortImpl(i);
- }
-
- public void writeShortImpl(final short i) throws JMSException
- {
- try
- {
- _data.writeShort(i);
- }
- catch (IOException e)
- {
- throw handle(e);
- }
- }
-
- protected void writeChar(char c) throws JMSException
- {
- writeTypeDiscriminator(CHAR_TYPE);
- writeCharImpl(c);
- }
-
- public void writeCharImpl(final char c) throws JMSException
- {
- try
- {
- _data.writeChar(c);
- }
- catch (IOException e)
- {
- throw handle(e);
- }
- }
-
- protected void writeInt(int i) throws JMSException
- {
- writeTypeDiscriminator(INT_TYPE);
- writeIntImpl(i);
- }
-
- protected void writeIntImpl(int i) throws JMSException
- {
- try
- {
- _data.writeInt(i);
- }
- catch (IOException e)
- {
- throw handle(e);
- }
- }
-
- protected void writeLong(long l) throws JMSException
- {
- writeTypeDiscriminator(LONG_TYPE);
- writeLongImpl(l);
- }
-
- public void writeLongImpl(final long l) throws JMSException
- {
- try
- {
- _data.writeLong(l);
- }
- catch (IOException e)
- {
- throw handle(e);
- }
- }
-
- protected void writeFloat(float v) throws JMSException
- {
- writeTypeDiscriminator(FLOAT_TYPE);
- writeFloatImpl(v);
- }
-
- public void writeFloatImpl(final float v) throws JMSException
- {
- try
- {
- _data.writeFloat(v);
- }
- catch (IOException e)
- {
- throw handle(e);
- }
- }
-
- protected void writeDouble(double v) throws JMSException
- {
- writeTypeDiscriminator(DOUBLE_TYPE);
- writeDoubleImpl(v);
- }
-
- public void writeDoubleImpl(final double v) throws JMSException
- {
- try
- {
- _data.writeDouble(v);
- }
- catch (IOException e)
- {
- throw handle(e);
- }
- }
-
- protected void writeString(String string) throws JMSException
- {
- if (string == null)
- {
- writeTypeDiscriminator(NULL_STRING_TYPE);
- }
- else
- {
- writeTypeDiscriminator(STRING_TYPE);
- writeNullTerminatedStringImpl(string);
- }
- }
-
- protected void writeNullTerminatedStringImpl(String string)
- throws JMSException
- {
- try
- {
- _data.write(string.getBytes(UTF8));
- _data.writeByte((byte) 0);
- }
- catch (IOException e)
- {
- throw handle(e);
- }
-
- }
-
- protected void writeBytes(byte[] bytes) throws JMSException
- {
- writeBytes(bytes, 0, bytes == null ? 0 : bytes.length);
- }
-
- protected void writeBytes(byte[] bytes, int offset, int length) throws JMSException
- {
- writeTypeDiscriminator(BYTEARRAY_TYPE);
- writeBytesImpl(bytes, offset, length);
- }
-
- public void writeBytesImpl(final byte[] bytes, final int offset, final int length) throws JMSException
- {
- try
- {
- if (bytes == null)
- {
- _data.writeInt(-1);
- }
- else
- {
- _data.writeInt(length);
- _data.write(bytes, offset, length);
- }
- }
- catch (IOException e)
- {
- throw handle(e);
- }
- }
-
- public void writeBytesRaw(final byte[] bytes, final int offset, final int length) throws JMSException
- {
- try
- {
- if (bytes != null)
- {
- _data.write(bytes, offset, length);
- }
- }
- catch (IOException e)
- {
- throw handle(e);
- }
- }
-
-
- protected void writeObject(Object object) throws JMSException
- {
- Class clazz;
-
- if (object == null)
- {
- // string handles the output of null values
- clazz = String.class;
- }
- else
- {
- clazz = object.getClass();
- }
-
- if (clazz == Byte.class)
- {
- writeByte((Byte) object);
- }
- else if (clazz == Boolean.class)
- {
- writeBoolean((Boolean) object);
- }
- else if (clazz == byte[].class)
- {
- writeBytes((byte[]) object);
- }
- else if (clazz == Short.class)
- {
- writeShort((Short) object);
- }
- else if (clazz == Character.class)
- {
- writeChar((Character) object);
- }
- else if (clazz == Integer.class)
- {
- writeInt((Integer) object);
- }
- else if (clazz == Long.class)
- {
- writeLong((Long) object);
- }
- else if (clazz == Float.class)
- {
- writeFloat((Float) object);
- }
- else if (clazz == Double.class)
- {
- writeDouble((Double) object);
- }
- else if (clazz == String.class)
- {
- writeString((String) object);
- }
- else
- {
- throw new MessageFormatException("Only primitives plus byte arrays and String are valid types");
- }
- }
-
- public ByteBuffer getData()
- {
- return ByteBuffer.wrap(_baos.toByteArray());
- }
-
- public void writeLengthPrefixedUTF(final String string) throws JMSException
- {
- try
- {
- CharsetEncoder encoder = UTF8.newEncoder();
- java.nio.ByteBuffer encodedString = encoder.encode(CharBuffer.wrap(string));
-
- writeShortImpl((short) encodedString.limit());
- while(encodedString.hasRemaining())
- {
- _data.writeByte(encodedString.get());
- }
- }
- catch (CharacterCodingException e)
- {
- JMSException jmse = new JMSException("Unable to encode string: " + e);
- jmse.setLinkedException(e);
- jmse.initCause(e);
- throw jmse;
- }
- catch (IOException e)
- {
- throw handle(e);
- }
-
- }
-}
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 ce87a112c9..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
@@ -87,9 +87,9 @@ public class UnprocessedMessage_0_8 extends UnprocessedMessage
public void receiveBody(ContentBody body)
{
- if (body._payload != null)
+ if (body.payload != null)
{
- final long payloadSize = body._payload.length;
+ final long payloadSize = body.payload.remaining();
if (_bodies == null)
{
diff --git a/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java b/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java
index 368ec60525..00503cc650 100644
--- a/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java
+++ b/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java
@@ -27,7 +27,6 @@ import java.util.Map;
import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.client.AMQDestination.Binding;
-import org.apache.qpid.client.messaging.address.Link.Reliability;
import org.apache.qpid.client.messaging.address.Link.Subscription;
import org.apache.qpid.client.messaging.address.Node.ExchangeNode;
import org.apache.qpid.client.messaging.address.Node.QueueNode;
@@ -55,7 +54,7 @@ public class AddressHelper
public static final String EXCLUSIVE = "exclusive";
public static final String AUTO_DELETE = "auto-delete";
public static final String TYPE = "type";
- public static final String ALT_EXCHANGE = "alternate-exchange";
+ public static final String ALT_EXCHANGE = "alt-exchange";
public static final String BINDINGS = "bindings";
public static final String BROWSE = "browse";
public static final String MODE = "mode";
@@ -232,9 +231,14 @@ public class AddressHelper
private boolean getDurability(Map map)
{
- Accessor access = new MapAccessor(map);
- Boolean result = access.getBoolean(DURABLE);
- return (result == null) ? false : result.booleanValue();
+ if (map != null && map.get(DURABLE) != null)
+ {
+ return Boolean.parseBoolean((String)map.get(DURABLE));
+ }
+ else
+ {
+ return false;
+ }
}
/**
@@ -258,7 +262,7 @@ public class AddressHelper
}
}
- public Link getLink() throws Exception
+ public Link getLink()
{
Link link = new Link();
link.setSubscription(new Subscription());
@@ -268,25 +272,6 @@ public class AddressHelper
: linkProps.getBoolean(DURABLE));
link.setName(linkProps.getString(NAME));
- String reliability = linkProps.getString(RELIABILITY);
- if ( reliability != null)
- {
- if (reliability.equalsIgnoreCase("unreliable"))
- {
- link.setReliability(Reliability.UNRELIABLE);
- }
- else if (reliability.equalsIgnoreCase("at-least-once"))
- {
- link.setReliability(Reliability.AT_LEAST_ONCE);
- }
- else
- {
- throw new Exception("The reliability mode '" +
- reliability + "' is not yet supported");
- }
-
- }
-
if (((Map) address.getOptions().get(LINK)).get(CAPACITY) instanceof Map)
{
MapAccessor capacityProps = new MapAccessor(
diff --git a/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java b/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java
index 5f97d625b4..a7d19d1bd5 100644
--- a/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java
+++ b/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java
@@ -20,8 +20,6 @@
*/
package org.apache.qpid.client.messaging.address;
-import static org.apache.qpid.client.messaging.address.Link.Reliability.UNSPECIFIED;
-
import java.util.HashMap;
import java.util.Map;
@@ -31,8 +29,6 @@ public class Link
{
public enum FilterType { SQL92, XQUERY, SUBJECT }
- public enum Reliability { UNRELIABLE, AT_MOST_ONCE, AT_LEAST_ONCE, EXACTLY_ONCE, UNSPECIFIED }
-
protected String name;
protected String _filter;
protected FilterType _filterType = FilterType.SUBJECT;
@@ -42,18 +38,7 @@ public class Link
protected int _producerCapacity = 0;
protected Node node;
protected Subscription subscription;
- protected Reliability reliability = UNSPECIFIED;
- public Reliability getReliability()
- {
- return reliability;
- }
-
- public void setReliability(Reliability reliability)
- {
- this.reliability = reliability;
- }
-
public Node getNode()
{
return node;
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 284954edba..eb5af119b2 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
@@ -20,9 +20,7 @@
*/
package org.apache.qpid.client.protocol;
-import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.OutputStream;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@@ -30,8 +28,10 @@ import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
+import org.apache.mina.filter.codec.ProtocolCodecException;
import org.apache.qpid.AMQConnectionClosedException;
import org.apache.qpid.AMQDisconnectedException;
import org.apache.qpid.AMQException;
@@ -46,7 +46,6 @@ 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.configuration.ClientProperties;
import org.apache.qpid.framing.AMQBody;
import org.apache.qpid.framing.AMQDataBlock;
import org.apache.qpid.framing.AMQFrame;
@@ -58,13 +57,16 @@ import org.apache.qpid.framing.HeartbeatBody;
import org.apache.qpid.framing.MethodRegistry;
import org.apache.qpid.framing.ProtocolInitiation;
import org.apache.qpid.framing.ProtocolVersion;
+import org.apache.qpid.jms.BrokerDetails;
+import org.apache.qpid.pool.Job;
+import org.apache.qpid.pool.ReferenceCountingExecutorService;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.protocol.AMQMethodEvent;
import org.apache.qpid.protocol.AMQMethodListener;
import org.apache.qpid.protocol.ProtocolEngine;
import org.apache.qpid.thread.Threading;
-import org.apache.qpid.transport.Sender;
-import org.apache.qpid.transport.network.NetworkConnection;
+import org.apache.qpid.transport.NetworkDriver;
+import org.apache.qpid.transport.network.io.IoTransport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -162,22 +164,20 @@ public class AMQProtocolHandler implements ProtocolEngine
private FailoverException _lastFailoverException;
/** Defines the default timeout to use for synchronous protocol commands. */
- private final long DEFAULT_SYNC_TIMEOUT = Long.getLong(ClientProperties.QPID_SYNC_OP_TIMEOUT,
- Long.getLong(ClientProperties.AMQJ_DEFAULT_SYNCWRITE_TIMEOUT,
- ClientProperties.DEFAULT_SYNC_OPERATION_TIMEOUT));
+ private final long DEFAULT_SYNC_TIMEOUT = Long.getLong("amqj.default_syncwrite_timeout", 1000 * 30);
/** Object to lock on when changing the latch */
private Object _failoverLatchChange = new Object();
private AMQCodecFactory _codecFactory;
-
+ private Job _readJob;
+ private Job _writeJob;
+ private ReferenceCountingExecutorService _poolReference = ReferenceCountingExecutorService.getInstance();
+ private NetworkDriver _networkDriver;
private ProtocolVersion _suggestedProtocolVersion;
private long _writtenBytes;
private long _readBytes;
- private NetworkConnection _network;
- private Sender<ByteBuffer> _sender;
-
/**
* Creates a new protocol handler, associated with the specified client connection instance.
*
@@ -189,10 +189,43 @@ public class AMQProtocolHandler implements ProtocolEngine
_protocolSession = new AMQProtocolSession(this, _connection);
_stateManager = new AMQStateManager(_protocolSession);
_codecFactory = new AMQCodecFactory(false, _protocolSession);
+ _poolReference.setThreadFactory(new ThreadFactory()
+ {
+
+ public Thread newThread(final Runnable runnable)
+ {
+ try
+ {
+ return Threading.getThreadFactory().createThread(runnable);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Failed to create thread", e);
+ }
+ }
+ });
+ _readJob = new Job(_poolReference, Job.MAX_JOB_EVENTS, true);
+ _writeJob = new Job(_poolReference, Job.MAX_JOB_EVENTS, false);
+ _poolReference.acquireExecutorService();
_failoverHandler = new FailoverHandler(this);
}
/**
+ * 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(),
+ brokerDetail.getBooleanProperty(BrokerDetails.OPTIONS_SSL));
+ _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
@@ -282,7 +315,7 @@ public class AMQProtocolHandler implements ProtocolEngine
// failover:
HeartbeatDiagnostics.timeout();
_logger.warn("Timed out while waiting for heartbeat from peer.");
- _network.close();
+ _networkDriver.close();
}
public void writerIdle()
@@ -304,12 +337,22 @@ public class AMQProtocolHandler implements ProtocolEngine
{
_logger.info("Exception caught therefore going to attempt failover: " + cause, cause);
// this will attempt failover
- _network.close();
+ _networkDriver.close();
closed();
}
else
{
+
+ if (cause instanceof ProtocolCodecException)
+ {
+ _logger.info("Protocol Exception caught NOT going to attempt failover as " +
+ "cause isn't AMQConnectionClosedException: " + cause, cause);
+
+ AMQException amqe = new AMQException("Protocol handler error: " + cause, cause);
+ propagateExceptionToAllWaiters(amqe);
+ }
_connection.exceptionReceived(cause);
+
}
// FIXME Need to correctly handle other exceptions. Things like ...
@@ -403,63 +446,76 @@ public class AMQProtocolHandler implements ProtocolEngine
public void received(ByteBuffer msg)
{
- _readBytes += msg.remaining();
try
{
+ _readBytes += msg.remaining();
final ArrayList<AMQDataBlock> dataBlocks = _codecFactory.getDecoder().decodeBuffer(msg);
- // Decode buffer
-
- for (AMQDataBlock message : dataBlocks)
+ Job.fireAsynchEvent(_poolReference.getPool(), _readJob, new Runnable()
{
- if (PROTOCOL_DEBUG)
- {
- _protocolLogger.info(String.format("RECV: [%s] %s", this, message));
- }
+ public void run()
+ {
+ // Decode buffer
- if(message instanceof AMQFrame)
+ for (AMQDataBlock message : dataBlocks)
{
- final boolean debug = _logger.isDebugEnabled();
- final long msgNumber = ++_messageReceivedCount;
- if (debug && ((msgNumber % 1000) == 0))
+ try
{
- _logger.debug("Received " + _messageReceivedCount + " protocol messages");
+ if (PROTOCOL_DEBUG)
+ {
+ _protocolLogger.info(String.format("RECV: [%s] %s", this, message));
+ }
+
+ if(message instanceof AMQFrame)
+ {
+ final boolean debug = _logger.isDebugEnabled();
+ final long msgNumber = ++_messageReceivedCount;
+
+ if (debug && ((msgNumber % 1000) == 0))
+ {
+ _logger.debug("Received " + _messageReceivedCount + " protocol messages");
+ }
+
+ AMQFrame frame = (AMQFrame) message;
+
+ final AMQBody bodyFrame = frame.getBodyFrame();
+
+ HeartbeatDiagnostics.received(bodyFrame instanceof HeartbeatBody);
+
+ bodyFrame.handle(frame.getChannel(), _protocolSession);
+
+ _connection.bytesReceived(_readBytes);
+ }
+ else if (message instanceof ProtocolInitiation)
+ {
+ // We get here if the server sends a response to our initial protocol header
+ // suggesting an alternate ProtocolVersion; the server will then close the
+ // connection.
+ ProtocolInitiation protocolInit = (ProtocolInitiation) message;
+ _suggestedProtocolVersion = protocolInit.checkVersion();
+ _logger.info("Broker suggested using protocol version:" + _suggestedProtocolVersion);
+
+ // get round a bug in old versions of qpid whereby the connection is not closed
+ _stateManager.changeState(AMQState.CONNECTION_CLOSED);
+ }
+ }
+ catch (Exception e)
+ {
+ _logger.error("Exception processing frame", e);
+ propagateExceptionToFrameListeners(e);
+ exception(e);
}
-
- AMQFrame frame = (AMQFrame) message;
-
- final AMQBody bodyFrame = frame.getBodyFrame();
-
- HeartbeatDiagnostics.received(bodyFrame instanceof HeartbeatBody);
-
- bodyFrame.handle(frame.getChannel(), _protocolSession);
-
- _connection.bytesReceived(_readBytes);
- }
- else if (message instanceof ProtocolInitiation)
- {
- // We get here if the server sends a response to our initial protocol header
- // suggesting an alternate ProtocolVersion; the server will then close the
- // connection.
- ProtocolInitiation protocolInit = (ProtocolInitiation) message;
- _suggestedProtocolVersion = protocolInit.checkVersion();
- _logger.info("Broker suggested using protocol version:" + _suggestedProtocolVersion);
-
- // get round a bug in old versions of qpid whereby the connection is not closed
- _stateManager.changeState(AMQState.CONNECTION_CLOSED);
}
}
+ });
}
catch (Exception e)
{
- _logger.error("Exception processing frame", e);
propagateExceptionToFrameListeners(e);
exception(e);
}
-
-
}
public void methodBodyReceived(final int channelId, final AMQBody bodyFrame)
@@ -514,13 +570,28 @@ public class AMQProtocolHandler implements ProtocolEngine
return getStateManager().createWaiter(states);
}
- public synchronized void writeFrame(AMQDataBlock frame)
+ /**
+ * Convenience method that writes a frame to the protocol session. Equivalent to calling
+ * getProtocolSession().write().
+ *
+ * @param frame the frame to write
+ */
+ public void writeFrame(AMQDataBlock frame)
{
- final ByteBuffer buf = asByteBuffer(frame);
- _writtenBytes += buf.remaining();
- _sender.send(buf);
- _sender.flush();
+ writeFrame(frame, false);
+ }
+ public void writeFrame(AMQDataBlock frame, boolean wait)
+ {
+ final ByteBuffer buf = frame.toNioByteBuffer();
+ _writtenBytes += buf.remaining();
+ Job.fireAsynchEvent(_poolReference.getPool(), _writeJob, new Runnable()
+ {
+ public void run()
+ {
+ _networkDriver.send(buf);
+ }
+ });
if (PROTOCOL_DEBUG)
{
_protocolLogger.debug(String.format("SEND: [%s] %s", this, frame));
@@ -537,41 +608,12 @@ public class AMQProtocolHandler implements ProtocolEngine
_connection.bytesSent(_writtenBytes);
- }
-
- private ByteBuffer asByteBuffer(AMQDataBlock block)
- {
- final ByteBuffer buf = ByteBuffer.allocate((int) block.getSize());
-
- try
+ if (wait)
{
- block.writePayload(new DataOutputStream(new OutputStream()
- {
-
-
- @Override
- public void write(int b) throws IOException
- {
- buf.put((byte) b);
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException
- {
- buf.put(b, off, len);
- }
- }));
- }
- catch (IOException e)
- {
- throw new RuntimeException(e);
+ _networkDriver.flush();
}
-
- buf.flip();
- return buf;
}
-
/**
* Convenience method that writes a frame to the protocol session and waits for a particular response. Equivalent to
* calling getProtocolSession().write() then waiting for the response.
@@ -665,23 +707,24 @@ public class AMQProtocolHandler implements ProtocolEngine
* <p/>If a failover exception occurs whilst closing the connection it is ignored, as the connection is closed
* anyway.
*
- * @param timeout The timeout to wait for an acknowledgment to the close request.
+ * @param timeout The timeout to wait for an acknowledgement to the close request.
*
* @throws AMQException If the close fails for any reason.
*/
public void closeConnection(long timeout) throws AMQException
{
+ ConnectionCloseBody body = _protocolSession.getMethodRegistry().createConnectionCloseBody(AMQConstant.REPLY_SUCCESS.getCode(), // replyCode
+ new AMQShortString("JMS client is closing the connection."), 0, 0);
+
+ final AMQFrame frame = body.generateFrame(0);
+
+ //If the connection is already closed then don't do a syncWrite
if (!getStateManager().getCurrentState().equals(AMQState.CONNECTION_CLOSED))
{
- // Connection is already closed then don't do a syncWrite
try
{
- final ConnectionCloseBody body = _protocolSession.getMethodRegistry().createConnectionCloseBody(AMQConstant.REPLY_SUCCESS.getCode(), // replyCode
- new AMQShortString("JMS client is closing the connection."), 0, 0);
- final AMQFrame frame = body.generateFrame(0);
-
syncWrite(frame, ConnectionCloseOkBody.class, timeout);
- _network.close();
+ _networkDriver.close();
closed();
}
catch (AMQTimeoutException e)
@@ -690,9 +733,10 @@ public class AMQProtocolHandler implements ProtocolEngine
}
catch (FailoverException e)
{
- _logger.debug("FailoverException interrupted connection close, ignoring as connection closed anyway.");
+ _logger.debug("FailoverException interrupted connection close, ignoring as connection close anyway.");
}
}
+ _poolReference.releaseExecutorService();
}
/** @return the number of bytes read from this protocol session */
@@ -800,23 +844,17 @@ public class AMQProtocolHandler implements ProtocolEngine
public SocketAddress getRemoteAddress()
{
- return _network.getRemoteAddress();
+ return _networkDriver.getRemoteAddress();
}
public SocketAddress getLocalAddress()
{
- return _network.getLocalAddress();
- }
-
- public void setNetworkConnection(NetworkConnection network)
- {
- setNetworkConnection(network, network.getSender());
+ return _networkDriver.getLocalAddress();
}
- public void setNetworkConnection(NetworkConnection network, Sender<ByteBuffer> sender)
+ public void setNetworkDriver(NetworkDriver driver)
{
- _network = network;
- _sender = sender;
+ _networkDriver = driver;
}
/** @param delay delay in seconds (not ms) */
@@ -824,15 +862,15 @@ public class AMQProtocolHandler implements ProtocolEngine
{
if (delay > 0)
{
- _network.setMaxWriteIdle(delay);
- _network.setMaxReadIdle(HeartbeatConfig.CONFIG.getTimeout(delay));
+ getNetworkDriver().setMaxWriteIdle(delay);
+ getNetworkDriver().setMaxReadIdle(HeartbeatConfig.CONFIG.getTimeout(delay));
HeartbeatDiagnostics.init(delay, HeartbeatConfig.CONFIG.getTimeout(delay));
}
}
- public NetworkConnection getNetworkConnection()
+ public NetworkDriver getNetworkDriver()
{
- return _network;
+ return _networkDriver;
}
public ProtocolVersion getSuggestedProtocolVersion()
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 b7253e6e9c..7976760696 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
@@ -20,36 +20,27 @@
*/
package org.apache.qpid.client.protocol;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.jms.JMSException;
import javax.security.sasl.SaslClient;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
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.handler.ClientMethodDispatcherImpl;
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.framing.AMQDataBlock;
-import org.apache.qpid.framing.AMQMethodBody;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.ContentBody;
-import org.apache.qpid.framing.ContentHeaderBody;
-import org.apache.qpid.framing.HeartbeatBody;
-import org.apache.qpid.framing.MethodDispatcher;
-import org.apache.qpid.framing.MethodRegistry;
-import org.apache.qpid.framing.ProtocolInitiation;
-import org.apache.qpid.framing.ProtocolVersion;
+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.transport.TransportException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.qpid.client.handler.ClientMethodDispatcherImpl;
/**
* Wrapper for protocol session that provides type-safe access to session attributes. <p/> The underlying protocol
@@ -157,6 +148,16 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession
return getAMQConnection().getVirtualHost();
}
+ public String getUsername()
+ {
+ return getAMQConnection().getUsername();
+ }
+
+ public String getPassword()
+ {
+ return getAMQConnection().getPassword();
+ }
+
public SaslClient getSaslClient()
{
return _saslClient;
@@ -298,11 +299,22 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession
return _connection.getSession(channelId);
}
+ /**
+ * Convenience method that writes a frame to the protocol session. Equivalent to calling
+ * getProtocolSession().write().
+ *
+ * @param frame the frame to write
+ */
public void writeFrame(AMQDataBlock frame)
{
_protocolHandler.writeFrame(frame);
}
+ public void writeFrame(AMQDataBlock frame, boolean wait)
+ {
+ _protocolHandler.writeFrame(frame, wait);
+ }
+
/**
* Starts the process of closing a session
*
@@ -363,15 +375,7 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession
public void closeProtocolSession() throws AMQException
{
- try
- {
- _protocolHandler.getNetworkConnection().close();
- }
- catch(TransportException e)
- {
- //ignore such exceptions, they were already logged
- //and this is a forcible close.
- }
+ _protocolHandler.closeConnection(0);
}
public void failover(String host, int port)
diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/ProtocolBufferMonitorFilter.java b/java/client/src/main/java/org/apache/qpid/client/protocol/ProtocolBufferMonitorFilter.java
new file mode 100644
index 0000000000..bbd0a7b144
--- /dev/null
+++ b/java/client/src/main/java/org/apache/qpid/client/protocol/ProtocolBufferMonitorFilter.java
@@ -0,0 +1,115 @@
+/*
+ *
+ * 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.protocol;
+
+import org.apache.mina.common.IoFilterAdapter;
+import org.apache.mina.common.IoSession;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A MINA filter that monitors the numbers of messages pending to be sent by MINA. It outputs a message
+ * when a threshold has been exceeded, and has a frequency configuration so that messages are not output
+ * too often.
+ *
+ */
+public class ProtocolBufferMonitorFilter extends IoFilterAdapter
+{
+ private static final Logger _logger = LoggerFactory.getLogger(ProtocolBufferMonitorFilter.class);
+
+ public static final long DEFAULT_FREQUENCY = 5000;
+
+ public static final int DEFAULT_THRESHOLD = 3000;
+
+ private int _bufferedMessages = 0;
+
+ private int _threshold;
+
+ private long _lastMessageOutputTime;
+
+ private long _outputFrequencyInMillis;
+
+ public ProtocolBufferMonitorFilter()
+ {
+ _threshold = DEFAULT_THRESHOLD;
+ _outputFrequencyInMillis = DEFAULT_FREQUENCY;
+ }
+
+ public ProtocolBufferMonitorFilter(int threshold, long frequency)
+ {
+ _threshold = threshold;
+ _outputFrequencyInMillis = frequency;
+ }
+
+ public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception
+ {
+ _bufferedMessages++;
+ if (_bufferedMessages > _threshold)
+ {
+ long now = System.currentTimeMillis();
+ if ((now - _lastMessageOutputTime) > _outputFrequencyInMillis)
+ {
+ _logger.warn("Protocol message buffer exceeded threshold of " + _threshold + ". Current backlog: "
+ + _bufferedMessages);
+ _lastMessageOutputTime = now;
+ }
+ }
+
+ nextFilter.messageReceived(session, message);
+ }
+
+ public void messageSent(NextFilter nextFilter, IoSession session, Object message) throws Exception
+ {
+ _bufferedMessages--;
+ nextFilter.messageSent(session, message);
+ }
+
+ public int getBufferedMessages()
+ {
+ return _bufferedMessages;
+ }
+
+ public int getThreshold()
+ {
+ return _threshold;
+ }
+
+ public void setThreshold(int threshold)
+ {
+ _threshold = threshold;
+ }
+
+ public long getOutputFrequencyInMillis()
+ {
+ return _outputFrequencyInMillis;
+ }
+
+ public void setOutputFrequencyInMillis(long outputFrequencyInMillis)
+ {
+ _outputFrequencyInMillis = outputFrequencyInMillis;
+ }
+
+ public long getLastMessageOutputTime()
+ {
+ return _lastMessageOutputTime;
+ }
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java b/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java
index 67dd1a58b6..fbca444208 100644
--- a/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java
+++ b/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java
@@ -22,9 +22,9 @@ package org.apache.qpid.client.security;
import javax.security.auth.callback.CallbackHandler;
-import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.client.protocol.AMQProtocolSession;
public interface AMQCallbackHandler extends CallbackHandler
{
- void initialise(ConnectionURL connectionURL);
+ void initialise(AMQProtocolSession protocolSession);
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.java b/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.java
index 14bae68561..140cbdeb75 100644
--- a/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.java
+++ b/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.java
@@ -20,22 +20,17 @@
*/
package org.apache.qpid.client.security;
+import org.apache.qpid.util.FileUtils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.io.IOException;
import java.io.InputStream;
-import java.util.Collection;
-import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-
-import org.apache.qpid.util.FileUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* CallbackHandlerRegistry is a registry for call back handlers for user authentication and interaction during user
@@ -47,7 +42,7 @@ import org.slf4j.LoggerFactory;
* "amp.callbackhandler.properties". The format of the properties file is:
*
* <p/><pre>
- * CallbackHanlder.n.mechanism=fully.qualified.class.name where n is an ordinal
+ * CallbackHanlder.mechanism=fully.qualified.class.name
* </pre>
*
* <p/>Where mechanism is an IANA-registered mechanism name and the fully qualified class name refers to a
@@ -71,15 +66,51 @@ public class CallbackHandlerRegistry
public static final String DEFAULT_RESOURCE_NAME = "org/apache/qpid/client/security/CallbackHandlerRegistry.properties";
/** A static reference to the singleton instance of this registry. */
- private static final CallbackHandlerRegistry _instance;
+ private static CallbackHandlerRegistry _instance = new CallbackHandlerRegistry();
/** Holds a map from SASL mechanism names to call back handlers. */
- private Map<String, Class<AMQCallbackHandler>> _mechanismToHandlerClassMap = new HashMap<String, Class<AMQCallbackHandler>>();
+ private Map<String, Class> _mechanismToHandlerClassMap = new HashMap<String, Class>();
+
+ /** Holds a space delimited list of mechanisms that callback handlers exist for. */
+ private String _mechanisms;
+
+ /**
+ * Gets the singleton instance of this registry.
+ *
+ * @return The singleton instance of this registry.
+ */
+ public static CallbackHandlerRegistry getInstance()
+ {
+ return _instance;
+ }
- /** Ordered collection of mechanisms for which callback handlers exist. */
- private Collection<String> _mechanisms;
+ /**
+ * Gets the callback handler class for a given SASL mechanism name.
+ *
+ * @param mechanism The SASL mechanism name.
+ *
+ * @return The callback handler class for the mechanism, or null if none is configured for that mechanism.
+ */
+ public Class getCallbackHandlerClass(String mechanism)
+ {
+ return (Class) _mechanismToHandlerClassMap.get(mechanism);
+ }
- static
+ /**
+ * Gets a space delimited list of supported SASL mechanisms.
+ *
+ * @return A space delimited list of supported SASL mechanisms.
+ */
+ public String getMechanisms()
+ {
+ return _mechanisms;
+ }
+
+ /**
+ * Creates the call back handler registry from its configuration resource or file. This also has the side effect
+ * of configuring and registering the SASL client factory implementations using {@link DynamicSaslRegistrar}.
+ */
+ private CallbackHandlerRegistry()
{
// Register any configured SASL client factories.
DynamicSaslRegistrar.registerSaslProviders();
@@ -89,12 +120,12 @@ public class CallbackHandlerRegistry
FileUtils.openFileOrDefaultResource(filename, DEFAULT_RESOURCE_NAME,
CallbackHandlerRegistry.class.getClassLoader());
- final Properties props = new Properties();
-
try
{
-
+ Properties props = new Properties();
props.load(is);
+ parseProperties(props);
+ _logger.info("Callback handlers available for SASL mechanisms: " + _mechanisms);
}
catch (IOException e)
{
@@ -115,68 +146,32 @@ public class CallbackHandlerRegistry
}
}
}
-
- _instance = new CallbackHandlerRegistry(props);
- _logger.info("Callback handlers available for SASL mechanisms: " + _instance._mechanisms);
-
}
- /**
- * Gets the singleton instance of this registry.
- *
- * @return The singleton instance of this registry.
- */
- public static CallbackHandlerRegistry getInstance()
- {
- return _instance;
- }
-
- public AMQCallbackHandler createCallbackHandler(final String mechanism)
+ /*private InputStream openPropertiesInputStream(String filename)
{
- final Class<AMQCallbackHandler> mechanismClass = _mechanismToHandlerClassMap.get(mechanism);
-
- if (mechanismClass == null)
+ boolean useDefault = true;
+ InputStream is = null;
+ if (filename != null)
{
- throw new IllegalArgumentException("Mechanism " + mechanism + " not known");
+ try
+ {
+ is = new BufferedInputStream(new FileInputStream(new File(filename)));
+ useDefault = false;
+ }
+ catch (FileNotFoundException e)
+ {
+ _logger.error("Unable to read from file " + filename + ": " + e, e);
+ }
}
- try
- {
- return mechanismClass.newInstance();
- }
- catch (InstantiationException e)
- {
- throw new IllegalArgumentException("Unable to create an instance of mechanism " + mechanism, e);
- }
- catch (IllegalAccessException e)
+ if (useDefault)
{
- throw new IllegalArgumentException("Unable to create an instance of mechanism " + mechanism, e);
+ is = CallbackHandlerRegistry.class.getResourceAsStream(DEFAULT_RESOURCE_NAME);
}
- }
- /**
- * Gets collections of supported SASL mechanism names, ordered by preference
- *
- * @return collection of SASL mechanism names.
- */
- public Collection<String> getMechanisms()
- {
- return Collections.unmodifiableCollection(_mechanisms);
- }
-
- /**
- * Creates the call back handler registry from its configuration resource or file.
- *
- * This also has the side effect of configuring and registering the SASL client factory
- * implementations using {@link DynamicSaslRegistrar}.
- *
- * This constructor is default protection to allow for effective unit testing. Clients must use
- * {@link #getInstance()} to obtain the singleton instance.
- */
- CallbackHandlerRegistry(final Properties props)
- {
- parseProperties(props);
- }
+ return is;
+ }*/
/**
* Scans the specified properties as a mapping from IANA registered SASL mechanism to call back handler
@@ -188,20 +183,20 @@ public class CallbackHandlerRegistry
*/
private void parseProperties(Properties props)
{
-
- final Map<Integer, String> mechanisms = new TreeMap<Integer, String>();
-
Enumeration e = props.propertyNames();
while (e.hasMoreElements())
{
- final String propertyName = (String) e.nextElement();
- final String[] parts = propertyName.split("\\.", 2);
+ String propertyName = (String) e.nextElement();
+ int period = propertyName.indexOf(".");
+ if (period < 0)
+ {
+ _logger.warn("Unable to parse property " + propertyName + " when configuring SASL providers");
- checkPropertyNameFormat(propertyName, parts);
+ continue;
+ }
- final String mechanism = parts[0];
- final int ordinal = getPropertyOrdinal(propertyName, parts);
- final String className = props.getProperty(propertyName);
+ String mechanism = propertyName.substring(period + 1);
+ String className = props.getProperty(propertyName);
Class clazz = null;
try
{
@@ -210,11 +205,20 @@ public class CallbackHandlerRegistry
{
_logger.warn("SASL provider " + clazz + " does not implement " + AMQCallbackHandler.class
+ ". Skipping");
+
continue;
}
- _mechanismToHandlerClassMap.put(mechanism, clazz);
- mechanisms.put(ordinal, mechanism);
+ _mechanismToHandlerClassMap.put(mechanism, clazz);
+ if (_mechanisms == null)
+ {
+ _mechanisms = mechanism;
+ }
+ else
+ {
+ // one time cost
+ _mechanisms = _mechanisms + " " + mechanism;
+ }
}
catch (ClassNotFoundException ex)
{
@@ -223,91 +227,5 @@ public class CallbackHandlerRegistry
continue;
}
}
-
- _mechanisms = mechanisms.values(); // order guaranteed by keys of treemap (i.e. our ordinals)
-
-
- }
-
- private void checkPropertyNameFormat(final String propertyName, final String[] parts)
- {
- if (parts.length != 2)
- {
- throw new IllegalArgumentException("Unable to parse property " + propertyName + " when configuring SASL providers");
- }
- }
-
- private int getPropertyOrdinal(final String propertyName, final String[] parts)
- {
- try
- {
- return Integer.parseInt(parts[1]);
- }
- catch(NumberFormatException nfe)
- {
- throw new IllegalArgumentException("Unable to parse property " + propertyName + " when configuring SASL providers", nfe);
- }
- }
-
- /**
- * Selects a SASL mechanism that is mutually available to both parties. If more than one
- * mechanism is mutually available the one appearing first (by ordinal) will be returned.
- *
- * @param peerMechanismList space separated list of mechanisms
- * @return selected mechanism, or null if none available
- */
- public String selectMechanism(final String peerMechanismList)
- {
- final Set<String> peerList = mechListToSet(peerMechanismList);
-
- return selectMechInternal(peerList, Collections.<String>emptySet());
- }
-
- /**
- * Selects a SASL mechanism that is mutually available to both parties.
- *
- * @param peerMechanismList space separated list of mechanisms
- * @param restrictionList space separated list of mechanisms
- * @return selected mechanism, or null if none available
- */
- public String selectMechanism(final String peerMechanismList, final String restrictionList)
- {
- final Set<String> peerList = mechListToSet(peerMechanismList);
- final Set<String> restrictionSet = mechListToSet(restrictionList);
-
- return selectMechInternal(peerList, restrictionSet);
- }
-
- private String selectMechInternal(final Set<String> peerSet, final Set<String> restrictionSet)
- {
- for (final String mech : _mechanisms)
- {
- if (peerSet.contains(mech))
- {
- if (restrictionSet.isEmpty() || restrictionSet.contains(mech))
- {
- return mech;
- }
- }
- }
-
- return null;
- }
-
- private Set<String> mechListToSet(final String mechanismList)
- {
- if (mechanismList == null)
- {
- return Collections.emptySet();
- }
-
- final StringTokenizer tokenizer = new StringTokenizer(mechanismList, " ");
- final Set<String> mechanismSet = new HashSet<String>(tokenizer.countTokens());
- while (tokenizer.hasMoreTokens())
- {
- mechanismSet.add(tokenizer.nextToken());
- }
- return Collections.unmodifiableSet(mechanismSet);
}
-
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties b/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties
index b04a756e80..1fcfde3579 100644
--- a/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties
+++ b/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties
@@ -16,17 +16,7 @@
# specific language governing permissions and limitations
# under the License.
#
-
-#
-# Format:
-# <mechanism name>.ordinal=<implementation>
-#
-# @see CallbackHandlerRegistry
-#
-
-EXTERNAL.1=org.apache.qpid.client.security.UsernamePasswordCallbackHandler
-GSSAPI.2=org.apache.qpid.client.security.UsernamePasswordCallbackHandler
-CRAM-MD5-HASHED.3=org.apache.qpid.client.security.UsernameHashedPasswordCallbackHandler
-CRAM-MD5.4=org.apache.qpid.client.security.UsernamePasswordCallbackHandler
-AMQPLAIN.5=org.apache.qpid.client.security.UsernamePasswordCallbackHandler
-PLAIN.6=org.apache.qpid.client.security.UsernamePasswordCallbackHandler
+CallbackHandler.CRAM-MD5-HASHED=org.apache.qpid.client.security.UsernameHashedPasswordCallbackHandler
+CallbackHandler.CRAM-MD5=org.apache.qpid.client.security.UsernamePasswordCallbackHandler
+CallbackHandler.AMQPLAIN=org.apache.qpid.client.security.UsernamePasswordCallbackHandler
+CallbackHandler.PLAIN=org.apache.qpid.client.security.UsernamePasswordCallbackHandler
diff --git a/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties b/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
index b903208927..1bff43142b 100644
--- a/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
+++ b/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
@@ -18,4 +18,3 @@
#
AMQPLAIN=org.apache.qpid.client.security.amqplain.AmqPlainSaslClientFactory
CRAM-MD5-HASHED=org.apache.qpid.client.security.crammd5hashed.CRAMMD5HashedSaslClientFactory
-ANONYMOUS=org.apache.qpid.client.security.anonymous.AnonymousSaslClientFactory
diff --git a/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java b/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
index 6ec83f0a23..66176dac3c 100644
--- a/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
+++ b/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
@@ -20,29 +20,30 @@
*/
package org.apache.qpid.client.security;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
+import org.apache.qpid.client.protocol.AMQProtocolSession;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
-import org.apache.qpid.jms.ConnectionURL;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
public class UsernameHashedPasswordCallbackHandler implements AMQCallbackHandler
{
- private ConnectionURL _connectionURL;
+ private static final Logger _logger = LoggerFactory.getLogger(UsernameHashedPasswordCallbackHandler.class);
- /**
- * @see org.apache.qpid.client.security.AMQCallbackHandler#initialise(org.apache.qpid.jms.ConnectionURL)
- */
- @Override
- public void initialise(ConnectionURL connectionURL)
+ private AMQProtocolSession _protocolSession;
+
+ public void initialise(AMQProtocolSession protocolSession)
{
- _connectionURL = connectionURL;
+ _protocolSession = protocolSession;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
@@ -52,13 +53,13 @@ public class UsernameHashedPasswordCallbackHandler implements AMQCallbackHandler
Callback cb = callbacks[i];
if (cb instanceof NameCallback)
{
- ((NameCallback) cb).setName(_connectionURL.getUsername());
+ ((NameCallback) cb).setName(_protocolSession.getUsername());
}
else if (cb instanceof PasswordCallback)
{
try
{
- ((PasswordCallback) cb).setPassword(getHash(_connectionURL.getPassword()));
+ ((PasswordCallback) cb).setPassword(getHash(_protocolSession.getPassword()));
}
catch (NoSuchAlgorithmException e)
{
@@ -98,5 +99,4 @@ public class UsernameHashedPasswordCallbackHandler implements AMQCallbackHandler
return hash;
}
-
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java b/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java
index ad088722c8..c50c62710f 100644
--- a/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java
+++ b/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java
@@ -27,19 +27,15 @@ import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
-import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.client.protocol.AMQProtocolSession;
public class UsernamePasswordCallbackHandler implements AMQCallbackHandler
{
- private ConnectionURL _connectionURL;
+ private AMQProtocolSession _protocolSession;
- /**
- * @see org.apache.qpid.client.security.AMQCallbackHandler#initialise(org.apache.qpid.jms.ConnectionURL)
- */
- @Override
- public void initialise(final ConnectionURL connectionURL)
+ public void initialise(AMQProtocolSession protocolSession)
{
- _connectionURL = connectionURL;
+ _protocolSession = protocolSession;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
@@ -49,11 +45,11 @@ public class UsernamePasswordCallbackHandler implements AMQCallbackHandler
Callback cb = callbacks[i];
if (cb instanceof NameCallback)
{
- ((NameCallback)cb).setName(_connectionURL.getUsername());
+ ((NameCallback)cb).setName(_protocolSession.getUsername());
}
else if (cb instanceof PasswordCallback)
{
- ((PasswordCallback)cb).setPassword(_connectionURL.getPassword().toCharArray());
+ ((PasswordCallback)cb).setPassword(_protocolSession.getPassword().toCharArray());
}
else
{
@@ -61,5 +57,4 @@ public class UsernamePasswordCallbackHandler implements AMQCallbackHandler
}
}
}
-
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClient.java b/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClient.java
deleted file mode 100644
index 0f56b2ef6c..0000000000
--- a/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClient.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.client.security.anonymous;
-
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslException;
-
-public class AnonymousSaslClient implements SaslClient
-{
- public String getMechanismName() {
- return "ANONYMOUS";
- }
- public boolean hasInitialResponse() {
- return true;
- }
- public byte[] evaluateChallenge(byte[] challenge) throws SaslException {
- return new byte[0];
- }
- public boolean isComplete() {
- return true;
- }
- public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
- {
- throw new IllegalStateException("No security layer supported");
- }
- public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
- {
- throw new IllegalStateException("No security layer supported");
- }
- public Object getNegotiatedProperty(String propName) {
- return null;
- }
- public void dispose() throws SaslException {}
-}
diff --git a/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClientFactory.java b/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClientFactory.java
deleted file mode 100644
index de698f87c6..0000000000
--- a/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClientFactory.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.client.security.anonymous;
-
-import java.util.Arrays;
-import java.util.Map;
-
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslClientFactory;
-import javax.security.sasl.SaslException;
-import javax.security.auth.callback.CallbackHandler;
-
-public class AnonymousSaslClientFactory implements SaslClientFactory
-{
- public SaslClient createSaslClient(String[] mechanisms, String authId,
- String protocol, String server,
- Map props, CallbackHandler cbh) throws SaslException
- {
- if (Arrays.asList(mechanisms).contains("ANONYMOUS")) {
- return new AnonymousSaslClient();
- } else {
- return null;
- }
- }
- public String[] getMechanismNames(Map props)
- {
- if (props == null || props.isEmpty()) {
- return new String[]{"ANONYMOUS"};
- } else {
- return new String[0];
- }
- }
-}
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 0d6fc727c1..9c7d62670c 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
@@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory;
import java.util.Set;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.io.IOException;
/**
* The state manager is responsible for managing the state of the protocol session. <p/>
@@ -47,7 +48,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
*
* 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 asynchronous errors that occur can be delivered to the correct waiters.
+ * that any asynchrous errors that occur can be delivered to the correct waiters.
*/
public class AMQStateManager implements AMQMethodListener
{
@@ -83,10 +84,7 @@ public class AMQStateManager implements AMQMethodListener
public AMQState getCurrentState()
{
- synchronized (_stateLock)
- {
- return _currentState;
- }
+ return _currentState;
}
public void changeState(AMQState newState)
@@ -116,7 +114,7 @@ public class AMQStateManager implements AMQMethodListener
}
/**
- * Setting of the ProtocolSession will be required when Failover has been successfully completed.
+ * 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.
@@ -133,9 +131,9 @@ public class AMQStateManager implements AMQMethodListener
}
/**
- * Propagate error to waiters
+ * Propogate error to waiters
*
- * @param error The error to propagate.
+ * @param error The error to propogate.
*/
public void error(Exception error)
{
@@ -179,7 +177,7 @@ public class AMQStateManager implements AMQMethodListener
}
/**
- * Create and add a new waiter to the notification list.
+ * 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.
*
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 732480e1c9..79f438d35d 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
@@ -34,7 +34,7 @@ import java.util.Set;
*
* On construction the current state and a set of States to await for is provided.
*
- * When await() is called the state at construction is compared against the awaitStates. If the state at construction is
+ * 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.
@@ -48,9 +48,9 @@ public class StateWaiter extends BlockingWaiter<AMQState>
{
private static final Logger _logger = LoggerFactory.getLogger(StateWaiter.class);
- private final Set<AMQState> _awaitStates;
- private final AMQState _startState;
- private final AMQStateManager _stateManager;
+ Set<AMQState> _awaitStates;
+ private AMQState _startState;
+ private AMQStateManager _stateManager;
/**
*
@@ -78,9 +78,9 @@ public class StateWaiter extends BlockingWaiter<AMQState>
}
/**
- * Await for the required State to be achieved within the default timeout.
+ * 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 achieved.
+ * @throws AMQException The exception that prevented the required state from being achived.
*/
public AMQState await() throws AMQException
{
@@ -88,13 +88,13 @@ public class StateWaiter extends BlockingWaiter<AMQState>
}
/**
- * Await for the required State to be achieved.
+ * 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 achieved.
+ * @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 achieved.
+ * @throws AMQException The exception that prevented the required state from being achived.
*/
public AMQState await(long timeout) throws AMQException
{
diff --git a/java/client/src/main/java/org/apache/qpid/client/transport/ClientConnectionDelegate.java b/java/client/src/main/java/org/apache/qpid/client/transport/ClientConnectionDelegate.java
deleted file mode 100644
index 1b483f6948..0000000000
--- a/java/client/src/main/java/org/apache/qpid/client/transport/ClientConnectionDelegate.java
+++ /dev/null
@@ -1,168 +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.transport;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslException;
-
-import org.apache.qpid.client.security.AMQCallbackHandler;
-import org.apache.qpid.client.security.CallbackHandlerRegistry;
-import org.apache.qpid.jms.ConnectionURL;
-import org.apache.qpid.transport.ClientDelegate;
-import org.apache.qpid.transport.Connection;
-import org.apache.qpid.transport.ConnectionException;
-import org.apache.qpid.transport.ConnectionOpenOk;
-import org.apache.qpid.transport.ConnectionSettings;
-import org.apache.qpid.transport.util.Logger;
-import org.apache.qpid.util.Strings;
-import org.ietf.jgss.GSSContext;
-import org.ietf.jgss.GSSException;
-import org.ietf.jgss.GSSManager;
-import org.ietf.jgss.GSSName;
-import org.ietf.jgss.Oid;
-
-/**
- *
- */
-public class ClientConnectionDelegate extends ClientDelegate
-{
- private static final Logger LOGGER = Logger.get(ClientDelegate.class);
-
- private static final String KRB5_OID_STR = "1.2.840.113554.1.2.2";
- protected static final Oid KRB5_OID;
-
- static
- {
- Oid oid;
- try
- {
- oid = new Oid(KRB5_OID_STR);
- }
- catch (GSSException ignore)
- {
- oid = null;
- }
-
- KRB5_OID = oid;
- }
-
- private final ConnectionURL _connectionURL;
-
- /**
- * @param settings
- * @param connectionURL
- */
- public ClientConnectionDelegate(ConnectionSettings settings, ConnectionURL connectionURL)
- {
- super(settings);
- this._connectionURL = connectionURL;
- }
-
- @Override
- protected SaslClient createSaslClient(List<Object> brokerMechs) throws ConnectionException, SaslException
- {
- final String brokerMechanisms = Strings.join(" ", brokerMechs);
- final String restrictionList = _conSettings.getSaslMechs();
- final String selectedMech = CallbackHandlerRegistry.getInstance().selectMechanism(brokerMechanisms, restrictionList);
- if (selectedMech == null)
- {
- throw new ConnectionException("Client and broker have no SASL mechanisms in common." +
- " Broker allows : " + brokerMechanisms +
- " Client has : " + CallbackHandlerRegistry.getInstance().getMechanisms() +
- " Client restricted itself to : " + (restrictionList != null ? restrictionList : "no restriction"));
- }
-
- Map<String,Object> saslProps = new HashMap<String,Object>();
- if (_conSettings.isUseSASLEncryption())
- {
- saslProps.put(Sasl.QOP, "auth-conf");
- }
-
- final AMQCallbackHandler handler = CallbackHandlerRegistry.getInstance().createCallbackHandler(selectedMech);
- handler.initialise(_connectionURL);
- final SaslClient sc = Sasl.createSaslClient(new String[] {selectedMech}, null, _conSettings.getSaslProtocol(), _conSettings.getSaslServerName(), saslProps, handler);
-
- return sc;
- }
-
- @Override
- public void connectionOpenOk(Connection conn, ConnectionOpenOk ok)
- {
- SaslClient sc = conn.getSaslClient();
- if (sc != null)
- {
- if (sc.getMechanismName().equals("GSSAPI"))
- {
- String id = getKerberosUser();
- if (id != null)
- {
- conn.setUserID(id);
- }
- }
- else if (sc.getMechanismName().equals("EXTERNAL"))
- {
- if (conn.getSecurityLayer() != null)
- {
- conn.setUserID(conn.getSecurityLayer().getUserID());
- }
- }
- }
-
- super.connectionOpenOk(conn, ok);
- }
-
- private String getKerberosUser()
- {
- LOGGER.debug("Obtaining userID from kerberos");
- String service = _conSettings.getSaslProtocol() + "@" + _conSettings.getSaslServerName();
- GSSManager manager = GSSManager.getInstance();
-
- try
- {
- GSSName acceptorName = manager.createName(service,
- GSSName.NT_HOSTBASED_SERVICE, KRB5_OID);
-
- GSSContext secCtx = manager.createContext(acceptorName,
- KRB5_OID,
- null,
- GSSContext.INDEFINITE_LIFETIME);
-
- secCtx.initSecContext(new byte[0], 0, 1);
-
- if (secCtx.getSrcName() != null)
- {
- return secCtx.getSrcName().toString();
- }
-
- }
- catch (GSSException e)
- {
- LOGGER.warn("Unable to retrieve userID from Kerberos due to error",e);
- }
-
- return null;
- }
-}
diff --git a/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java b/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java
new file mode 100644
index 0000000000..1ac8f62e32
--- /dev/null
+++ b/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java
@@ -0,0 +1,90 @@
+/*
+ *
+ * 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.transport;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.SimpleByteBufferAllocator;
+import org.apache.qpid.client.SSLConfiguration;
+import org.apache.qpid.client.protocol.AMQProtocolHandler;
+import org.apache.qpid.jms.BrokerDetails;
+import org.apache.qpid.ssl.SSLContextFactory;
+import org.apache.qpid.transport.network.mina.MINANetworkDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SocketTransportConnection implements ITransportConnection
+{
+ private static final Logger _logger = LoggerFactory.getLogger(SocketTransportConnection.class);
+ private static final int DEFAULT_BUFFER_SIZE = 32 * 1024;
+
+ private SocketConnectorFactory _socketConnectorFactory;
+
+ static interface SocketConnectorFactory
+ {
+ IoConnector newSocketConnector();
+ }
+
+ public SocketTransportConnection(SocketConnectorFactory socketConnectorFactory)
+ {
+ _socketConnectorFactory = socketConnectorFactory;
+ }
+
+ public void connect(AMQProtocolHandler protocolHandler, BrokerDetails brokerDetail) throws IOException
+ {
+ ByteBuffer.setUseDirectBuffers(Boolean.getBoolean("amqj.enableDirectBuffers"));
+
+ // the MINA default is currently to use the pooled allocator although this may change in future
+ // once more testing of the performance of the simple allocator has been done
+ if (!Boolean.getBoolean("amqj.enablePooledAllocator"))
+ {
+ _logger.info("Using SimpleByteBufferAllocator");
+ ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
+ }
+
+ final IoConnector ioConnector = _socketConnectorFactory.newSocketConnector();
+ final InetSocketAddress address;
+
+ if (brokerDetail.getTransport().equals(BrokerDetails.SOCKET))
+ {
+ address = null;
+ }
+ else
+ {
+ address = new InetSocketAddress(brokerDetail.getHost(), brokerDetail.getPort());
+ _logger.info("Attempting connection to " + address);
+ }
+
+ SSLConfiguration sslConfig = protocolHandler.getConnection().getSSLConfiguration();
+ SSLContextFactory sslFactory = null;
+ if (sslConfig != null)
+ {
+ sslFactory = new SSLContextFactory(sslConfig.getKeystorePath(), sslConfig.getKeystorePassword(), sslConfig.getCertType());
+ }
+
+ MINANetworkDriver driver = new MINANetworkDriver(ioConnector);
+ driver.open(brokerDetail.getPort(), address.getAddress(), protocolHandler, null, sslFactory);
+ protocolHandler.setNetworkDriver(driver);
+ }
+}
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
new file mode 100644
index 0000000000..aef3a563af
--- /dev/null
+++ b/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java
@@ -0,0 +1,351 @@
+/*
+ *
+ * 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.transport;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.transport.socket.nio.ExistingSocketConnector;
+import org.apache.mina.transport.socket.nio.MultiThreadSocketConnector;
+import org.apache.mina.transport.socket.nio.SocketConnector;
+import org.apache.mina.transport.vmpipe.VmPipeAcceptor;
+import org.apache.mina.transport.vmpipe.VmPipeAddress;
+import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException;
+import org.apache.qpid.jms.BrokerDetails;
+import org.apache.qpid.protocol.ProtocolEngineFactory;
+import org.apache.qpid.thread.QpidThreadExecutor;
+import org.apache.qpid.transport.network.mina.MINANetworkDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 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
+ * protocol events. <p/> Could be extended in future to support different transport types by turning this into concrete
+ * class/interface combo.
+ */
+public class TransportConnection
+{
+ private static ITransportConnection _instance;
+
+ private static final Map _inVmPipeAddress = new HashMap();
+ private static VmPipeAcceptor _acceptor;
+ private static int _currentInstance = -1;
+ private static int _currentVMPort = -1;
+
+ private static final int TCP = 0;
+ private static final int VM = 1;
+ private static final int SOCKET = 2;
+
+ private static Logger _logger = LoggerFactory.getLogger(TransportConnection.class);
+
+ private static final String DEFAULT_QPID_SERVER = "org.apache.qpid.server.protocol.AMQProtocolEngineFactory";
+
+ private static Map<String, Socket> _openSocketRegister = new ConcurrentHashMap<String, Socket>();
+
+ public static void registerOpenSocket(String socketID, Socket openSocket)
+ {
+ _openSocketRegister.put(socketID, openSocket);
+ }
+
+ public static Socket removeOpenSocket(String socketID)
+ {
+ return _openSocketRegister.remove(socketID);
+ }
+
+ public static synchronized ITransportConnection getInstance(final BrokerDetails details) throws AMQTransportConnectionException
+ {
+ int transport = getTransport(details.getTransport());
+
+ if (transport == -1)
+ {
+ throw new AMQNoTransportForProtocolException(details, null, null);
+ }
+
+ switch (transport)
+ {
+ case SOCKET:
+ return new SocketTransportConnection(new SocketTransportConnection.SocketConnectorFactory()
+ {
+ public IoConnector newSocketConnector()
+ {
+ ExistingSocketConnector connector = new ExistingSocketConnector(1,new QpidThreadExecutor());
+
+ Socket socket = TransportConnection.removeOpenSocket(details.getHost());
+
+ if (socket != null)
+ {
+ _logger.info("Using existing Socket:" + socket);
+
+ ((ExistingSocketConnector) connector).setOpenSocket(socket);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Active Socket must be provided for broker " +
+ "with 'socket://<SocketID>' transport:" + details);
+ }
+ return connector;
+ }
+ });
+ case TCP:
+ return new SocketTransportConnection(new SocketTransportConnection.SocketConnectorFactory()
+ {
+ public IoConnector newSocketConnector()
+ {
+ SocketConnector result;
+ // FIXME - this needs to be sorted to use the new Mina MultiThread SA.
+ if (Boolean.getBoolean("qpidnio"))
+ {
+ _logger.warn("Using Qpid MultiThreaded NIO - " + (System.getProperties().containsKey("qpidnio")
+ ? "Qpid NIO is new default"
+ : "Sysproperty 'qpidnio' is set"));
+ result = new MultiThreadSocketConnector(1, new QpidThreadExecutor());
+ }
+ else
+ {
+ _logger.info("Using Mina NIO");
+ result = new SocketConnector(1, new QpidThreadExecutor()); // non-blocking connector
+ }
+ // Don't have the connector's worker thread wait around for other connections (we only use
+ // one SocketConnector per connection at the moment anyway). This allows short-running
+ // clients (like unit tests) to complete quickly.
+ result.setWorkerTimeout(0);
+ return result;
+ }
+ });
+ case VM:
+ {
+ return getVMTransport(details, Boolean.getBoolean("amqj.AutoCreateVMBroker"));
+ }
+ default:
+ throw new AMQNoTransportForProtocolException(details, "Transport not recognised:" + transport, null);
+ }
+ }
+
+ private static int getTransport(String transport)
+ {
+ if (transport.equals(BrokerDetails.SOCKET))
+ {
+ return SOCKET;
+ }
+
+ if (transport.equals(BrokerDetails.TCP))
+ {
+ return TCP;
+ }
+
+ if (transport.equals(BrokerDetails.VM))
+ {
+ return VM;
+ }
+
+ return -1;
+ }
+
+ private static ITransportConnection getVMTransport(BrokerDetails details, boolean AutoCreate)
+ throws AMQVMBrokerCreationException
+ {
+ int port = details.getPort();
+
+ synchronized (_inVmPipeAddress)
+ {
+ if (!_inVmPipeAddress.containsKey(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);
+ }
+ }
+ }
+
+ return new VmPipeTransportConnection(port);
+ }
+
+ public static void createVMBroker(int port) throws AMQVMBrokerCreationException
+ {
+ synchronized(TransportConnection.class)
+ {
+ if (_acceptor == null)
+ {
+ _acceptor = new VmPipeAcceptor();
+
+ IoServiceConfig config = _acceptor.getDefaultConfig();
+ }
+ }
+ synchronized (_inVmPipeAddress)
+ {
+
+ if (!_inVmPipeAddress.containsKey(port))
+ {
+ _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)
+ {
+ _logger.error("Got IOException.", e);
+
+ // Try and unbind provider
+ try
+ {
+ 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);
+ }
+ catch (IOException justUseFirstException)
+ {
+ 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);
+ }
+ }
+
+ }
+ else
+ {
+ _logger.info("InVM Qpid.AMQP on port " + port + " already exits.");
+ }
+ }
+ }
+
+ private static IoHandlerAdapter createBrokerInstance(int port) throws AMQVMBrokerCreationException
+ {
+ String protocolProviderClass = System.getProperty("amqj.protocolprovider.class", DEFAULT_QPID_SERVER);
+ _logger.info("Creating Qpid protocol provider: " + protocolProviderClass);
+
+ // can't use introspection to get Provider as it is a server class.
+ // need to go straight to IoHandlerAdapter but that requries the queues and exchange from the ApplicationRegistry which we can't access.
+
+ // get right constructor and pass in instancec ID - "port"
+ IoHandlerAdapter provider;
+ try
+ {
+ Class[] cnstr = {Integer.class};
+ Object[] params = {port};
+
+ provider = new MINANetworkDriver();
+ ProtocolEngineFactory engineFactory = (ProtocolEngineFactory) Class.forName(protocolProviderClass).getConstructor(cnstr).newInstance(params);
+ ((MINANetworkDriver) provider).setProtocolEngineFactory(engineFactory, true);
+ // Give the broker a second to create
+ _logger.info("Created VMBroker Instance:" + port);
+ }
+ catch (Exception e)
+ {
+ _logger.info("Unable to create InVM Qpid.AMQP on port " + port + ". Because: " + e.getCause());
+ String because;
+ if (e.getCause() == null)
+ {
+ because = e.toString();
+ }
+ else
+ {
+ because = e.getCause().toString();
+ }
+
+ AMQVMBrokerCreationException amqbce =
+ new AMQVMBrokerCreationException(null, port, because + " Stopped InVM Qpid.AMQP creation", e);
+ throw amqbce;
+ }
+
+ return provider;
+ }
+
+ public static void killAllVMBrokers()
+ {
+ _logger.info("Killing all VM Brokers");
+ synchronized(TransportConnection.class)
+ {
+ if (_acceptor != null)
+ {
+ _acceptor.unbindAll();
+ }
+ synchronized (_inVmPipeAddress)
+ {
+ _inVmPipeAddress.clear();
+ }
+ _acceptor = null;
+ }
+ _currentInstance = -1;
+ _currentVMPort = -1;
+ }
+
+ public static void killVMBroker(int port)
+ {
+ synchronized (_inVmPipeAddress)
+ {
+ 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/transport/VmPipeTransportConnection.java b/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java
new file mode 100644
index 0000000000..87cc2e7a5a
--- /dev/null
+++ b/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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.transport;
+
+import java.io.IOException;
+
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.transport.vmpipe.QpidVmPipeConnector;
+import org.apache.mina.transport.vmpipe.VmPipeAddress;
+import org.apache.mina.transport.vmpipe.VmPipeConnector;
+import org.apache.qpid.client.protocol.AMQProtocolHandler;
+import org.apache.qpid.jms.BrokerDetails;
+import org.apache.qpid.transport.network.mina.MINANetworkDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class VmPipeTransportConnection implements ITransportConnection
+{
+ private static final Logger _logger = LoggerFactory.getLogger(VmPipeTransportConnection.class);
+
+ private int _port;
+
+ private MINANetworkDriver _networkDriver;
+
+ public VmPipeTransportConnection(int port)
+ {
+ _port = port;
+ }
+
+ public void connect(AMQProtocolHandler protocolHandler, BrokerDetails brokerDetail) throws IOException
+ {
+ final VmPipeConnector ioConnector = new QpidVmPipeConnector();
+
+ final VmPipeAddress address = new VmPipeAddress(_port);
+ _logger.info("Attempting connection to " + address);
+ _networkDriver = new MINANetworkDriver(ioConnector, protocolHandler);
+ protocolHandler.setNetworkDriver(_networkDriver);
+ ConnectFuture future = ioConnector.connect(address, _networkDriver);
+ // wait for connection to complete
+ future.join();
+ // we call getSession which throws an IOException if there has been an error connecting
+ future.getSession();
+ _networkDriver.setProtocolEngine(protocolHandler);
+ }
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java b/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java
index 03167561ef..f3f74dd332 100644
--- a/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java
+++ b/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java
@@ -45,7 +45,7 @@ public class URLParser
private void parseURL(String fullURL) throws URLSyntaxException
{
// Connection URL format
- // amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\',option=\'value\';tcp://host:port?option=\'value\'',failover='method?option=\'value\',option='value''"
+ // amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\',option=\'value\';vm://:3/virtualpath?option=\'value\'',failover='method?option=\'value\',option='value''"
// Options are of course optional except for requiring a single broker in the broker list.
try
{
@@ -195,7 +195,7 @@ public class URLParser
{
String brokerlist = _url.getOptions().get(AMQConnectionURL.OPTIONS_BROKERLIST);
- // brokerlist tcp://host:port?option='value',option='value';tcp://host:port/virtualpath?option='value'
+ // brokerlist tcp://host:port?option='value',option='value';vm://:3/virtualpath?option='value'
StringTokenizer st = new StringTokenizer(brokerlist, "" + URLHelper.BROKER_SEPARATOR);
while (st.hasMoreTokens())
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
index bec41644fc..208658a5ff 100644
--- 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
@@ -28,8 +28,9 @@ 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.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+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
@@ -63,8 +64,6 @@ import org.slf4j.LoggerFactory;
*/
public abstract class BlockingWaiter<T>
{
- private static final Logger _logger = LoggerFactory.getLogger(BlockingWaiter.class);
-
/** This flag is used to indicate that the blocked for method has been received. */
private volatile boolean _ready = false;
@@ -181,7 +180,7 @@ public abstract class BlockingWaiter<T>
}
catch (InterruptedException e)
{
- _logger.error(e.getMessage(), e);
+ System.err.println(e.getMessage());
// IGNORE -- //fixme this isn't ideal as being interrupted isn't equivellant to sucess
// if (!_ready && timeout != -1)
// {
@@ -229,12 +228,12 @@ public abstract class BlockingWaiter<T>
}
/**
- * This is a callback, called when an error has occurred that should interrupt any waiter.
+ * 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 propagated.
+ * @param e The exception being propogated.
*/
public void error(Exception e)
{
@@ -256,7 +255,7 @@ public abstract class BlockingWaiter<T>
}
else
{
- _logger.error("WARNING: new error '" + e == null ? "null" : e.getMessage() + "' arrived while old one not yet processed:" + _error.getMessage());
+ System.err.println("WARNING: new error '" + e == null ? "null" : e.getMessage() + "' arrived while old one not yet processed:" + _error.getMessage());
}
if (_waiting.get())
@@ -273,7 +272,7 @@ public abstract class BlockingWaiter<T>
}
catch (InterruptedException e1)
{
- _logger.error(e1.getMessage(), e1);
+ System.err.println(e.getMessage());
}
}
_errorAck = false;
diff --git a/java/client/src/main/java/org/apache/qpid/client/util/ClassLoadingAwareObjectInputStream.java b/java/client/src/main/java/org/apache/qpid/client/util/ClassLoadingAwareObjectInputStream.java
deleted file mode 100644
index 669a0f1abf..0000000000
--- a/java/client/src/main/java/org/apache/qpid/client/util/ClassLoadingAwareObjectInputStream.java
+++ /dev/null
@@ -1,134 +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.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectStreamClass;
-import java.lang.reflect.Proxy;
-import java.util.HashMap;
-
-
-/**
- * <code>ClassLoadingAwareObjectInputStream</code> is an Extention of Object input stream to be used
- * to de-serialize JMS Object Messages.
- *
- * <p>This was introduced to resolve the class loading issues which can happen when we use the client
- * libraries in a complex class loading Environment.</p>
- */
-public class ClassLoadingAwareObjectInputStream extends ObjectInputStream
-{
- /** <p>Class loader instance which loaded this class.
- * It will be used to load classes when we failed to load classes from dynamic class loading</p> */
- private static final ClassLoader _ON_FAULT_CLASS_LOADER =
- ClassLoadingAwareObjectInputStream.class.getClassLoader();
-
- /** <p>Maps primitive type names to corresponding class objects.</p> */
- private static final HashMap<String, Class> _primitives = new HashMap<String, Class>(8, 1.0F);
-
-
- public ClassLoadingAwareObjectInputStream(InputStream in) throws IOException
- {
- super(in);
- }
-
- @Override
- protected Class resolveClass(ObjectStreamClass classDesc)
- throws IOException, ClassNotFoundException
- {
-
- // Here we use TTCL as our primary class loader to load the classes
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
-
- return load(classDesc.getName(), cl);
- }
-
- @Override
- protected Class resolveProxyClass(String[] interfaces)
- throws IOException, ClassNotFoundException
- {
- // Here we use TTCL as our primary class loader to load the classes
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
-
- Class[] cinterfaces = new Class[interfaces.length];
- for (int i = 0; i < interfaces.length; i++)
- {
- cinterfaces[i] = load(interfaces[i], cl);
- }
-
- try
- {
- return Proxy.getProxyClass(cinterfaces[0].getClassLoader(), cinterfaces);
- }
- catch (IllegalArgumentException e)
- {
- throw new ClassNotFoundException(null, e);
- }
- }
-
- /**
- * <p>
- * Method we used to load class that are needed to de-serialize the objects. </p>
- * <p>
- * Here we first look up for the objects from the given class loader and if its not there
- * we will be using the class loader of this class.
- * </p>
- * @param className Class name to lookup
- * @param cl primary class loader which we 1st use to lookup
- * @return Class instance we are looking for
- * @throws ClassNotFoundException if both primary and secondary lockup's failed.
- */
- private Class load(String className, ClassLoader cl)
- throws ClassNotFoundException
- {
- try
- {
- return Class.forName(className, false, cl);
- }
- catch (ClassNotFoundException e)
- {
- final Class clazz = _primitives.get(className);
-
- if (clazz != null)
- {
- return clazz;
- }
- else
- {
- return Class.forName(className, false, _ON_FAULT_CLASS_LOADER);
- }
- }
- }
-
- static
- {
- _primitives.put("boolean", boolean.class);
- _primitives.put("byte", byte.class);
- _primitives.put("char", char.class);
- _primitives.put("short", short.class);
- _primitives.put("int", int.class);
- _primitives.put("long", long.class);
- _primitives.put("float", float.class);
- _primitives.put("double", double.class);
- _primitives.put("void", void.class);
- }
-}
diff --git a/java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java b/java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java
new file mode 100644
index 0000000000..dc0d9b8c78
--- /dev/null
+++ b/java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java
@@ -0,0 +1,60 @@
+/*
+ *
+ * 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.vmbroker;
+
+import org.apache.qpid.client.transport.AMQTransportConnectionException;
+import org.apache.qpid.protocol.AMQConstant;
+
+/**
+ * AMQVMBrokerCreationException represents failure to create an in VM broker on the vm transport medium.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Represent failure to create an in VM broker.
+ * </table>
+ *
+ * @todo Error code never used. This is not an AMQException.
+ */
+public class AMQVMBrokerCreationException extends AMQTransportConnectionException
+{
+ private int _port;
+
+ /**
+ * @param port
+ *
+ * @deprecated
+ */
+ public AMQVMBrokerCreationException(int port)
+ {
+ this(null, port, "Unable to create vm broker", null);
+ }
+
+ public AMQVMBrokerCreationException(AMQConstant errorCode, int port, String message, Throwable cause)
+ {
+ super(errorCode, message, cause);
+ _port = port;
+ }
+
+ public String toString()
+ {
+ return super.toString() + " on port " + _port;
+ }
+}
diff --git a/java/client/src/main/java/org/apache/qpid/filter/JMSSelectorFilter.java b/java/client/src/main/java/org/apache/qpid/filter/JMSSelectorFilter.java
index 40718c6435..4159986090 100644
--- a/java/client/src/main/java/org/apache/qpid/filter/JMSSelectorFilter.java
+++ b/java/client/src/main/java/org/apache/qpid/filter/JMSSelectorFilter.java
@@ -37,9 +37,9 @@ public class JMSSelectorFilter implements MessageFilter
public JMSSelectorFilter(String selector) throws AMQInternalException
{
_selector = selector;
- if (_logger.isDebugEnabled())
+ if (JMSSelectorFilter._logger.isDebugEnabled())
{
- _logger.debug("Created JMSSelectorFilter with selector:" + _selector);
+ JMSSelectorFilter._logger.debug("Created JMSSelectorFilter with selector:" + _selector);
}
_matcher = new SelectorParser().parse(selector);
}
@@ -49,16 +49,16 @@ public class JMSSelectorFilter implements MessageFilter
try
{
boolean match = _matcher.matches(message);
- if (_logger.isDebugEnabled())
+ if (JMSSelectorFilter._logger.isDebugEnabled())
{
- _logger.debug(message + " match(" + match + ") selector(" + System
+ JMSSelectorFilter._logger.debug(message + " match(" + match + ") selector(" + System
.identityHashCode(_selector) + "):" + _selector);
}
return match;
}
catch (AMQInternalException e)
{
- _logger.warn("Caught exception when evaluating message selector for message " + message, e);
+ JMSSelectorFilter._logger.warn("Caght exception when evaluating message selector for message " + message, e);
}
return false;
}
diff --git a/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java b/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java
index 574a1b3888..b7b6bd57bc 100644
--- a/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java
+++ b/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java
@@ -19,7 +19,6 @@ package org.apache.qpid.filter;
import java.util.HashMap;
-import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import org.apache.qpid.AMQInternalException;
@@ -33,7 +32,7 @@ import org.slf4j.LoggerFactory;
public class PropertyExpression implements Expression
{
// Constants - defined the same as JMS
- private static enum JMSDeliveryMode { NON_PERSISTENT, PERSISTENT }
+ private static final int NON_PERSISTENT = 1;
private static final int DEFAULT_PRIORITY = 4;
private static final Logger _logger = LoggerFactory.getLogger(PropertyExpression.class);
@@ -80,24 +79,22 @@ public class PropertyExpression implements Expression
{
public Object evaluate(AbstractJMSMessage message)
{
-
- JMSDeliveryMode mode = JMSDeliveryMode.NON_PERSISTENT;
try
{
- mode = message.getJMSDeliveryMode() == DeliveryMode.PERSISTENT ?
- JMSDeliveryMode.PERSISTENT : JMSDeliveryMode.NON_PERSISTENT;
-
+ int mode = message.getJMSDeliveryMode();
if (_logger.isDebugEnabled())
{
_logger.debug("JMSDeliveryMode is :" + mode);
}
+
+ return mode;
}
catch (JMSException e)
{
_logger.warn("Error evaluating property",e);
}
- return mode.toString();
+ return NON_PERSISTENT;
}
});
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 0c2f4ce57d..6d81f728c9 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
@@ -22,7 +22,7 @@ package org.apache.qpid.jms;
import java.util.Map;
-import org.apache.qpid.transport.ConnectionSettings;
+import org.apache.qpid.client.SSLConfiguration;
public interface BrokerDetails
{
@@ -52,7 +52,9 @@ public interface BrokerDetails
public static final int DEFAULT_PORT = 5672;
+ public static final String SOCKET = "socket";
public static final String TCP = "tcp";
+ public static final String VM = "vm";
public static final String DEFAULT_TRANSPORT = TCP;
@@ -104,12 +106,14 @@ public interface BrokerDetails
long getTimeout();
void setTimeout(long timeout);
+
+ SSLConfiguration getSSLConfiguration();
+
+ void setSSLConfiguration(SSLConfiguration sslConfiguration);
boolean getBooleanProperty(String propName);
String toString();
boolean equals(Object o);
-
- ConnectionSettings buildConnectionSettings();
}
diff --git a/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java b/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java
index 26641982d7..0e8ca60686 100644
--- a/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java
+++ b/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java
@@ -27,7 +27,7 @@ import java.util.List;
/**
Connection URL format
- amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\'&option=\'value\';tcp://host:port/virtualpath?option=\'value\''&failover='method?option=\'value\'&option='value''"
+ amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\'&option=\'value\';vm://:3/virtualpath?option=\'value\''&failover='method?option=\'value\'&option='value''"
Options are of course optional except for requiring a single broker in the broker list.
The option seperator is defined to be either '&' or ','
*/
diff --git a/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java b/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java
index 56abf03c81..7cdcd32306 100644
--- a/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java
+++ b/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.jms;
+import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.jms.failover.FailoverExchangeMethod;
import org.apache.qpid.jms.failover.FailoverMethod;
import org.apache.qpid.jms.failover.FailoverRoundRobinServers;
@@ -50,7 +51,7 @@ public class FailoverPolicy
private long _lastMethodTime;
private long _lastFailTime;
- public FailoverPolicy(ConnectionURL connectionDetails, Connection conn)
+ public FailoverPolicy(ConnectionURL connectionDetails, AMQConnection conn)
{
FailoverMethod method;
@@ -82,7 +83,7 @@ public class FailoverPolicy
*/
if (failoverMethod.equals(FailoverMethod.SINGLE_BROKER))
{
- method = new FailoverSingleServer(connectionDetails);
+ method = new FailoverRoundRobinServers(connectionDetails);
}
else
{
diff --git a/java/client/src/main/java/org/apache/qpid/jms/MessageProducer.java b/java/client/src/main/java/org/apache/qpid/jms/MessageProducer.java
index 4ad917fa83..b830c377b8 100644
--- a/java/client/src/main/java/org/apache/qpid/jms/MessageProducer.java
+++ b/java/client/src/main/java/org/apache/qpid/jms/MessageProducer.java
@@ -51,4 +51,7 @@ public interface MessageProducer extends javax.jms.MessageProducer
int priority, long timeToLive, boolean mandatory, boolean immediate)
throws JMSException;
+ void send(Destination destination, Message message, int deliveryMode, int priority, long timeToLive,
+ boolean mandatory, boolean immediate, boolean waitUntilSent) throws JMSException;
+
}
diff --git a/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java b/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java
index cb3ab718e9..9e6000c472 100644
--- a/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java
+++ b/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java
@@ -32,9 +32,9 @@ import javax.jms.Session;
import org.apache.qpid.client.AMQAnyDestination;
import org.apache.qpid.client.AMQBrokerDetails;
+import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.jms.BrokerDetails;
-import org.apache.qpid.jms.Connection;
import org.apache.qpid.jms.ConnectionURL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -58,7 +58,7 @@ public class FailoverExchangeMethod implements FailoverMethod, MessageListener
private static final Logger _logger = LoggerFactory.getLogger(FailoverExchangeMethod.class);
/** This is not safe to use until attainConnection is called */
- private Connection _conn;
+ private AMQConnection _conn;
/** Protects the broker list when modifications happens */
private Object _brokerListLock = new Object();
@@ -80,7 +80,7 @@ public class FailoverExchangeMethod implements FailoverMethod, MessageListener
/** Denotes the number of failed attempts **/
private int _failedAttemps = 0;
- public FailoverExchangeMethod(ConnectionURL connectionDetails, Connection conn)
+ public FailoverExchangeMethod(ConnectionURL connectionDetails, AMQConnection conn)
{
_connectionDetails = connectionDetails;
_originalBrokerDetail = _connectionDetails.getBrokerDetails(0);
@@ -140,6 +140,7 @@ public class FailoverExchangeMethod implements FailoverMethod, MessageListener
broker.setHost(tokens[1]);
broker.setPort(Integer.parseInt(tokens[2]));
broker.setProperties(_originalBrokerDetail.getProperties());
+ broker.setSSLConfiguration(_originalBrokerDetail.getSSLConfiguration());
brokerList.add(broker);
if (currentBrokerIP.equals(broker.getHost()) &&
diff --git a/java/client/src/main/java/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java b/java/client/src/main/java/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java
index b480f56c07..fec5af55c1 100644
--- a/java/client/src/main/java/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java
+++ b/java/client/src/main/java/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java
@@ -36,7 +36,6 @@ import javax.jms.Queue;
import javax.jms.Topic;
import javax.naming.Context;
import javax.naming.NamingException;
-import javax.naming.ConfigurationException;
import javax.naming.spi.InitialContextFactory;
import org.apache.qpid.client.AMQConnectionFactory;
@@ -140,7 +139,7 @@ public class PropertiesFileInitialContextFactory implements InitialContextFactor
return new ReadOnlyContext(environment, data);
}
- protected void createConnectionFactories(Map data, Hashtable environment) throws ConfigurationException
+ protected void createConnectionFactories(Map data, Hashtable environment)
{
for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();)
{
@@ -158,7 +157,7 @@ public class PropertiesFileInitialContextFactory implements InitialContextFactor
}
}
- protected void createDestinations(Map data, Hashtable environment) throws ConfigurationException
+ protected void createDestinations(Map data, Hashtable environment)
{
for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();)
{
@@ -226,7 +225,7 @@ public class PropertiesFileInitialContextFactory implements InitialContextFactor
/**
* Factory method to create new Connection Factory instances
*/
- protected ConnectionFactory createFactory(String url) throws ConfigurationException
+ protected ConnectionFactory createFactory(String url)
{
try
{
@@ -234,18 +233,16 @@ public class PropertiesFileInitialContextFactory implements InitialContextFactor
}
catch (URLSyntaxException urlse)
{
- _logger.warn("Unable to create factory:" + urlse);
-
- ConfigurationException ex = new ConfigurationException("Failed to parse entry: " + urlse + " due to : " + urlse.getMessage());
- ex.initCause(urlse);
- throw ex;
+ _logger.warn("Unable to createFactories:" + urlse);
}
+
+ return null;
}
/**
* Factory method to create new Destination instances from an AMQP BindingURL
*/
- protected Destination createDestination(String str) throws ConfigurationException
+ protected Destination createDestination(String str)
{
try
{
@@ -255,9 +252,7 @@ public class PropertiesFileInitialContextFactory implements InitialContextFactor
{
_logger.warn("Unable to create destination:" + e, e);
- ConfigurationException ex = new ConfigurationException("Failed to parse entry: " + str + " due to : " + e.getMessage());
- ex.initCause(e);
- throw ex;
+ return null;
}
}
diff --git a/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindConnectionFactory.java b/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindConnectionFactory.java
new file mode 100644
index 0000000000..2c08f1e34a
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindConnectionFactory.java
@@ -0,0 +1,185 @@
+/*
+ *
+ * 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.IBMPerfTest;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.qpid.client.AMQConnectionFactory;
+import org.apache.qpid.url.URLSyntaxException;
+
+import javax.jms.ConnectionFactory;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import java.io.File;
+import java.util.Hashtable;
+
+public class JNDIBindConnectionFactory
+{
+
+ public static final String CONNECTION_FACTORY_BINDING = "amq.ConnectionFactory";
+ public static final String DEFAULT_PROVIDER_FILE_PATH = System.getProperty("java.io.tmpdir") + File.separator + "IBMPerfTestsJNDI";
+ public static final String PROVIDER_URL = "file://" + DEFAULT_PROVIDER_FILE_PATH;
+ public static final String FSCONTEXT_FACTORY = "com.sun.jndi.fscontext.RefFSContextFactory";
+ public static final String DEFAULT_CONNECTION_URL = "amqp://guest:guest@clientid/testpath?brokerlist='tcp://localhost:5672'";
+
+ private static void printUsage()
+ {
+ System.out.println("Using default values: Usage:java JNDIBindConnectionFactory <connection url> [<Connection Factory Binding>] [<Provider URL>] [<JNDI Context Factory>]");
+
+ }
+
+ public static void main(String[] args)
+ {
+ Logger.getRootLogger().setLevel(Level.OFF);
+
+ String connectionFactoryBinding = CONNECTION_FACTORY_BINDING;
+ String provider = PROVIDER_URL;
+ String contextFactory = FSCONTEXT_FACTORY;
+ if (args.length == 0)
+ {
+ printUsage();
+ System.exit(1);
+ }
+
+ String connectionURL = args[0];
+
+ System.out.println("Using Connection:" + connectionURL + "\n");
+
+
+ if (args.length > 1)
+ {
+ connectionFactoryBinding = args[1];
+
+ if (args.length > 2)
+ {
+ provider = args[2];
+
+ if (args.length > 3)
+ {
+ contextFactory = args[3];
+ }
+ }
+ else
+ {
+ System.out.println("Using default File System Context Factory");
+ System.out.println("Using default Connection Factory Binding:" + connectionFactoryBinding);
+ }
+ }
+ else
+ {
+ printUsage();
+ }
+
+
+ System.out.println("File System Context Factory\n" +
+ "Connection:" + connectionURL + "\n" +
+ "Connection Factory Binding:" + connectionFactoryBinding + "\n" +
+ "JNDI Provider URL:" + provider);
+
+ if (provider.startsWith("file"))
+ {
+ File file = new File(provider.substring(provider.indexOf("://") + 3));
+
+ if (file.exists() && !file.isDirectory())
+ {
+ System.out.println("Couldn't make directory file already exists");
+ System.exit(1);
+ }
+ else
+ {
+ if (!file.exists())
+ {
+ if (!file.mkdirs())
+ {
+ System.out.println("Couldn't make directory");
+ System.exit(1);
+ }
+ }
+ }
+ }
+
+ new JNDIBindConnectionFactory(provider, connectionFactoryBinding, contextFactory, connectionURL);
+
+ }
+
+ public JNDIBindConnectionFactory(String provider, String binding, String contextFactory, String CONNECTION_URL)
+ {
+ // Set up the environment for creating the initial context
+ Hashtable env = new Hashtable(11);
+ env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory);
+
+ env.put(Context.PROVIDER_URL, provider);
+
+ try
+ {
+ // Create the initial context
+ Context ctx = new InitialContext(env);
+
+ // Create the object to be bound
+ ConnectionFactory factory = null;
+
+ try
+ {
+ factory = new AMQConnectionFactory(CONNECTION_URL);
+
+
+ try
+ {
+ Object obj = ctx.lookup(binding);
+
+ if (obj != null)
+ {
+ System.out.println("Un-binding previous Connection Factory");
+ ctx.unbind(binding);
+ }
+ }
+ catch (NamingException e)
+ {
+ System.out.println("Operation failed: " + e);
+ }
+
+ // Perform the bind
+ ctx.bind(binding, factory);
+ System.out.println("Bound Connection Factory:" + binding);
+
+ // Check that it is bound
+ Object obj = ctx.lookup(binding);
+ System.out.println("Connection URL:" + ((AMQConnectionFactory) obj).getConnectionURL());
+
+ System.out.println("JNDI FS Context:" + provider);
+ }
+ catch (NamingException amqe)
+ {
+ System.out.println("Operation failed: " + amqe);
+ }
+ catch (URLSyntaxException e)
+ {
+ System.out.println("Operation failed: " + e);
+ }
+
+ }
+ catch (NamingException e)
+ {
+ System.out.println("Operation failed: " + e);
+ }
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindQueue.java b/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindQueue.java
new file mode 100644
index 0000000000..10e8b94311
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindQueue.java
@@ -0,0 +1,213 @@
+/*
+ *
+ * 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.IBMPerfTest;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.client.AMQSession;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import java.io.File;
+import java.util.Hashtable;
+
+public class JNDIBindQueue
+{
+ public static final String DEFAULT_PROVIDER_FILE_PATH = System.getProperty("java.io.tmpdir") + File.separator + "IBMPerfTestsJNDI";
+ public static final String PROVIDER_URL = "file://" + DEFAULT_PROVIDER_FILE_PATH;
+ public static final String FSCONTEXT_FACTORY = "com.sun.jndi.fscontext.RefFSContextFactory";
+
+ Connection _connection = null;
+ Context _ctx = null;
+
+
+ public JNDIBindQueue(String queueBinding, String queueName, String provider, String contextFactory)
+ {
+ // Set up the environment for creating the initial context
+ Hashtable env = new Hashtable(11);
+ env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory);
+
+ env.put(Context.PROVIDER_URL, provider);
+
+ try
+ {
+ // Create the initial context
+ _ctx = new InitialContext(env);
+
+ // Create the object to be bound
+
+ try
+ {
+ _connection = new AMQConnection("amqp://guest:guest@clientid/test?brokerlist='tcp://localhost:5672'");
+ System.out.println("Connected");
+ }
+ catch (Exception amqe)
+ {
+ System.out.println("Unable to create AMQConnectionFactory:" + amqe);
+ }
+
+ if (_connection != null)
+ {
+ bindQueue(queueName, queueBinding);
+ }
+
+ // Check that it is bound
+ Object obj = _ctx.lookup(queueBinding);
+
+ System.out.println("Bound Queue:" + ((AMQQueue) obj).toURL());
+
+ System.out.println("JNDI FS Context:" + provider);
+
+ }
+ catch (NamingException e)
+ {
+ System.out.println("Operation failed: " + e);
+ }
+ finally
+ {
+ try
+ {
+ if (_connection != null)
+ {
+ _connection.close();
+ }
+ }
+ catch (JMSException closeE)
+ {
+ System.out.println("Connection closing failed: " + closeE);
+ }
+ }
+
+
+ }
+
+
+ private void bindQueue(String queueName, String queueBinding) throws NamingException
+ {
+
+ try
+ {
+ Object obj = _ctx.lookup(queueBinding);
+
+ if (obj != null)
+ {
+ System.out.println("Un-binding exisiting object");
+ _ctx.unbind(queueBinding);
+ }
+ }
+ catch (NamingException e)
+ {
+
+ }
+
+ Queue queue = null;
+ try
+ {
+
+ Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ if (session != null)
+ {
+ queue = ((AMQSession) session).createQueue(queueName);
+ }
+ }
+ catch (JMSException jmse)
+ {
+ System.out.println("Unable to create Queue:" + jmse);
+ }
+
+ // Perform the bind
+ _ctx.bind(queueBinding, queue);
+ }
+
+
+ public static void main(String[] args)
+ {
+ Logger.getRootLogger().setLevel(Level.OFF);
+
+ String provider = JNDIBindQueue.PROVIDER_URL;
+ String contextFactory = JNDIBindQueue.FSCONTEXT_FACTORY;
+
+ if (args.length > 1)
+ {
+ String binding = args[0];
+ String queueName = args[1];
+
+ if (args.length > 2)
+ {
+ provider = args[2];
+
+ if (args.length > 3)
+ {
+ contextFactory = args[3];
+ }
+ }
+ else
+ {
+ System.out.println("Using default File System Context Factory");
+ }
+
+ System.out.println("File System Context Factory\n" +
+ "Binding Queue:'" + queueName + "' to '" + binding + "'\n" +
+ "JNDI Provider URL:" + provider);
+
+ if (provider.startsWith("file"))
+ {
+ File file = new File(provider.substring(provider.indexOf("://") + 3));
+
+ if (file.exists() && !file.isDirectory())
+ {
+ System.out.println("Couldn't make directory file already exists");
+ System.exit(1);
+ }
+ else
+ {
+ if (!file.exists())
+ {
+ if (!file.mkdirs())
+ {
+ System.out.println("Couldn't make directory");
+ System.exit(1);
+ }
+ }
+ }
+ }
+
+
+ new JNDIBindQueue(binding, queueName, provider, contextFactory);
+
+ }
+ else
+ {
+ System.out.println("Using Defaults: Usage:java JNDIBindQueue <Binding> <queue name> [<Provider URL> [<JNDI Context Factory>]]");
+ }
+
+ }
+
+
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindTopic.java b/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindTopic.java
new file mode 100644
index 0000000000..ca071c1187
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindTopic.java
@@ -0,0 +1,212 @@
+/*
+ *
+ * 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.IBMPerfTest;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.client.AMQTopic;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.Session;
+import javax.jms.Topic;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import java.io.File;
+import java.util.Hashtable;
+
+public class JNDIBindTopic
+{
+ public static final String DEFAULT_PROVIDER_FILE_PATH = System.getProperty("java.io.tmpdir") + File.separator + "IBMPerfTestsJNDI";
+ public static final String PROVIDER_URL = "file://" + DEFAULT_PROVIDER_FILE_PATH;
+
+ public static final String FSCONTEXT_FACTORY = "com.sun.jndi.fscontext.RefFSContextFactory";
+
+ Connection _connection = null;
+ Context _ctx = null;
+
+
+ public JNDIBindTopic(String topicBinding, String topicName, String provider, String contextFactory)
+ {
+ // Set up the environment for creating the initial context
+ Hashtable env = new Hashtable(11);
+ env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory);
+
+ env.put(Context.PROVIDER_URL, provider);
+
+ try
+ {
+ // Create the initial context
+ _ctx = new InitialContext(env);
+
+ // Create the object to be bound
+
+ try
+ {
+ _connection = new AMQConnection("amqp://guest:guest@clientid/test?brokerlist='tcp://localhost:5672'");
+ System.out.println("Connected");
+ }
+ catch (Exception amqe)
+ {
+ System.out.println("Unable to create AMQConnectionFactory:" + amqe);
+ }
+
+ if (_connection != null)
+ {
+ bindTopic(topicName, topicBinding);
+ }
+
+ // Check that it is bound
+ Object obj = _ctx.lookup(topicBinding);
+
+ System.out.println("Bound Queue:" + ((AMQTopic) obj).toURL());
+
+ System.out.println("JNDI FS Context:" + provider);
+
+ }
+ catch (NamingException e)
+ {
+ System.out.println("Operation failed: " + e);
+ }
+ finally
+ {
+ try
+ {
+ if (_connection != null)
+ {
+ _connection.close();
+ }
+ }
+ catch (JMSException closeE)
+ {
+ System.out.println("Operation failed: " + closeE);
+ }
+ }
+ }
+
+
+ private void bindTopic(String topicName, String topicBinding) throws NamingException
+ {
+
+ try
+ {
+ Object obj = _ctx.lookup(topicBinding);
+
+ if (obj != null)
+ {
+ System.out.println("Un-binding exisiting object");
+ _ctx.unbind(topicBinding);
+ }
+ }
+ catch (NamingException e)
+ {
+
+ }
+
+ Topic topic = null;
+ try
+ {
+
+ Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ if (session != null)
+ {
+ topic = ((AMQSession) session).createTopic(topicName);
+ }
+ }
+ catch (JMSException jmse)
+ {
+ System.out.println("Unable to create Topic:" + jmse);
+ }
+
+ // Perform the bind
+ _ctx.bind(topicBinding, topic);
+ }
+
+
+ public static void main(String[] args)
+ {
+ Logger.getRootLogger().setLevel(Level.OFF);
+
+ String provider = JNDIBindTopic.PROVIDER_URL;
+ String contextFactory = JNDIBindTopic.FSCONTEXT_FACTORY;
+
+ if (args.length > 1)
+ {
+ String binding = args[0];
+ String queueName = args[1];
+
+ if (args.length > 2)
+ {
+ provider = args[2];
+
+ if (args.length > 3)
+ {
+ contextFactory = args[3];
+ }
+ }
+ else
+ {
+ System.out.println("Using default File System Context Factory");
+ }
+
+ System.out.println("File System Context Factory\n" +
+ "Binding Topic:'" + queueName + "' to '" + binding + "'\n" +
+ "JNDI Provider URL:" + provider);
+
+
+ if (provider.startsWith("file"))
+ {
+ File file = new File(provider.substring(provider.indexOf("://") + 3));
+
+ if (file.exists() && !file.isDirectory())
+ {
+ System.out.println("Couldn't make directory file already exists");
+ System.exit(1);
+ }
+ else
+ {
+ if (!file.exists())
+ {
+ if (!file.mkdirs())
+ {
+ System.out.println("Couldn't make directory");
+ System.exit(1);
+ }
+ }
+ }
+ }
+
+ new JNDIBindTopic(binding, queueName, provider, contextFactory);
+
+ }
+ else
+ {
+ System.out.println("Usage:java JNDIBindTopic <Binding> <topic name> [<Provider URL> [<JNDI Context Factory>]]");
+ }
+
+ }
+
+
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/README.txt b/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/README.txt
new file mode 100644
index 0000000000..95ee9f9c77
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/README.txt
@@ -0,0 +1,11 @@
+These JNDI setup tools are mainly for use in conjunction with the IBM JMS Performance Harness available here:
+The jar should be placed in the client/test/lib/ directory.
+
+http://www.alphaworks.ibm.com/tech/perfharness
+
+
+These JNDI classes use the the SUN FileSystem context.
+There are two jar files that should be placed in your client/test/lib directory.
+
+http://javashoplm.sun.com/ECom/docs/Welcome.jsp?StoreId=22&PartDetailId=7110-jndi-1.2.1-oth-JPR&SiteId=JSC&TransactionId=noreg
+
diff --git a/java/client/src/old_test/java/org/apache/qpid/cluster/Client.java b/java/client/src/old_test/java/org/apache/qpid/cluster/Client.java
new file mode 100644
index 0000000000..cf8059a143
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/cluster/Client.java
@@ -0,0 +1,129 @@
+/*
+ *
+ * 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.cluster;
+
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.client.AMQTopic;
+import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.url.URLSyntaxException;
+
+import javax.jms.MessageListener;
+import javax.jms.Message;
+import javax.jms.Session;
+import javax.jms.JMSException;
+import javax.jms.MessageProducer;
+import javax.jms.TextMessage;
+import java.util.Random;
+
+public class Client
+{
+ private final Random random = new Random();
+ private final String name;
+ private final Session session;
+ private final MessageProducer topicProducer;
+ private final MessageProducer queueProducer;
+
+ Client(AMQConnection connection, String name) throws JMSException, InterruptedException
+ {
+ this.name = name;
+ session = connection.createSession(false, AMQSession.NO_ACKNOWLEDGE);
+
+ AMQTopic topic = new AMQTopic(((AMQSession)session).getDefaultTopicExchangeName(), new AMQShortString("cluster_test_topic"));
+ AMQQueue queue = new AMQQueue(((AMQSession)session).getDefaultQueueExchangeName(), new AMQShortString("cluster_test_queue"));
+
+ topicProducer = session.createProducer(topic);
+ queueProducer = session.createProducer(queue);
+
+ //subscribe to a known topic
+ session.createConsumer(topic).setMessageListener(new TopicHandler());
+ //subscribe to a known queue
+ session.createConsumer(queue).setMessageListener(new QueueHandler());
+
+ connection.start();
+
+ while(true)
+ {
+ Thread.sleep(random.nextInt(60000));
+ sendToQueue(name + ":" + randomString(5));
+ }
+ }
+
+ private synchronized void sendToTopic(String message) throws JMSException
+ {
+ topicProducer.send(session.createTextMessage(message));
+ }
+
+ private synchronized void sendToQueue(String message) throws JMSException
+ {
+ queueProducer.send(session.createTextMessage(message));
+ }
+
+ private String randomString(int length){
+ char[] c = new char[length];
+ for(int i = 0; i < length; i++)
+ {
+ c[i] = (char) ('A' + random.nextInt(26));
+ }
+ return new String(c);
+ }
+
+ private class QueueHandler implements MessageListener
+ {
+ public void onMessage(Message message)
+ {
+ try
+ {
+ sendToTopic(((TextMessage) message).getText());
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private class TopicHandler implements MessageListener
+ {
+ public void onMessage(Message message)
+ {
+ try
+ {
+ System.out.println(((TextMessage) message).getText());
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static void main(String[] argv) throws AMQException, JMSException, InterruptedException, URLSyntaxException
+ {
+ //assume args describe the set of brokers to try
+
+ String clientName = argv.length > 1 ? argv[1] : "testClient";
+ new Client(new AMQConnection(argv.length > 0 ? argv[0] : "vm://:1", "guest", "guest", clientName, "/test"), clientName);
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/codec/BasicDeliverTest.java b/java/client/src/old_test/java/org/apache/qpid/codec/BasicDeliverTest.java
new file mode 100644
index 0000000000..1db7e200bd
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/codec/BasicDeliverTest.java
@@ -0,0 +1,277 @@
+/*
+ *
+ * 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.codec;
+
+import org.apache.qpid.framing.*;
+import org.apache.mina.common.*;
+import org.apache.mina.common.support.BaseIoSession;
+import org.apache.mina.filter.codec.ProtocolDecoderOutput;
+import org.apache.mina.filter.codec.ProtocolEncoderOutput;
+
+import java.net.SocketAddress;
+
+/**
+ */
+public class BasicDeliverTest
+{
+ public static void main(String[] argv) throws Exception
+ {
+ BasicDeliverTest test = new BasicDeliverTest();
+
+ //warm up:
+ test.encode(512, 100000);
+
+ //real tests:
+ test.encode(16, 10000, 15);
+ test.encode(32, 10000, 15);
+ test.encode(64, 10000, 15);
+ test.encode(128, 10000, 15);
+ test.encode(256, 10000, 15);
+ test.encode(512, 10000, 15);
+ test.encode(1024, 10000, 15);
+ test.encode(2048, 10000, 15);
+
+ test.decode(16, 10000, 15);
+ test.decode(32, 10000, 15);
+ test.decode(64, 10000, 15);
+ test.decode(128, 10000, 15);
+ test.decode(256, 10000, 15);
+ test.decode(512, 10000, 15);
+ test.decode(1024, 10000, 15);
+ test.decode(2048, 10000, 15);
+ }
+
+ void decode(int size, int count, int iterations) throws Exception
+ {
+ long min = Long.MAX_VALUE;
+ long max = 0;
+ long total = 0;
+ for (int i = 0; i < iterations; i++)
+ {
+ long time = decode(size, count);
+ total += time;
+ if (time < min)
+ {
+ min = time;
+ }
+ if (time > max)
+ {
+ max = time;
+ }
+ }
+ System.out.println("Decoded " + count + " messages of " + size +
+ " bytes: avg=" + (total / iterations) + ", min=" + min + ", max=" + max);
+ }
+
+
+ long decode(int size, int count) throws Exception
+ {
+ AMQDataBlock block = getDataBlock(size);
+ ByteBuffer data = ByteBuffer.allocate((int) block.getSize()); // XXX: Is cast a problem?
+ block.writePayload(data);
+ data.flip();
+ AMQDecoder decoder = new AMQDecoder(false);
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < count; i++)
+ {
+ decoder.decode(session, data, decoderOutput);
+ data.rewind();
+ }
+ return System.currentTimeMillis() - start;
+ }
+
+ void encode(int size, int count, int iterations) throws Exception
+ {
+ long min = Long.MAX_VALUE;
+ long max = 0;
+ long total = 0;
+ for (int i = 0; i < iterations; i++)
+ {
+ long time = encode(size, count);
+ total += time;
+ if (time < min)
+ {
+ min = time;
+ }
+ if (time > max)
+ {
+ max = time;
+ }
+ }
+ System.out.println("Encoded " + count + " messages of " + size +
+ " bytes: avg=" + (total / iterations) + ", min=" + min + ", max=" + max);
+ }
+
+ long encode(int size, int count) throws Exception
+ {
+ IoSession session = null;
+ AMQDataBlock block = getDataBlock(size);
+ AMQEncoder encoder = new AMQEncoder();
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < count; i++)
+ {
+ encoder.encode(session, block, encoderOutput);
+ }
+ return System.currentTimeMillis() - start;
+ }
+
+ private final ProtocolEncoderOutput encoderOutput = new ProtocolEncoderOutput()
+ {
+
+ public void write(ByteBuffer byteBuffer)
+ {
+ }
+
+ public void mergeAll()
+ {
+ }
+
+ public WriteFuture flush()
+ {
+ return null;
+ }
+ };
+
+ private final ProtocolDecoderOutput decoderOutput = new ProtocolDecoderOutput()
+ {
+ public void write(Object object)
+ {
+ }
+
+ public void flush()
+ {
+ }
+ };
+
+ private final IoSession session = new BaseIoSession()
+ {
+
+ protected void updateTrafficMask()
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public IoService getService()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public IoServiceConfig getServiceConfig()
+ {
+ return null;
+ }
+
+ public IoHandler getHandler()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public IoSessionConfig getConfig()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public IoFilterChain getFilterChain()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public TransportType getTransportType()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public SocketAddress getRemoteAddress()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public SocketAddress getLocalAddress()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public SocketAddress getServiceAddress()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public int getScheduledWriteRequests()
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public int getScheduledWriteBytes()
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+ };
+
+ private static final char[] DATA = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
+
+ static CompositeAMQDataBlock getDataBlock(int size)
+ {
+ //create a frame representing message delivery
+ AMQFrame[] frames = new AMQFrame[3];
+ frames[0] = wrapBody(createBasicDeliverBody());
+ frames[1] = wrapBody(createContentHeaderBody());
+ frames[2] = wrapBody(createContentBody(size));
+
+ return new CompositeAMQDataBlock(frames);
+ }
+
+ static AMQFrame wrapBody(AMQBody body)
+ {
+ AMQFrame frame = new AMQFrame(1, body);
+ return frame;
+ }
+
+ static ContentBody createContentBody(int size)
+ {
+ ContentBody body = new ContentBody();
+ body.payload = ByteBuffer.allocate(size);
+ for (int i = 0; i < size; i++)
+ {
+ body.payload.put((byte) DATA[i % DATA.length]);
+ }
+ return body;
+ }
+
+ static ContentHeaderBody createContentHeaderBody()
+ {
+ ContentHeaderBody body = new ContentHeaderBody();
+ body.properties = new BasicContentHeaderProperties();
+ body.weight = 1;
+ body.classId = 6;
+ return body;
+ }
+
+ static BasicDeliverBody createBasicDeliverBody()
+ {
+ BasicDeliverBody body = new BasicDeliverBody((byte) 8, (byte) 0,
+ BasicDeliverBody.getClazz((byte) 8, (byte) 0),
+ BasicDeliverBody.getMethod((byte) 8, (byte) 0),
+ new AMQShortString("myConsumerTag"), 1,
+ new AMQShortString("myExchange"), false,
+ new AMQShortString("myRoutingKey"));
+ return body;
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/codec/Client.java b/java/client/src/old_test/java/org/apache/qpid/codec/Client.java
new file mode 100644
index 0000000000..3886021277
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/codec/Client.java
@@ -0,0 +1,133 @@
+/*
+ *
+ * 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.codec;
+
+import org.apache.mina.transport.socket.nio.SocketConnector;
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.filter.codec.ProtocolCodecFilter;
+import org.apache.qpid.framing.AMQDataBlock;
+import org.apache.qpid.framing.AMQFrame;
+import org.apache.qpid.framing.BasicDeliverBody;
+import org.apache.qpid.framing.ContentBody;
+
+import java.net.InetSocketAddress;
+
+public class Client extends IoHandlerAdapter
+{
+ //private static final int[] DEFAULT_SIZES = new int[]{1024, 512, 256, 128, 56};
+ //private static final int[] DEFAULT_SIZES = new int[]{256, 256, 256, 256, 256, 512, 512, 512, 512, 512};
+ private static final int[] DEFAULT_SIZES = new int[]{256, 512, 256, 512, 256, 512, 256, 512, 256, 512};
+ //private static final int[] DEFAULT_SIZES = new int[]{1024, 1024, 1024, 1024, 1024};
+
+ private final IoSession _session;
+ private final long _start;
+ private final int _size;
+ private final int _count;
+ private int _received;
+ private boolean _closed;
+
+ Client(String host, int port, int size, int count) throws Exception
+ {
+ _count = count;
+ _size = size;
+ AMQDataBlock block = BasicDeliverTest.getDataBlock(size);
+
+ InetSocketAddress address = new InetSocketAddress(host, port);
+ ConnectFuture future = new SocketConnector().connect(address, this);
+ future.join();
+ _session = future.getSession();
+
+ _start = System.currentTimeMillis();
+ for(int i = 0; i < count; i++)
+ {
+ _session.write(block);
+ }
+ }
+
+ void close()
+ {
+ long time = System.currentTimeMillis() - _start;
+ System.out.println("Received " + _received + " messages of " + _size
+ + " bytes in " + time + "ms.");
+ _session.close();
+ synchronized(this)
+ {
+ _closed = true;
+ notify();
+ }
+ }
+
+ void waitForClose() throws InterruptedException
+ {
+ synchronized(this)
+ {
+ while(!_closed)
+ {
+ wait();
+ }
+ }
+ }
+
+ public void sessionCreated(IoSession session) throws Exception
+ {
+ session.getFilterChain().addLast("protocolFilter", new ProtocolCodecFilter(new AMQCodecFactory(false)));
+ }
+
+ public void messageReceived(IoSession session, Object object) throws Exception
+ {
+ if(isContent(object) && ++_received == _count) close();
+ }
+
+ public void exceptionCaught(IoSession session, Throwable throwable) throws Exception
+ {
+ throwable.printStackTrace();
+ close();
+ }
+
+ private static boolean isDeliver(Object o)
+ {
+ return o instanceof AMQFrame && ((AMQFrame) o).getBodyFrame() instanceof BasicDeliverBody;
+ }
+
+ private static boolean isContent(Object o)
+ {
+ return o instanceof AMQFrame && ((AMQFrame) o).getBodyFrame() instanceof ContentBody;
+ }
+
+ public static void main(String[] argv) throws Exception
+ {
+ String host = argv.length > 0 ? argv[0] : "localhost";
+ int port = argv.length > 1 ? Integer.parseInt(argv[1]) : 8888;
+ int count = argv.length > 2 ? Integer.parseInt(argv[2]) : 10000;
+ int[] sizes = argv.length > 3 ? new int[]{Integer.parseInt(argv[3])} : DEFAULT_SIZES;
+
+ System.out.println("Connecting to " + host + ":" + port);
+
+ for(int i = 0; i < sizes.length; i++)
+ {
+ new Client(host, port, sizes[i], count).waitForClose();
+ Thread.sleep(1000);
+ }
+ }
+
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/codec/Server.java b/java/client/src/old_test/java/org/apache/qpid/codec/Server.java
new file mode 100644
index 0000000000..fa4295e0b2
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/codec/Server.java
@@ -0,0 +1,103 @@
+/*
+ *
+ * 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.codec;
+
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.transport.socket.nio.SocketAcceptor;
+import org.apache.mina.util.SessionUtil;
+import org.apache.mina.filter.codec.ProtocolCodecFilter;
+import org.apache.qpid.framing.AMQFrame;
+import org.apache.qpid.framing.CompositeAMQDataBlock;
+
+import java.net.InetSocketAddress;
+
+public class Server extends IoHandlerAdapter
+{
+ Server(int port) throws Exception
+ {
+ new SocketAcceptor().bind(new InetSocketAddress(port), this);
+ System.out.println("Listening on " + port);
+ }
+
+ public void sessionCreated(IoSession session) throws Exception
+ {
+ SessionUtil.initialize(session);
+ session.getFilterChain().addLast("protocolFilter", new ProtocolCodecFilter(new AMQCodecFactory(false)));
+ }
+
+ public void messageReceived(IoSession session, Object object) throws Exception
+ {
+ getAccumulator(session).received(session, (AMQFrame) object);
+ }
+
+ public void sessionOpened(IoSession session) throws Exception
+ {
+ System.out.println("sessionOpened()");
+ }
+
+ public void sessionClosed(IoSession session) throws Exception
+ {
+ System.out.println("sessionClosed()");
+ }
+
+ public void exceptionCaught(IoSession session, Throwable t) throws Exception
+ {
+ System.out.println("exceptionCaught()");
+ t.printStackTrace();
+ session.close();
+ }
+
+ private Accumulator getAccumulator(IoSession session)
+ {
+ Accumulator a = (Accumulator) session.getAttribute(ACCUMULATOR);
+ if(a == null)
+ {
+ a = new Accumulator();
+ session.setAttribute(ACCUMULATOR, a);
+ }
+ return a;
+ }
+
+ private static final String ACCUMULATOR = Accumulator.class.getName();
+
+ private static class Accumulator
+ {
+ private final AMQFrame[] frames = new AMQFrame[3];
+ private int i;
+
+ void received(IoSession session, AMQFrame frame)
+ {
+ frames[i++] = frame;
+ if(i >= frames.length)
+ {
+ i = 0;
+ session.write(new CompositeAMQDataBlock(frames));
+ }
+ }
+ }
+
+ public static void main(String[] argv) throws Exception
+ {
+ int port = argv.length > 0 ? Integer.parseInt(argv[0]) : 8888;
+ new Server(port);
+ }
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/message/TypedBytesCodes.java b/java/client/src/old_test/java/org/apache/qpid/config/AMQConnectionFactoryInitialiser.java
index 26a0b41cdc..cac0064785 100644
--- a/java/client/src/main/java/org/apache/qpid/client/message/TypedBytesCodes.java
+++ b/java/client/src/old_test/java/org/apache/qpid/config/AMQConnectionFactoryInitialiser.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,29 +18,18 @@
* under the License.
*
*/
-package org.apache.qpid.client.message;
-
-public interface TypedBytesCodes
-{
- static final byte BOOLEAN_TYPE = (byte) 1;
-
- static final byte BYTE_TYPE = (byte) 2;
-
- static final byte BYTEARRAY_TYPE = (byte) 3;
+package org.apache.qpid.config;
- static final byte SHORT_TYPE = (byte) 4;
+import org.apache.qpid.client.AMQConnectionFactory;
+import org.apache.qpid.config.ConnectionFactoryInitialiser;
+import org.apache.qpid.config.ConnectorConfig;
- static final byte CHAR_TYPE = (byte) 5;
+import javax.jms.ConnectionFactory;
- static final byte INT_TYPE = (byte) 6;
-
- static final byte LONG_TYPE = (byte) 7;
-
- static final byte FLOAT_TYPE = (byte) 8;
-
- static final byte DOUBLE_TYPE = (byte) 9;
-
- static final byte STRING_TYPE = (byte) 10;
-
- static final byte NULL_STRING_TYPE = (byte) 11;
+class AMQConnectionFactoryInitialiser implements ConnectionFactoryInitialiser
+{
+ public ConnectionFactory getFactory(ConnectorConfig config)
+ {
+ return new AMQConnectionFactory(config.getHost(), config.getPort(), "/test_path");
+ }
}
diff --git a/java/client/src/old_test/java/org/apache/qpid/config/AbstractConfig.java b/java/client/src/old_test/java/org/apache/qpid/config/AbstractConfig.java
new file mode 100644
index 0000000000..04381d66a0
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/config/AbstractConfig.java
@@ -0,0 +1,69 @@
+/*
+ *
+ * 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.config;
+
+public abstract class AbstractConfig
+{
+ 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;
+ }
+
+ protected int parseInt(String msg, String i)
+ {
+ try
+ {
+ return Integer.parseInt(i);
+ }
+ catch(NumberFormatException e)
+ {
+ throw new RuntimeException(msg + ": " + i);
+ }
+ }
+
+ protected long parseLong(String msg, String i)
+ {
+ try
+ {
+ return Long.parseLong(i);
+ }
+ catch(NumberFormatException e)
+ {
+ throw new RuntimeException(msg + ": " + i);
+ }
+ }
+
+ public abstract void setOption(String key, String value);
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/message/QpidMessageProperties.java b/java/client/src/old_test/java/org/apache/qpid/config/ConnectionFactoryInitialiser.java
index b30afafa35..a9984eb09a 100644
--- a/java/client/src/main/java/org/apache/qpid/client/message/QpidMessageProperties.java
+++ b/java/client/src/old_test/java/org/apache/qpid/config/ConnectionFactoryInitialiser.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,17 +18,12 @@
* under the License.
*
*/
-package org.apache.qpid.client.message;
+package org.apache.qpid.config;
-/**
- * Place holder for Qpid specific message properties
- */
-public class QpidMessageProperties
-{
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
- public static final String QPID_SUBJECT = "qpid.subject";
-
- // AMQP 0-10 related properties
- public static final String AMQP_0_10_APP_ID = "x-amqp-0-10.app-id";
- public static final String AMQP_0_10_ROUTING_KEY = "x-amqp-0-10.routing-key";
+public interface ConnectionFactoryInitialiser
+{
+ public ConnectionFactory getFactory(ConnectorConfig config) throws JMSException;
}
diff --git a/java/client/src/old_test/java/org/apache/qpid/config/Connector.java b/java/client/src/old_test/java/org/apache/qpid/config/Connector.java
new file mode 100644
index 0000000000..ff2377f087
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/config/Connector.java
@@ -0,0 +1,40 @@
+/*
+ *
+ * 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.config;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+
+public class Connector
+{
+ public Connection createConnection(ConnectorConfig config) throws Exception
+ {
+ return getConnectionFactory(config).createConnection();
+ }
+
+ ConnectionFactory getConnectionFactory(ConnectorConfig config) throws Exception
+ {
+ String factory = config.getFactory();
+ if(factory == null) factory = AMQConnectionFactoryInitialiser.class.getName();
+ System.out.println("Using " + factory);
+ return ((ConnectionFactoryInitialiser) Class.forName(factory).newInstance()).getFactory(config);
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/config/ConnectorConfig.java b/java/client/src/old_test/java/org/apache/qpid/config/ConnectorConfig.java
new file mode 100644
index 0000000000..b120ed3f12
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/config/ConnectorConfig.java
@@ -0,0 +1,28 @@
+/*
+ *
+ * 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.config;
+
+public interface ConnectorConfig
+{
+ public String getHost();
+ public int getPort();
+ public String getFactory();
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/config/JBossConnectionFactoryInitialiser.java b/java/client/src/old_test/java/org/apache/qpid/config/JBossConnectionFactoryInitialiser.java
new file mode 100644
index 0000000000..1c86aea56c
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/config/JBossConnectionFactoryInitialiser.java
@@ -0,0 +1,117 @@
+/*
+ *
+ * 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.config;
+
+import org.apache.qpid.config.ConnectionFactoryInitialiser;
+import org.apache.qpid.config.ConnectorConfig;
+
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.MBeanException;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.NameNotFoundException;
+import java.util.Hashtable;
+
+public class JBossConnectionFactoryInitialiser implements ConnectionFactoryInitialiser
+{
+ public ConnectionFactory getFactory(ConnectorConfig config) throws JMSException
+ {
+ ConnectionFactory cf = null;
+ InitialContext ic = null;
+ Hashtable ht = new Hashtable();
+ ht.put(InitialContext.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
+ String jbossHost = System.getProperty("jboss.host", "eqd-lxamq01");
+ String jbossPort = System.getProperty("jboss.port", "1099");
+ ht.put(InitialContext.PROVIDER_URL, "jnp://" + jbossHost + ":" + jbossPort);
+ ht.put(InitialContext.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
+
+ try
+ {
+ ic = new InitialContext(ht);
+ if (!doesDestinationExist("topictest.messages", ic))
+ {
+ deployTopic("topictest.messages", ic);
+ }
+ if (!doesDestinationExist("topictest.control", ic))
+ {
+ deployTopic("topictest.control", ic);
+ }
+
+ cf = (ConnectionFactory) ic.lookup("/ConnectionFactory");
+ return cf;
+ }
+ catch (NamingException e)
+ {
+ JMSException jmse = new JMSException("Unable to lookup object: " + e);
+ jmse.setLinkedException(e);
+ jmse.initCause(e);
+ throw jmse;
+ }
+ catch (Exception e)
+ {
+ JMSException jmse = new JMSException("Error creating topic: " + e);
+ jmse.setLinkedException(e);
+ jmse.initCause(e);
+ throw jmse;
+ }
+ }
+
+ private boolean doesDestinationExist(String name, InitialContext ic) throws Exception
+ {
+ try
+ {
+ ic.lookup("/" + name);
+ }
+ catch (NameNotFoundException e)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ private void deployTopic(String name, InitialContext ic) throws Exception
+ {
+ MBeanServerConnection mBeanServer = lookupMBeanServerProxy(ic);
+
+ ObjectName serverObjectName = new ObjectName("jboss.messaging:service=ServerPeer");
+
+ String jndiName = "/" + name;
+ try
+ {
+ mBeanServer.invoke(serverObjectName, "createTopic",
+ new Object[]{name, jndiName},
+ new String[]{"java.lang.String", "java.lang.String"});
+ }
+ catch (MBeanException e)
+ {
+ System.err.println("Error: " + e);
+ System.err.println("Cause: " + e.getCause());
+ }
+ }
+
+ private MBeanServerConnection lookupMBeanServerProxy(InitialContext ic) throws NamingException
+ {
+ return (MBeanServerConnection) ic.lookup("jmx/invoker/RMIAdaptor");
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/flow/ChannelFlowTest.java b/java/client/src/old_test/java/org/apache/qpid/flow/ChannelFlowTest.java
new file mode 100644
index 0000000000..cb8adae18c
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/flow/ChannelFlowTest.java
@@ -0,0 +1,112 @@
+/*
+ *
+ * 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.flow;
+
+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.exchange.ExchangeDefaults;
+import org.apache.qpid.framing.AMQShortString;
+
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
+
+public class ChannelFlowTest implements MessageListener
+{
+ private int sent;
+ private int received;
+
+ ChannelFlowTest(String broker) throws Exception
+ {
+ this(new AMQConnection(broker, "guest", "guest", randomize("Client"), "/test"));
+ }
+
+ ChannelFlowTest(AMQConnection connection) throws Exception
+ {
+ this(connection, new AMQQueue(connection.getDefaultQueueExchangeName(), new AMQShortString(randomize("ChannelFlowTest")), true));
+ }
+
+ ChannelFlowTest(AMQConnection connection, AMQDestination destination) throws Exception
+ {
+ AMQSession session = (AMQSession) connection.createSession(false, AMQSession.NO_ACKNOWLEDGE, 50,25);
+
+ //set up a slow consumer
+ session.createConsumer(destination).setMessageListener(this);
+ connection.start();
+
+ //create a publisher
+ MessageProducer producer = session.createProducer(destination);
+ Message msg = session.createTextMessage("Message");
+
+ //publish in bursts that are fast enough to cause channel flow control
+ for(int i = 0; i < 10; i++)
+ {
+ for(int j = 0; j < 100; j++)
+ {
+ producer.send(msg);
+ sent++;
+ }
+ waitUntilReceived(sent - 40);
+ }
+
+ waitUntilReceived(sent);
+
+ session.close();
+ connection.close();
+ }
+
+
+ private synchronized void waitUntilReceived(int count) throws InterruptedException
+ {
+ while(received <count)
+ {
+ wait();
+ }
+ }
+
+ public synchronized void onMessage(Message message)
+ {
+ try
+ {
+ Thread.sleep(50);
+
+ received++;
+ notify();
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private static String randomize(String in)
+ {
+ return in + System.currentTimeMillis();
+ }
+
+ public static void main(String[] argv) throws Exception
+ {
+ new ChannelFlowTest(argv.length == 0 ? "localhost:5672" : argv[0]);
+ }
+
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/fragmentation/TestLargePublisher.java b/java/client/src/old_test/java/org/apache/qpid/fragmentation/TestLargePublisher.java
new file mode 100644
index 0000000000..2fe01fc126
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/fragmentation/TestLargePublisher.java
@@ -0,0 +1,196 @@
+/*
+ *
+ * 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.fragmentation;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.url.URLSyntaxException;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQTopic;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.jms.MessageProducer;
+import org.apache.qpid.jms.Session;
+import org.apache.log4j.Logger;
+
+import javax.jms.BytesMessage;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * A client that behaves as follows:
+ * <ul><li>Connects to a queue, whose name is specified as a cmd-line argument</li>
+ * <li>Creates a temporary queue</li>
+ * <li>Creates messages containing a property that is the name of the temporary queue</li>
+ * <li>Fires off a message on the original queue and waits for a response on the temporary queue</li>
+ * </ul>
+ */
+public class TestLargePublisher
+{
+ private static final Logger _log = Logger.getLogger(TestLargePublisher.class);
+
+ private AMQConnection _connection;
+
+ private AMQSession _session;
+
+ private class CallbackHandler implements MessageListener
+ {
+ private int _expectedMessageCount;
+
+ private int _actualMessageCount;
+
+ private long _startTime;
+
+ public CallbackHandler(int expectedMessageCount, long startTime)
+ {
+ _expectedMessageCount = expectedMessageCount;
+ _startTime = startTime;
+ }
+
+ public void onMessage(Message m)
+ {
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Message received: " + m);
+ }
+ _actualMessageCount++;
+ if (_actualMessageCount%1000 == 0)
+ {
+ _log.info("Received message count: " + _actualMessageCount);
+ }
+ /*if (!"henson".equals(m.toString()))
+ {
+ _log.error("AbstractJMSMessage response not correct: expected 'henson' but got " + m.toString());
+ }
+ else
+ {
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("AbstractJMSMessage " + m + " received");
+ }
+ else
+ {
+ _log.info("AbstractJMSMessage received");
+ }
+ } */
+
+ if (_actualMessageCount == _expectedMessageCount)
+ {
+ long timeTaken = System.currentTimeMillis() - _startTime;
+ System.out.println("Total time taken to receive " + _expectedMessageCount+ " messages was " +
+ timeTaken + "ms, equivalent to " +
+ (_expectedMessageCount/(timeTaken/1000.0)) + " messages per second");
+ }
+ }
+ }
+
+ public TestLargePublisher(String host, int port, String clientID,
+ final int messageCount) throws AMQException,URLSyntaxException
+ {
+ try
+ {
+ createConnection(host, port, clientID);
+
+ _session = (AMQSession) _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ AMQTopic destination = new AMQTopic(_session.getDefaultTopicExchangeName(), new AMQShortString("large"));
+ MessageProducer producer = (MessageProducer) _session.createProducer(destination);
+
+ _connection.start();
+ //TextMessage msg = _session.createTextMessage(tempDestination.getQueueName() + "/Presented to in conjunction with Mahnah Mahnah and the Snowths");
+ final long startTime = System.currentTimeMillis();
+
+ for (int i = 0; i < messageCount; i++)
+ {
+ BytesMessage msg = _session.createBytesMessage();
+ populateMessage(msg);
+ producer.send(msg);
+ }
+ _log.info("Finished sending " + messageCount + " messages");
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void createConnection(String host, int port, String clientID) throws AMQException , URLSyntaxException
+ {
+ _connection = new AMQConnection(host, port, "guest", "guest",
+ clientID, "/test");
+ }
+
+ private void populateMessage(BytesMessage msg) throws JMSException
+ {
+ int size = 1024 * 187; // 187k
+ byte[] data = new byte[size];
+ for (int i = 0; i < data.length; i++)
+ {
+ data[i] = (byte)(i%25);
+ }
+ msg.writeBytes(data);
+ }
+
+ /**
+ *
+ * @param args argument 1 if present specifies the name of the temporary queue to create. Leaving it blank
+ * means the server will allocate a name.
+ */
+ public static void main(String[] args) throws URLSyntaxException
+ {
+ final String host;
+ final int port;
+ final int numMessages;
+ if (args.length == 0)
+ {
+ host = "localhost";
+ port = 5672;
+ numMessages = 100;
+// System.err.println("Usage: TestLargePublisher <host> <port> <number of messages>");
+ }
+ else
+ {
+ host = args[0];
+ port = Integer.parseInt(args[1]);
+ numMessages = Integer.parseInt(args[2]);
+ }
+
+ try
+ {
+ InetAddress address = InetAddress.getLocalHost();
+ String clientID = address.getHostName() + System.currentTimeMillis();
+ TestLargePublisher client = new TestLargePublisher(host, port, clientID, numMessages);
+ }
+ catch (UnknownHostException e)
+ {
+ e.printStackTrace();
+ }
+ catch (AMQException e)
+ {
+ System.err.println("Error in client: " + e);
+ e.printStackTrace();
+ }
+
+ //System.exit(0);
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/fragmentation/TestLargeSubscriber.java b/java/client/src/old_test/java/org/apache/qpid/fragmentation/TestLargeSubscriber.java
new file mode 100644
index 0000000000..b0cde22349
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/fragmentation/TestLargeSubscriber.java
@@ -0,0 +1,167 @@
+/*
+ *
+ * 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.fragmentation;
+
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQTopic;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.jms.Session;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.log4j.Logger;
+
+import javax.jms.*;
+import java.net.InetAddress;
+
+public class TestLargeSubscriber
+{
+ private static final Logger _logger = Logger.getLogger(TestLargeSubscriber.class);
+
+ private static MessageProducer _destinationProducer;
+
+ private static String _destinationName;
+
+ public static void main(String[] args)
+ {
+ _logger.info("Starting...");
+
+ final String host;
+ final int port;
+ final String username;
+ final String password;
+ final String virtualPath;
+ final int numExpectedMessages;
+ if (args.length == 0)
+ {
+ host = "localhost";
+ port = 5672;
+ username = "guest";
+ password = "guest";
+ virtualPath = "/test";
+ numExpectedMessages = 100;
+ }
+ else if (args.length == 6)
+ {
+ host = args[0];
+ port = Integer.parseInt(args[1]);
+ username = args[2];
+ password = args[3];
+ virtualPath = args[4];
+ numExpectedMessages = Integer.parseInt(args[5]);
+ }
+ else
+ {
+ System.out.println("Usage: host port username password virtual-path expectedMessageCount");
+ System.exit(1);
+ throw new RuntimeException("cannot be reached");
+ }
+
+ try
+ {
+ InetAddress address = InetAddress.getLocalHost();
+ AMQConnection con = new AMQConnection(host, port, username, password,
+ address.getHostName(), virtualPath);
+ final AMQSession session = (AMQSession) con.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ final int expectedMessageCount = numExpectedMessages;
+
+ MessageConsumer consumer = session.createConsumer(new AMQTopic(session.getDefaultTopicExchangeName(),
+ new AMQShortString("large")),
+ 100, true, false, null);
+
+ consumer.setMessageListener(new MessageListener()
+ {
+ private int _messageCount;
+
+ private long _startTime = 0;
+
+ public void onMessage(Message message)
+ {
+ validateMessage(message);
+ if (_messageCount++ == 0)
+ {
+ _startTime = System.currentTimeMillis();
+ }
+ if (_logger.isInfoEnabled())
+ {
+ _logger.info("Got message '" + message + "'");
+ }
+ if (_messageCount == expectedMessageCount)
+ {
+ long totalTime = System.currentTimeMillis() - _startTime;
+ _logger.error("Total time to receive " + _messageCount + " messages was " +
+ totalTime + "ms. Rate is " + (_messageCount/(totalTime/1000.0)));
+ }
+ }
+
+ private void validateMessage(Message message)
+ {
+ if (!(message instanceof BytesMessage))
+ {
+ _logger.error("Message is not of correct type - should be BytesMessage and is " +
+ message.getClass());
+ }
+ BytesMessage bm = (BytesMessage) message;
+ final int expectedSize = 1024 * 187; // 187k
+ try
+ {
+ if (bm.getBodyLength() != expectedSize)
+ {
+ _logger.error("Message is not correct length - should be " + expectedSize + " and is " +
+ bm.getBodyLength());
+ }
+ }
+ catch (JMSException e)
+ {
+ _logger.error("Failed to validate message: " + e, e);
+ }
+ try
+ {
+ byte[] data = new byte[(int)bm.getBodyLength()];
+ bm.readBytes(data);
+ for (int i = 0; i < data.length; i++)
+ {
+ if (data[i] != (byte)(i%25))
+ {
+ _logger.error("byte " + i + " of message is wrong - should be " + i%25 + " but is " +
+ data[i]);
+ }
+ }
+ _logger.info("***** Validated message successfully");
+ }
+ catch (JMSException e)
+ {
+ _logger.error("Failed to validate message: " + e, e);
+ }
+ }
+ });
+ con.start();
+ }
+ catch (Throwable t)
+ {
+ System.err.println("Fatal error: " + t);
+ t.printStackTrace();
+ }
+
+ System.out.println("Waiting...");
+ }
+}
+
diff --git a/java/client/src/old_test/java/org/apache/qpid/headers/Listener.java b/java/client/src/old_test/java/org/apache/qpid/headers/Listener.java
new file mode 100644
index 0000000000..cb5caefc1e
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/headers/Listener.java
@@ -0,0 +1,117 @@
+/*
+ *
+ * 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.headers;
+
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.jms.Session;
+//import org.apache.qpid.testutil.Config;
+
+import javax.jms.MessageListener;
+import javax.jms.Message;
+import javax.jms.Destination;
+import javax.jms.MessageProducer;
+import javax.jms.JMSException;
+
+public class Listener //implements MessageListener
+{
+/* private final AMQConnection _connection;
+ private final MessageProducer _controller;
+ private final AMQSession _session;
+ private final MessageFactory _factory;
+ private int count;
+ private long start;
+
+ Listener(AMQConnection connection, Destination exchange) throws Exception
+ {
+ _connection = connection;
+ _session = (AMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ _factory = new MessageFactory(_session, 0, 19);
+
+ //register for events
+ _factory.createConsumer(exchange).setMessageListener(this);
+ _connection.start();
+
+ _controller = _session.createProducer(exchange);
+ }
+
+ private void shutdown()
+ {
+ try
+ {
+ _session.close();
+ _connection.stop();
+ _connection.close();
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace(System.out);
+ }
+ }
+
+ private void report()
+ {
+ try
+ {
+ String msg = getReport();
+ _controller.send(_factory.createReportResponseMessage(msg));
+ System.out.println("Sent report: " + msg);
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace(System.out);
+ }
+ }
+
+ private String getReport() throws JMSException
+ {
+ long time = (System.currentTimeMillis() - start);
+ return "Received " + count + " in " + time + "ms";
+ }
+
+ public void onMessage(Message message)
+ {
+ if(count == 0) start = System.currentTimeMillis();
+
+ if(_factory.isShutdown(message))
+ {
+ shutdown();
+ }
+ else if(_factory.isReport(message))
+ {
+ //send a report:
+ report();
+ }
+ else if (++count % 100 == 0)
+ {
+ System.out.println("Received " + count + " messages.");
+ }
+ }
+
+ public static void main(String[] argv) throws Exception
+ {
+ Config config = new Config();
+ config.setType(Config.HEADERS);
+ config.setName("test_headers_exchange");
+ config.setOptions(argv);
+ new Listener((AMQConnection) config.getConnection(), config.getDestination());
+ }*/
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/headers/MessageFactory.java b/java/client/src/old_test/java/org/apache/qpid/headers/MessageFactory.java
new file mode 100644
index 0000000000..a2d575fdd4
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/headers/MessageFactory.java
@@ -0,0 +1,175 @@
+/*
+ *
+ * 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.headers;
+
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.FieldTableFactory;
+
+import javax.jms.BytesMessage;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.TextMessage;
+
+/**
+ */
+class MessageFactory
+{
+ private static final char[] DATA = "abcdefghijklmnopqrstuvwxyz".toCharArray();
+
+ private final AMQSession _session;
+ private final byte[] _payload;
+
+ private String[] _headerNames;
+
+ MessageFactory(AMQSession session)
+ {
+ this(session, Integer.getInteger("amqj.test.message_size", 256).intValue(), 5);
+ }
+
+ MessageFactory(AMQSession session, int payloadSize, int headerCount)
+ {
+ if (headerCount < 1)
+ {
+ throw new IllegalArgumentException("Header count must be positive");
+ }
+ _session = session;
+ _payload = new byte[payloadSize];
+ for (int i = 0; i < _payload.length; i++)
+ {
+ _payload[i] = (byte) DATA[i % DATA.length];
+ }
+ _headerNames = new String[headerCount];
+ // note that with the standard encoding the headers get prefixed with an S to indicate their type
+ for (int i = 0; i < _headerNames.length; i++)
+ {
+ if (i < 10)
+ {
+ _headerNames[i] = "F000" + i;
+ }
+ else if (i >= 10 && i < 100)
+ {
+ _headerNames[i] = "F00" + i;
+ }
+ else
+ {
+ _headerNames[i] = "F0" + i;
+ }
+ }
+ }
+
+ Message createEventMessage() throws JMSException
+ {
+ BytesMessage msg = _session.createBytesMessage();
+ if (_payload.length != 0)
+ {
+ msg.writeBytes(_payload);
+ }
+ return setHeaders(msg, _headerNames);
+ }
+
+ Message createShutdownMessage() throws JMSException
+ {
+ return setHeaders(_session.createMessage(), new String[]{"F0000", "SHUTDOWN"});
+ }
+
+ Message createReportRequestMessage() throws JMSException
+ {
+ return setHeaders(_session.createMessage(), new String[]{"F0000", "REPORT"});
+ }
+
+ Message createReportResponseMessage(String msg) throws JMSException
+ {
+ return setHeaders(_session.createTextMessage(msg), new String[]{"CONTROL", "REPORT"});
+ }
+
+ boolean isShutdown(Message m)
+ {
+ return checkPresent(m, "SHUTDOWN");
+ }
+
+ boolean isReport(Message m)
+ {
+ return checkPresent(m, "REPORT");
+ }
+
+ Object getReport(Message m)
+ {
+ try
+ {
+ return ((TextMessage) m).getText();
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace(System.out);
+ return e.toString();
+ }
+ }
+
+ FieldTable getConsumerBinding()
+ {
+ FieldTable binding = FieldTableFactory.newFieldTable();
+ binding.setString("SF0000", "value");
+ return binding;
+ }
+
+ FieldTable getControllerBinding()
+ {
+ FieldTable binding = FieldTableFactory.newFieldTable();
+ binding.setString("SCONTROL", "value");
+ return binding;
+ }
+
+ MessageConsumer createConsumer(Destination source) throws Exception
+ {
+ return _session.createConsumer(source, 0, false, true, null, getConsumerBinding());
+ }
+
+ MessageConsumer createController(Destination source) throws Exception
+ {
+ return _session.createConsumer(source, 0, false, true, null, getControllerBinding());
+ }
+
+ private static boolean checkPresent(Message m, String s)
+ {
+ try
+ {
+ return m.getStringProperty(s) != null;
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace(System.out);
+ return false;
+ }
+ }
+
+ private static Message setHeaders(Message m, String[] headers) throws JMSException
+ {
+ for (int i = 0; i < headers.length; i++)
+ {
+ // the value in GRM is 5 bytes
+ m.setStringProperty(headers[i], "value");
+ }
+ return m;
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/headers/Publisher.java b/java/client/src/old_test/java/org/apache/qpid/headers/Publisher.java
new file mode 100644
index 0000000000..d9ef702c48
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/headers/Publisher.java
@@ -0,0 +1,133 @@
+/*
+ *
+ * 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.headers;
+
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQSession;
+//import org.apache.qpid.testutil.Config;
+
+import javax.jms.*;
+
+public class Publisher // implements MessageListener
+{
+/* private final Object _lock = new Object();
+ private final AMQConnection _connection;
+ private final AMQSession _session;
+ private final Destination _exchange;
+ private final MessageFactory _factory;
+ private final MessageProducer _publisher;
+ private int _count;
+
+ Publisher(AMQConnection connection, Destination exchange) throws Exception
+ {
+ _connection = connection;
+ _exchange = exchange;
+ _session = (AMQSession) _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ _factory = new MessageFactory(_session, 0, 19);
+ _publisher = _session.createProducer(_exchange);
+ }
+
+ Publisher(Config config) throws Exception
+ {
+ this((AMQConnection) config.getConnection(), config.getDestination());
+ }
+
+ private void test(int msgCount, int consumerCount) throws Exception
+ {
+ _count = consumerCount;
+ _factory.createController(_exchange).setMessageListener(this);
+ _connection.start();
+ long start = System.currentTimeMillis();
+ publish(msgCount);
+ waitForCompletion(consumerCount);
+ long end = System.currentTimeMillis();
+
+ System.out.println("Completed in " + (end - start) + " ms.");
+
+ //request shutdown
+ _publisher.send(_factory.createShutdownMessage());
+
+ _connection.stop();
+ _connection.close();
+ }
+
+ private void publish(int count) throws Exception
+ {
+
+ //send events
+ for (int i = 0; i < count; i++)
+ {
+ _publisher.send(_factory.createEventMessage());
+ if ((i + 1) % 100 == 0)
+ {
+ System.out.println("Sent " + (i + 1) + " messages");
+ }
+ }
+
+ //request report
+ _publisher.send(_factory.createReportRequestMessage());
+ }
+
+ private void waitForCompletion(int consumers) throws Exception
+ {
+ System.out.println("Waiting for completion...");
+ synchronized (_lock)
+ {
+ while (_count > 0)
+ {
+ _lock.wait();
+ }
+ }
+ }
+
+
+ public void onMessage(Message message)
+ {
+ System.out.println("Received report " + _factory.getReport(message) + " " + --_count + " remaining");
+ if (_count == 0)
+ {
+ synchronized (_lock)
+ {
+ _lock.notify();
+ }
+ }
+ }
+
+
+ public static void main(String[] argv) throws Exception
+ {
+ if (argv.length >= 2)
+ {
+ int msgCount = Integer.parseInt(argv[argv.length - 2]);
+ int consumerCount = Integer.parseInt(argv[argv.length - 1]);
+
+ Config config = new Config();
+ config.setType(Config.HEADERS);
+ config.setName("test_headers_exchange");
+ String[] options = new String[argv.length - 2];
+ System.arraycopy(argv, 0, options, 0, options.length);
+ config.setOptions(options);
+
+ new Publisher(config).test(msgCount, consumerCount);
+ }
+
+ }*/
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Bind.java b/java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Bind.java
new file mode 100644
index 0000000000..ee6a12c233
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Bind.java
@@ -0,0 +1,273 @@
+/*
+ *
+ * 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.jndi.referenceable;
+
+import org.apache.qpid.client.*;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.url.URLSyntaxException;
+
+import javax.jms.*;
+import javax.naming.*;
+
+import java.util.Properties;
+import java.io.InputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+/**
+ * Binds a reference from a JNDI source.
+ * Given a properties file with the JNDI information and a binding string.
+ */
+public class Bind
+{
+ private static final String USAGE="USAGE: java bind <JNDI Properties file> -cf <url> <binding> | -c <url> <binding> [-t <topic Name> <binding>] [-q <queue Name> <binding>]";
+ public Bind(String propertiesFile, String bindingURL, Referenceable reference) throws NameAlreadyBoundException, NoInitialContextException
+ {
+ // Set up the environment for creating the initial context
+ String qpid_home = System.getProperty("QPID_HOME");
+
+ if (qpid_home == null || qpid_home.equals(""))
+ {
+ System.out.println("QPID_HOME is not set");
+ System.exit(1);
+ }
+
+ if (qpid_home.charAt(qpid_home.length() - 1) != '/')
+ {
+ qpid_home += "/";
+ }
+
+ try
+ {
+ InputStream inputStream = new FileInputStream(qpid_home + propertiesFile);
+ Properties properties = new Properties();
+ properties.load(inputStream);
+
+ // Create the initial context
+ Context ctx = new InitialContext(properties);
+
+ // Perform the binds
+ ctx.bind(bindingURL, reference);
+
+ // Close the context when we're done
+ ctx.close();
+ }
+ catch (IOException ioe)
+ {
+ System.out.println("Unable to access properties file:" + propertiesFile + " Due to:" + ioe);
+ }
+ catch (NamingException e)
+ {
+ System.out.println("Operation failed: " + e);
+ if (e instanceof NameAlreadyBoundException)
+ {
+ throw (NameAlreadyBoundException) e;
+ }
+
+ if (e instanceof NoInitialContextException)
+ {
+ throw (NoInitialContextException) e;
+ }
+ }
+
+ }
+
+ private static String parse(String[] args, int index, String what, String type)
+ {
+ try
+ {
+ return args[index];
+ }
+ catch (IndexOutOfBoundsException ioobe)
+ {
+ System.out.println("ERROR: No " + what + " specified for " + type + ".");
+ System.out.println(USAGE);
+ System.exit(1);
+ }
+
+ // The path is either return normally or exception.. which calls system exit so keep the compiler happy
+ return "Never going to happen";
+ }
+
+
+ public static void main(String[] args) throws NameAlreadyBoundException, NoInitialContextException, URLSyntaxException, AMQException, JMSException
+ {
+
+
+ org.apache.log4j.Logger.getRootLogger().setLevel(org.apache.log4j.Level.OFF);
+
+// org.apache.log4j.Logger _logger = org.apache.log4j.Logger.getLogger(AMQConnection.class);
+// _logger.setLevel(org.apache.log4j.Level.OFF);
+
+ boolean exit = false;
+
+ String qpid_home = System.getProperty("QPID_HOME");
+
+ if (qpid_home == null || qpid_home.equals(""))
+ {
+ System.out.println("QPID_HOME is not set");
+ exit = true;
+ }
+
+ if (args.length <= 2)
+ {
+ System.out.println("At least a connection or connection factory must be requested to be bound.");
+ exit = true;
+ }
+ else
+ {
+ if ((args.length - 1) % 3 != 0)
+ {
+ System.out.println("Not all values have full details");
+ exit = true;
+ }
+ }
+ if (exit)
+ {
+ System.out.println(USAGE);
+ System.exit(1);
+ }
+
+ if (qpid_home.charAt(qpid_home.length() - 1) != '/')
+
+ {
+ qpid_home += "/";
+ }
+
+ AMQConnectionFactory cf = null;
+ AMQConnection c = null;
+ AMQSession session = null;
+ Referenceable reference = null;
+
+ for (int index = 1; index < args.length; index ++)
+ {
+ String obj = args[index];
+
+ String what = "Invalid";
+ String binding;
+
+ if (obj.startsWith("-c"))
+ {
+ boolean isFactory = obj.contains("f");
+
+
+ if (isFactory)
+ {
+ what = "ConnectionFactory";
+ }
+ else
+ {
+ what = "Factory";
+ }
+
+ String url = parse(args, ++index, "url", what);
+
+ if (isFactory)
+ {
+
+ cf = new AMQConnectionFactory(url);
+ reference = cf;
+ }
+ else
+ {
+ c = new AMQConnection(url);
+ reference = c;
+ }
+
+ }
+
+ if (obj.equals("-t") || obj.equals("-q"))
+ {
+ if (c == null)
+ {
+ c = (AMQConnection) cf.createConnection();
+ }
+
+ if (session == null)
+ {
+ session = (AMQSession) c.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ }
+
+ }
+
+ if (obj.equals("-t"))
+ {
+
+ String topicName = parse(args, ++index, "Topic Name", "Topic");
+ reference = (AMQTopic) session.createTopic(topicName);
+ what = "Topic";
+ }
+ else
+ {
+ if (obj.equals("-q"))
+ {
+ String topicName = parse(args, ++index, "Queue Name", "Queue");
+ reference = (AMQQueue) session.createQueue(topicName);
+ what = "Queue";
+ }
+ }
+
+ binding = parse(args, ++index, "binding", what);
+ if (binding == null)
+ {
+ System.out.println(obj + " is not a known Object to bind.");
+ System.exit(1);
+ }
+ else
+ {
+ System.out.print("Binding:" + reference + " to " + binding);
+ try
+ {
+ new Bind(args[0], binding, reference);
+ System.out.println(" ..Successful");
+
+ }
+ catch (NameAlreadyBoundException nabe)
+ {
+ System.out.println("");
+ if (!obj.startsWith("-c") || index == args.length - 1)
+ {
+ throw nabe;
+ }
+ else
+ {
+ System.out.println("Continuing with other bindings using the same connection details");
+ }
+ }
+ finally
+ {
+ if (!obj.startsWith("-c") || index == args.length - 1)
+ {
+ if (c != null)
+ {
+ c.close();
+ }
+ }
+ }
+ }
+ }
+
+ if (c != null)
+ {
+ c.close();
+ }
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Lookup.java b/java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Lookup.java
new file mode 100644
index 0000000000..1c9d8b0fd5
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Lookup.java
@@ -0,0 +1,196 @@
+/*
+ *
+ * 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.jndi.referenceable;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * Looksup a reference from a JNDI source.
+ * Given a properties file with the JNDI information and a binding string.
+ */
+public class Lookup
+{
+ private static final String USAGE = "USAGE: java lookup <JNDI Properties file> -b <binding>";
+ private Properties _properties;
+ private Object _object;
+
+ public Lookup(String propertiesFile, String bindingValue) throws NamingException
+ {
+ // Set up the environment for creating the initial context
+ String qpid_home = System.getProperty("QPID_HOME");
+
+ if (qpid_home == null || qpid_home.equals(""))
+ {
+ System.out.println("QPID_HOME is not set");
+ System.exit(1);
+ }
+
+ if (qpid_home.charAt(qpid_home.length() - 1) != '/')
+ {
+ qpid_home += "/";
+ }
+
+ try
+ {
+ InputStream inputStream = new FileInputStream(qpid_home + propertiesFile);
+ Properties properties = new Properties();
+ properties.load(inputStream);
+
+ _properties = properties;
+ lookup(bindingValue);
+ }
+ catch (IOException ioe)
+ {
+ System.out.println("Unable to access properties file:" + propertiesFile + " Due to:" + ioe);
+ }
+ }
+
+ public Object lookup(String bindingValue) throws NamingException
+ {
+
+ // Create the initial context
+ Context ctx = new InitialContext(_properties);
+
+ // Perform the binds
+ _object = ctx.lookup(bindingValue);
+
+ // Close the context when we're done
+ ctx.close();
+
+ return getObject();
+ }
+
+ public Object getObject()
+ {
+ return _object;
+ }
+
+ private static String parse(String[] args, int index, String what)
+ {
+ try
+ {
+ return args[index];
+ }
+ catch (IndexOutOfBoundsException ioobe)
+ {
+ System.out.println("ERROR: No " + what + " specified.");
+ System.out.println(USAGE);
+ System.exit(1);
+ }
+
+ // The path is either return normally or exception.. which calls system exit so keep the compiler happy
+ return "Never going to happen";
+ }
+
+
+ public static void main(String[] args) throws NamingException
+ {
+ boolean exit = false;
+
+ String qpid_home = System.getProperty("QPID_HOME");
+
+ if (qpid_home == null || qpid_home.equals(""))
+ {
+ System.out.println("QPID_HOME is not set");
+ exit = true;
+ }
+
+ if (args.length <= 2)
+ {
+ System.out.println("At least a connection or connection factory must be requested to be bound.");
+ exit = true;
+ }
+ else
+ {
+ if ((args.length - 1) % 2 != 0)
+ {
+ System.out.println("Not all values have full details");
+ exit = true;
+ }
+ }
+ if (exit)
+ {
+ System.out.println(USAGE);
+ System.exit(1);
+ }
+
+ if (qpid_home.charAt(qpid_home.length() - 1) != '/')
+
+ {
+ qpid_home += "/";
+ }
+
+ for (int index = 1; index < args.length; index ++)
+ {
+ String obj = args[index];
+
+
+ if (obj.equals("-b"))
+ {
+ String binding = parse(args, ++index, "binding");
+
+ if (binding == null)
+ {
+ System.out.println("Binding not specified.");
+ System.exit(1);
+ }
+ else
+ {
+ System.out.print("Looking up:" + binding);
+ try
+ {
+ Lookup l = new Lookup(args[0], binding);
+
+ Object object = l.getObject();
+
+ if (object instanceof Connection)
+ {
+ try
+ {
+ ((Connection) object).close();
+ }
+ catch (JMSException jmse)
+ {
+ ;
+ }
+ }
+ }
+ catch (NamingException nabe)
+ {
+ System.out.println("Problem unbinding " + binding + " continuing with other values.");
+ }
+ }
+ }// if -b
+ else
+ {
+ System.out.println("Continuing with other bindings option not known:" + obj);
+ }
+ }//for
+ }//main
+}//class
diff --git a/java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Unbind.java b/java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Unbind.java
new file mode 100644
index 0000000000..1acead674c
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Unbind.java
@@ -0,0 +1,166 @@
+/*
+ *
+ * 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.jndi.referenceable;
+
+import javax.naming.*;
+
+import java.util.Properties;
+import java.io.InputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+/**
+ * Unbinds a reference from a JNDI source.
+ * Given a properties file with the JNDI information and a binding string.
+ */
+public class Unbind
+{
+ private static final String USAGE = "USAGE: java unbind <JNDI Properties file> -b <binding>";
+
+ public Unbind(String propertiesFile, String bindingValue) throws NamingException
+ {
+ // Set up the environment for creating the initial context
+ String qpid_home = System.getProperty("QPID_HOME");
+
+ if (qpid_home == null || qpid_home.equals(""))
+ {
+ System.out.println("QPID_HOME is not set");
+ System.exit(1);
+ }
+
+ if (qpid_home.charAt(qpid_home.length() - 1) != '/')
+ {
+ qpid_home += "/";
+ }
+
+ try
+ {
+ InputStream inputStream = new FileInputStream(qpid_home + propertiesFile);
+ Properties properties = new Properties();
+ properties.load(inputStream);
+
+ // Create the initial context
+ Context ctx = new InitialContext(properties);
+
+ // Perform the binds
+ ctx.unbind(bindingValue);
+
+ // Close the context when we're done
+ ctx.close();
+ }
+ catch (IOException ioe)
+ {
+ System.out.println("Unable to access properties file:" + propertiesFile + " Due to:" + ioe);
+ }
+ }
+
+ private static String parse(String[] args, int index, String what)
+ {
+ try
+ {
+ return args[index];
+ }
+ catch (IndexOutOfBoundsException ioobe)
+ {
+ System.out.println("ERROR: No " + what + " specified.");
+ System.out.println(USAGE);
+ System.exit(1);
+ }
+
+ // The path is either return normally or exception.. which calls system exit so keep the compiler happy
+ return "Never going to happen";
+ }
+
+
+ public static void main(String[] args) throws NamingException
+ {
+ boolean exit = false;
+
+ String qpid_home = System.getProperty("QPID_HOME");
+
+ if (qpid_home == null || qpid_home.equals(""))
+ {
+ System.out.println("QPID_HOME is not set");
+ exit = true;
+ }
+
+ if (args.length <= 2)
+ {
+ System.out.println("At least a connection or connection factory must be requested to be bound.");
+ exit = true;
+ }
+ else
+ {
+ if ((args.length - 1) % 2 != 0)
+ {
+ System.out.println("Not all values have full details");
+ exit = true;
+ }
+ }
+ if (exit)
+ {
+ System.out.println(USAGE);
+ System.exit(1);
+ }
+
+ if (qpid_home.charAt(qpid_home.length() - 1) != '/')
+
+ {
+ qpid_home += "/";
+ }
+
+ for (int index = 1; index < args.length; index ++)
+ {
+ String obj = args[index];
+
+
+ if (obj.equals("-b"))
+ {
+ String binding = parse(args, ++index, "binding");
+
+ if (binding == null)
+ {
+ System.out.println("Binding not specified.");
+ System.exit(1);
+ }
+ else
+ {
+ System.out.print("UnBinding:" + binding);
+ try
+ {
+ new Unbind(args[0], binding);
+ System.out.println(" ..Successful");
+ }
+ catch (NamingException nabe)
+ {
+ System.out.println("");
+
+ System.out.println("Problem unbinding " + binding + " continuing with other values.");
+ }
+ }
+ }// if -b
+ else
+ {
+ System.out.println("Continuing with other bindings option not known:" + obj);
+ }
+ }//for
+ }//main
+}//class
diff --git a/java/client/src/old_test/java/org/apache/qpid/latency/LatencyTest.java b/java/client/src/old_test/java/org/apache/qpid/latency/LatencyTest.java
new file mode 100644
index 0000000000..4865a68dc4
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/latency/LatencyTest.java
@@ -0,0 +1,153 @@
+/*
+ *
+ * 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.latency;
+
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.client.AMQDestination;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.framing.AMQShortString;
+
+import javax.jms.MessageProducer;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.JMSException;
+import javax.jms.TextMessage;
+import javax.jms.BytesMessage;
+
+public class LatencyTest implements MessageListener
+{
+ private volatile boolean waiting;
+ private int sent;
+ private int received;
+
+ private final byte[] data;
+
+ private long min = Long.MAX_VALUE;
+ private long max = 0;
+ private long total = 0;
+
+ LatencyTest(String broker, int count, int delay, int length) throws Exception
+ {
+ this(new AMQConnection(broker, "guest", "guest", randomize("Client"), "/test"), count, delay, length);
+ }
+
+ LatencyTest(AMQConnection connection, int count, int delay, int length) throws Exception
+ {
+ this(connection, new AMQQueue(connection.getDefaultQueueExchangeName(), new AMQShortString(randomize("LatencyTest")), true), count, delay, length);
+ }
+
+ LatencyTest(AMQConnection connection, AMQDestination destination, int count, int delay, int length) throws Exception
+ {
+ AMQSession session = (AMQSession) connection.createSession(false, AMQSession.NO_ACKNOWLEDGE);
+
+ data = new byte[length];
+ for(int i = 0; i < data.length; i++)
+ {
+ data[i] = (byte) (i % 100);
+ }
+
+ //set up a consumer
+ session.createConsumer(destination).setMessageListener(this);
+ connection.start();
+
+ //create a publisher
+ MessageProducer producer = session.createProducer(destination, false, false, true);
+
+ //publish at a low volume
+ for(int i = 0; i < count; i++)
+ {
+ BytesMessage msg = session.createBytesMessage();
+ msg.writeBytes(data);
+ msg.setStringProperty("sent-at", Long.toString(System.nanoTime()));
+ producer.send(msg);
+ Thread.sleep(delay);
+ if(++sent % 100 == 0)
+ {
+ System.out.println("Sent " + sent + " of " + count);
+ }
+ }
+
+ waitUntilReceived(sent);
+
+ session.close();
+ connection.close();
+
+ System.out.println("Latency (in nanoseconds): avg=" + (total/sent) + ", min=" + min + ", max=" + max
+ + ", avg(discarding min and max)=" + ((total - min - max) / (sent - 2)));
+ }
+
+
+ private synchronized void waitUntilReceived(int count) throws InterruptedException
+ {
+ waiting = true;
+ while(received < count)
+ {
+ wait();
+ }
+ waiting = false;
+ }
+
+ public void onMessage(Message message)
+ {
+ received++;
+ try
+ {
+ long sent = Long.parseLong(message.getStringProperty("sent-at"));
+ long time = System.nanoTime() - sent;
+ total += time;
+ min = Math.min(min, time);
+ max = Math.max(max, time);
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace();
+ }
+
+ if(waiting){
+ synchronized(this)
+ {
+ notify();
+ }
+ }
+ }
+
+ private static String randomize(String in)
+ {
+ return in + System.currentTimeMillis();
+ }
+
+ public static void main(String[] argv) throws Exception
+ {
+ String host = argv.length > 0 ? argv[0] : "localhost:5672";
+ if("-help".equals(host))
+ {
+ System.out.println("Usage: <broker> <message count> <delay between messages> <message size>");
+ }
+ int count = argv.length > 1 ? Integer.parseInt(argv[1]) : 1000;
+ int delay = argv.length > 2 ? Integer.parseInt(argv[2]) : 1000;
+ int size = argv.length > 3 ? Integer.parseInt(argv[3]) : 512;
+ new LatencyTest(host, count, delay, size);
+ }
+
+
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/mina/AcceptorTest.java b/java/client/src/old_test/java/org/apache/qpid/mina/AcceptorTest.java
new file mode 100644
index 0000000000..f0ac0e6902
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/mina/AcceptorTest.java
@@ -0,0 +1,102 @@
+/*
+ *
+ * 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.mina;
+
+import org.apache.log4j.Logger;
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IoAcceptor;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.transport.socket.nio.SocketAcceptor;
+import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
+import org.apache.mina.transport.socket.nio.SocketSessionConfig;
+import org.apache.qpid.pool.ReadWriteThreadModel;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests MINA socket performance. This acceptor simply reads data from the network and writes it back again.
+ *
+ */
+public class AcceptorTest extends TestCase
+{
+ private static final Logger _logger = Logger.getLogger(AcceptorTest.class);
+
+ public static int PORT = 9999;
+
+ private static class TestHandler extends IoHandlerAdapter
+ {
+ private int _sentCount;
+
+ private int _bytesSent;
+
+ public void messageReceived(IoSession session, Object message) throws Exception
+ {
+ ((ByteBuffer) message).acquire();
+ session.write(message);
+ _logger.debug("Sent response " + ++_sentCount);
+ _bytesSent += ((ByteBuffer)message).remaining();
+ _logger.debug("Bytes sent: " + _bytesSent);
+ }
+
+ public void messageSent(IoSession session, Object message) throws Exception
+ {
+ //((ByteBuffer) message).release();
+ }
+
+ public void exceptionCaught(IoSession session, Throwable cause) throws Exception
+ {
+ _logger.error("Error: " + cause, cause);
+ }
+ }
+
+ public void testStartAcceptor() throws IOException
+ {
+ IoAcceptor acceptor = null;
+ acceptor = new SocketAcceptor();
+
+ SocketAcceptorConfig config = (SocketAcceptorConfig) acceptor.getDefaultConfig();
+ SocketSessionConfig sc = (SocketSessionConfig) config.getSessionConfig();
+ sc.setTcpNoDelay(true);
+ sc.setSendBufferSize(32768);
+ sc.setReceiveBufferSize(32768);
+
+ config.setThreadModel(ReadWriteThreadModel.getInstance());
+
+ acceptor.bind(new InetSocketAddress(PORT),
+ new TestHandler());
+ _logger.info("Bound on port " + PORT);
+ }
+
+ public static void main(String[] args) throws IOException
+ {
+ AcceptorTest a = new AcceptorTest();
+ a.testStartAcceptor();
+ }
+
+ public static junit.framework.Test suite()
+ {
+ return new junit.framework.TestSuite(AcceptorTest.class);
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/mina/BlockingAcceptorTest.java b/java/client/src/old_test/java/org/apache/qpid/mina/BlockingAcceptorTest.java
new file mode 100644
index 0000000000..bfe29c47e6
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/mina/BlockingAcceptorTest.java
@@ -0,0 +1,93 @@
+/*
+ *
+ * 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.mina;
+
+import org.apache.log4j.Logger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+import junit.framework.TestCase;
+
+public class BlockingAcceptorTest extends TestCase
+{
+ private static final Logger _logger = Logger.getLogger(BlockingAcceptorTest.class);
+
+ public static int PORT = 9999;
+
+ public void testStartAcceptor() throws IOException
+ {
+
+ ServerSocket sock = new ServerSocket(PORT);
+
+ sock.setReuseAddress(true);
+ sock.setReceiveBufferSize(32768);
+ _logger.info("Bound on port " + PORT);
+
+ while (true)
+ {
+ final Socket s = sock.accept();
+ _logger.info("Received connection from " + s.getRemoteSocketAddress());
+ s.setReceiveBufferSize(32768);
+ s.setSendBufferSize(32768);
+ s.setTcpNoDelay(true);
+ new Thread(new Runnable()
+ {
+ public void run()
+ {
+ byte[] chunk = new byte[32768];
+ try
+ {
+ InputStream is = s.getInputStream();
+ OutputStream os = s.getOutputStream();
+
+ while (true)
+ {
+ int count = is.read(chunk, 0, chunk.length);
+ if (count > 0)
+ {
+ os.write(chunk, 0, count);
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ _logger.error("Error - closing connection: " + e, e);
+ }
+ }
+ }, "SocketReaderWriter").start();
+ }
+ }
+
+ public static void main(String[] args) throws IOException
+ {
+ BlockingAcceptorTest a = new BlockingAcceptorTest();
+ a.testStartAcceptor();
+ }
+
+ public static junit.framework.Test suite()
+ {
+ return new junit.framework.TestSuite(AcceptorTest.class);
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/mina/WriterTest.java b/java/client/src/old_test/java/org/apache/qpid/mina/WriterTest.java
new file mode 100644
index 0000000000..910345624f
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/mina/WriterTest.java
@@ -0,0 +1,271 @@
+/*
+ *
+ * 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.mina;
+
+import org.apache.log4j.Logger;
+import org.apache.mina.common.*;
+import org.apache.mina.transport.socket.nio.SocketConnector;
+import org.apache.mina.transport.socket.nio.SocketConnectorConfig;
+import org.apache.mina.transport.socket.nio.SocketSessionConfig;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.concurrent.CountDownLatch;
+
+import junit.framework.TestCase;
+
+public class WriterTest extends TestCase
+{
+ private static final Logger _logger = Logger.getLogger(WriterTest.class);
+
+ private static class RunnableWriterTest implements Runnable
+ {
+ private Logger _logger;
+
+ private IoSession _session;
+
+ private long _startTime;
+
+ private long[] _chunkTimes;
+
+ private int _chunkCount = 500000;
+
+ private int _chunkSize = 1024;
+
+ private CountDownLatch _notifier;
+
+ public RunnableWriterTest(Logger logger)
+ {
+ _logger = logger;
+ }
+
+ public void run()
+ {
+ _startTime = System.currentTimeMillis();
+ _notifier = new CountDownLatch(1);
+ for (int i = 0; i < _chunkCount; i++)
+ {
+ ByteBuffer buf = ByteBuffer.allocate(_chunkSize, false);
+ byte check = (byte) (i % 128);
+ buf.put(check);
+ buf.fill((byte)88, buf.remaining());
+ buf.flip();
+ _session.write(buf);
+ }
+
+ try
+ {
+ _logger.info("All buffers sent; waiting for receipt from server");
+ _notifier.await();
+ }
+ catch (InterruptedException e)
+ {
+ }
+ _logger.info("Completed");
+ long totalTime = System.currentTimeMillis() - _startTime;
+ _logger.info("Total time: " + totalTime);
+ _logger.info("MB per second: " + (_chunkSize * _chunkCount)/totalTime);
+ long lastChunkTime = _startTime;
+ double average = 0;
+ for (int i = 0; i < _chunkTimes.length; i++)
+ {
+ if (i == 0)
+ {
+ average = _chunkTimes[i] - _startTime;
+ }
+ else
+ {
+ long delta = _chunkTimes[i] - lastChunkTime;
+ if (delta != 0)
+ {
+ average = (average + delta)/2;
+ }
+ }
+ lastChunkTime = _chunkTimes[i];
+ }
+ _logger.info("Average chunk time: " + average + "ms");
+ CloseFuture cf = _session.close();
+ cf.join();
+ }
+
+ private class WriterHandler extends IoHandlerAdapter
+ {
+ private int _chunksReceived = 0;
+
+ private int _partialBytesRead = 0;
+
+ private byte _partialCheckNumber;
+
+ private int _totalBytesReceived = 0;
+
+ public void messageReceived(IoSession session, Object message) throws Exception
+ {
+ ByteBuffer result = (ByteBuffer) message;
+ _totalBytesReceived += result.remaining();
+ int size = result.remaining();
+ long now = System.currentTimeMillis();
+ if (_partialBytesRead > 0)
+ {
+ int offset = _chunkSize - _partialBytesRead;
+ if (size >= offset)
+ {
+ _chunkTimes[_chunksReceived++] = now;
+ result.position(offset);
+ }
+ else
+ {
+ // have not read even one chunk, including the previous partial bytes
+ _partialBytesRead += size;
+ return;
+ }
+ }
+
+ int chunkCount = result.remaining()/_chunkSize;
+
+ for (int i = 0; i < chunkCount; i++)
+ {
+ _chunkTimes[_chunksReceived++] = now;
+ byte check = result.get();
+ _logger.debug("Check number " + check + " read");
+ if (check != (byte)((_chunksReceived - 1)%128))
+ {
+ _logger.error("Check number " + check + " read when expected " + (_chunksReceived%128));
+ }
+ _logger.debug("Chunk times recorded");
+
+ try
+ {
+ result.skip(_chunkSize - 1);
+ }
+ catch (IllegalArgumentException e)
+ {
+ _logger.error("Position was: " + result.position());
+ _logger.error("Tried to skip to: " + (_chunkSize * i));
+ _logger.error("limit was; " + result.limit());
+ }
+ }
+ _logger.debug("Chunks received now " + _chunksReceived);
+ _logger.debug("Bytes received: " + _totalBytesReceived);
+ _partialBytesRead = result.remaining();
+
+ if (_partialBytesRead > 0)
+ {
+ _partialCheckNumber = result.get();
+ }
+
+ if (_chunksReceived >= _chunkCount)
+ {
+ _notifier.countDown();
+ }
+
+ }
+
+ public void exceptionCaught(IoSession session, Throwable cause) throws Exception
+ {
+ _logger.error("Error: " + cause, cause);
+ }
+ }
+
+ public void startWriter(int chunkSize) throws IOException, InterruptedException
+ {
+ _chunkSize = chunkSize;
+
+ IoConnector ioConnector = null;
+
+ ioConnector = new SocketConnector();
+
+ SocketConnectorConfig cfg = (SocketConnectorConfig) ioConnector.getDefaultConfig();
+ cfg.setThreadModel(ThreadModel.MANUAL);
+ SocketSessionConfig scfg = (SocketSessionConfig) cfg.getSessionConfig();
+ scfg.setTcpNoDelay(true);
+ scfg.setSendBufferSize(32768);
+ scfg.setReceiveBufferSize(32768);
+
+ final InetSocketAddress address = new InetSocketAddress("localhost", AcceptorTest.PORT);
+ _logger.info("Attempting connection to " + address);
+ ConnectFuture future = ioConnector.connect(address, new WriterHandler());
+ // wait for connection to complete
+ future.join();
+ _logger.info("Connection completed");
+ // we call getSession which throws an IOException if there has been an error connecting
+ _session = future.getSession();
+ _chunkTimes = new long[_chunkCount];
+ Thread t = new Thread(this);
+ t.start();
+ t.join();
+ _logger.info("Test completed");
+ }
+ }
+
+ private RunnableWriterTest _runnableWriterTest = new RunnableWriterTest(_logger);
+
+ public void test1k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 1k test");
+ _runnableWriterTest.startWriter(1024);
+ }
+
+ public void test2k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 2k test");
+ _runnableWriterTest.startWriter(2048);
+ }
+
+ public void test4k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 4k test");
+ _runnableWriterTest.startWriter(4096);
+ }
+
+ public void test8k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 8k test");
+ _runnableWriterTest.startWriter(8192);
+ }
+
+ public void test16k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 16k test");
+ _runnableWriterTest.startWriter(16384);
+ }
+
+ public void test32k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 32k test");
+ _runnableWriterTest.startWriter(32768);
+ }
+
+ public static void main(String[] args) throws IOException, InterruptedException
+ {
+ WriterTest w = new WriterTest();
+ //w.test1k();
+ //w.test2k();
+ //w.test4k();
+ w.test8k();
+ //w.test16k();
+ //w.test32k();
+ }
+
+ public static junit.framework.Test suite()
+ {
+ return new junit.framework.TestSuite(WriterTest.class);
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/multiconsumer/AMQTest.java b/java/client/src/old_test/java/org/apache/qpid/multiconsumer/AMQTest.java
new file mode 100644
index 0000000000..db02b9954a
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/multiconsumer/AMQTest.java
@@ -0,0 +1,269 @@
+/*
+ *
+ * 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.multiconsumer;
+
+import java.io.ByteArrayOutputStream;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+
+import javax.jms.Connection;
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.qpid.client.AMQConnectionFactory;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQTopic;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.jms.Session;
+
+/**
+ * Test AMQ.
+ */
+public class AMQTest extends TestCase implements ExceptionListener
+{
+
+ private final static String COMPRESSION_PROPNAME = "_MSGAPI_COMP";
+ private final static String UTF8 = "UTF-8";
+ private static final String SUBJECT = "test.amq";
+ private static final String DUMMYCONTENT = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ private static final String HUGECONTENT;
+
+ private AMQConnection connect = null;
+ private Session pubSession = null;
+ private Session subSession = null;
+ private Topic topic = null;
+
+ static
+ {
+ StringBuilder sb = new StringBuilder(DUMMYCONTENT.length() * 115);
+ for (int i = 0; i < 100; i++)
+ {
+ sb.append(DUMMYCONTENT);
+ }
+ HUGECONTENT = sb.toString();
+ }
+
+ private void setup() throws Exception
+ {
+ connect = new AMQConnection("localhost", 5672, "guest", "guest", "client1", "/");
+ connect.setExceptionListener(this);
+ pubSession = connect.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
+ subSession = connect.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
+ topic = new AMQTopic(pubSession.getDefaultTopicExchangeName(), new AMQShortString(SUBJECT));
+
+ connect.start();
+ }
+
+ public void testMultipleListeners() throws Exception
+ {
+ setup();
+ try
+ {
+ // Create 5 listeners
+ MsgHandler[] listeners = new MsgHandler[5];
+ for (int i = 0; i < listeners.length; i++)
+ {
+ listeners[i] = new MsgHandler();
+ MessageConsumer subscriber = subSession.createConsumer(topic);
+ subscriber.setMessageListener(listeners[i]);
+ }
+ MessageProducer publisher = pubSession.createProducer(topic);
+ // Send a single message
+ TextMessage msg = pubSession.createTextMessage();
+ msg.setText(DUMMYCONTENT);
+ publisher.send(msg);
+ Thread.sleep(5000);
+ // Check listeners to ensure they all got it
+ for (int i = 0; i < listeners.length; i++)
+ {
+ if (listeners[i].isGotIt())
+ {
+ System.out.println("Got callback for listener " + i);
+ }
+ else
+ {
+ TestCase.fail("Listener " + i + " did not get callback");
+ }
+ }
+ }
+ catch (Throwable e)
+ {
+ System.err.println("Error: " + e);
+ e.printStackTrace(System.err);
+ }
+ finally
+ {
+ close();
+ }
+ }
+
+ public void testCompression() throws Exception
+ {
+ setup();
+ String comp = this.compressString(HUGECONTENT);
+ try
+ {
+ MsgHandler listener = new MsgHandler();
+ MessageConsumer subscriber = subSession.createConsumer(topic);
+ subscriber.setMessageListener(listener);
+ MessageProducer publisher = pubSession.createProducer(topic);
+
+ // Send a single message
+ TextMessage msg = pubSession.createTextMessage();
+ // Set the compressed text
+ msg.setText(comp);
+ msg.setBooleanProperty(COMPRESSION_PROPNAME, true);
+ publisher.send(msg);
+ Thread.sleep(1000);
+ // Check listeners to ensure we got it
+ if (listener.isGotIt())
+ {
+ System.out.println("Got callback for listener");
+ }
+ else
+ {
+ TestCase.fail("Listener did not get callback");
+ }
+ }
+ finally
+ {
+ close();
+ }
+ }
+
+ private void close() throws Exception
+ {
+ if (connect != null)
+ {
+ connect.close();
+ }
+ }
+
+ private class MsgHandler implements MessageListener
+ {
+ private boolean gotIt = false;
+
+ public void onMessage(Message msg)
+ {
+ try
+ {
+ TextMessage textMessage = (TextMessage) msg;
+ String string = textMessage.getText();
+ if (string != null && string.length() > 0)
+ {
+ gotIt = true;
+ }
+ if (textMessage.getBooleanProperty(COMPRESSION_PROPNAME))
+ {
+ string = inflateString(string);
+ }
+ System.out.println("Got callback of size " + (string==null?0:string.length()));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public boolean isGotIt()
+ {
+ return this.gotIt;
+ }
+ }
+
+ private String compressString(String string) throws Exception
+ {
+ long start = System.currentTimeMillis();
+ byte[] input = string.getBytes();
+ Deflater compressor = new Deflater(Deflater.BEST_COMPRESSION);
+ compressor.setInput(input);
+ compressor.finish();
+
+ // Get byte array from output of compressor
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(input.length);
+ byte[] buf = new byte[1024];
+ while (!compressor.finished())
+ {
+ int cnt = compressor.deflate(buf);
+ baos.write(buf, 0, cnt);
+ }
+ baos.close();
+ byte[] output = baos.toByteArray();
+
+ // Convert byte array into String
+ byte[] base64 = Base64.encodeBase64(output);
+ String sComp = new String(base64, UTF8);
+
+ long diff = System.currentTimeMillis() - start;
+ System.out.println("Compressed text from " + input.length + " to "
+ + sComp.getBytes().length + " in " + diff + " ms");
+ System.out.println("Compressed text = '" + sComp + "'");
+
+ return sComp;
+ }
+
+ private String inflateString(String string) throws Exception
+ {
+ byte[] input = string.getBytes();
+
+ // First convert Base64 string back to binary array
+ byte[] bytes = Base64.decodeBase64(input);
+
+ // Set string as input data for decompressor
+ Inflater decompressor = new Inflater();
+ decompressor.setInput(bytes);
+
+ // Decompress the data
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length);
+ byte[] buf = new byte[1024];
+ while (!decompressor.finished())
+ {
+ int count = decompressor.inflate(buf);
+ bos.write(buf, 0, count);
+ }
+ bos.close();
+ byte[] output = bos.toByteArray();
+
+ // Get the decompressed data
+ return new String(output, UTF8);
+ }
+
+ /**
+ * @see javax.jms.ExceptionListener#onException(javax.jms.JMSException)
+ */
+ public void onException(JMSException e)
+ {
+ System.err.println(e.getMessage());
+ e.printStackTrace(System.err);
+ }
+
+
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/pubsub1/TestPublisher.java b/java/client/src/old_test/java/org/apache/qpid/pubsub1/TestPublisher.java
new file mode 100644
index 0000000000..37b4ff1498
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/pubsub1/TestPublisher.java
@@ -0,0 +1,176 @@
+/*
+ *
+ * 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.pubsub1;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.url.URLSyntaxException;
+import org.apache.qpid.client.AMQTopic;
+import org.apache.qpid.jms.MessageProducer;
+import org.apache.qpid.jms.Session;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.TextMessage;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * A client that behaves as follows:
+ * <ul><li>Connects to a queue, whose name is specified as a cmd-line argument</li>
+ * <li>Creates a temporary queue</li>
+ * <li>Creates messages containing a property that is the name of the temporary queue</li>
+ * <li>Fires off a message on the original queue and waits for a response on the temporary queue</li>
+ * </ul>
+ *
+ */
+public class TestPublisher
+{
+ private static final Logger _log = Logger.getLogger(TestPublisher.class);
+
+ private AMQConnection _connection;
+
+ private Session _session;
+
+ private class CallbackHandler implements MessageListener
+ {
+ private int _expectedMessageCount;
+
+ private int _actualMessageCount;
+
+ private long _startTime;
+
+ public CallbackHandler(int expectedMessageCount, long startTime)
+ {
+ _expectedMessageCount = expectedMessageCount;
+ _startTime = startTime;
+ }
+
+ public void onMessage(Message m)
+ {
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Message received: " + m);
+ }
+ _actualMessageCount++;
+ if (_actualMessageCount%1000 == 0)
+ {
+ _log.info("Received message count: " + _actualMessageCount);
+ }
+ /*if (!"henson".equals(m.toString()))
+ {
+ _log.error("AbstractJMSMessage response not correct: expected 'henson' but got " + m.toString());
+ }
+ else
+ {
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("AbstractJMSMessage " + m + " received");
+ }
+ else
+ {
+ _log.info("AbstractJMSMessage received");
+ }
+ } */
+
+ if (_actualMessageCount == _expectedMessageCount)
+ {
+ long timeTaken = System.currentTimeMillis() - _startTime;
+ System.out.println("Total time taken to receive " + _expectedMessageCount+ " messages was " +
+ timeTaken + "ms, equivalent to " +
+ (_expectedMessageCount/(timeTaken/1000.0)) + " messages per second");
+ }
+ }
+ }
+
+ public TestPublisher(String host, int port, String clientID, String commandQueueName,
+ final int messageCount) throws AMQException, URLSyntaxException
+ {
+ try
+ {
+ createConnection(host, port, clientID);
+
+ _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ AMQTopic destination = new AMQTopic(_session.getDefaultTopicExchangeName(), new AMQShortString(commandQueueName));
+ MessageProducer producer = (MessageProducer) _session.createProducer(destination);
+
+ _connection.start();
+ //TextMessage msg = _session.createTextMessage(tempDestination.getQueueName() + "/Presented to in conjunction with Mahnah Mahnah and the Snowths");
+ final long startTime = System.currentTimeMillis();
+
+ for (int i = 0; i < messageCount; i++)
+ {
+ TextMessage msg = _session.createTextMessage(destination.getTopicName() + "/Presented to in conjunction with Mahnah Mahnah and the Snowths: " + i);
+
+ //msg.setIntProperty("a",i % 2);
+ //msg.setIntProperty("b",i % 4);
+
+ producer.send(msg);
+ }
+ _log.info("Finished sending " + messageCount + " messages");
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void createConnection(String host, int port, String clientID) throws AMQException, URLSyntaxException
+ {
+ _connection = new AMQConnection(host, port, "guest", "guest",
+ clientID, "/test");
+ }
+
+ /**
+ *
+ * @param args argument 1 if present specifies the name of the temporary queue to create. Leaving it blank
+ * means the server will allocate a name.
+ */
+ public static void main(String[] args) throws URLSyntaxException
+ {
+ if (args.length == 0)
+ {
+ System.err.println("Usage: TestPublisher <host> <port> <command queue name> <number of messages>");
+ }
+ try
+ {
+ int port = Integer.parseInt(args[1]);
+ InetAddress address = InetAddress.getLocalHost();
+ String clientID = address.getHostName() + System.currentTimeMillis();
+ TestPublisher client = new TestPublisher(args[0], port, clientID, args[2], Integer.parseInt(args[3]));
+ }
+ catch (UnknownHostException e)
+ {
+ e.printStackTrace();
+ }
+ catch (AMQException e)
+ {
+ System.err.println("Error in client: " + e);
+ e.printStackTrace();
+ }
+
+ //System.exit(0);
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/pubsub1/TestSubscriber.java b/java/client/src/old_test/java/org/apache/qpid/pubsub1/TestSubscriber.java
new file mode 100644
index 0000000000..450d9b3914
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/pubsub1/TestSubscriber.java
@@ -0,0 +1,122 @@
+/*
+ *
+ * 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.pubsub1;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQTopic;
+import org.apache.qpid.jms.Session;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.framing.AMQShortString;
+
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.Topic;
+import java.net.InetAddress;
+
+public class TestSubscriber
+{
+ private static final Logger _logger = Logger.getLogger(TestSubscriber.class);
+
+ private static class TestMessageListener implements MessageListener
+ {
+ private String _name;
+
+ private int _expectedMessageCount;
+
+ private int _messageCount;
+
+ private long _startTime = 0;
+
+ public TestMessageListener(String name, int expectedMessageCount)
+ {
+ _name = name;
+ _expectedMessageCount = expectedMessageCount;
+ }
+
+ public void onMessage(javax.jms.Message message)
+ {
+ if (_messageCount++ == 0)
+ {
+ _startTime = System.currentTimeMillis();
+ }
+ if (_logger.isInfoEnabled())
+ {
+ _logger.info(_name + " got message '" + message + "'");
+ }
+ if (_messageCount == _expectedMessageCount)
+ {
+ long totalTime = System.currentTimeMillis() - _startTime;
+ _logger.error(_name + ": Total time to receive " + _messageCount + " messages was " +
+ totalTime + "ms. Rate is " + (_messageCount/(totalTime/1000.0)));
+ }
+ if (_messageCount > _expectedMessageCount)
+ {
+ _logger.error("Oops! More messages received than expected (" + _messageCount + ")");
+ }
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ _logger.info("Starting...");
+
+ if (args.length != 7)
+ {
+ System.out.println("Usage: host port username password virtual-path expectedMessageCount selector");
+ System.exit(1);
+ }
+ try
+ {
+ InetAddress address = InetAddress.getLocalHost();
+ AMQConnection con1 = new AMQConnection(args[0], Integer.parseInt(args[1]), args[2], args[3],
+ address.getHostName(), args[4]);
+ final Session session1 = con1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ AMQConnection con2 = new AMQConnection(args[0], Integer.parseInt(args[1]), args[2], args[3],
+ address.getHostName(), args[4]);
+ final Session session2 = con2.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ String selector = args[6];
+
+ final int expectedMessageCount = Integer.parseInt(args[5]);
+ _logger.info("Message selector is <" + selector + ">...");
+
+ Topic t = new AMQTopic(session1.getDefaultTopicExchangeName(), new AMQShortString("cbr"));
+ MessageConsumer consumer1 = session1.createConsumer(t,
+ 100, false, false, selector);
+ MessageConsumer consumer2 = session2.createConsumer(t,
+ 100, false, false, selector);
+
+ consumer1.setMessageListener(new TestMessageListener("ML 1", expectedMessageCount));
+ consumer2.setMessageListener(new TestMessageListener("ML 2", expectedMessageCount));
+ con1.start();
+ con2.start();
+ }
+ catch (Throwable t)
+ {
+ System.err.println("Fatal error: " + t);
+ t.printStackTrace();
+ }
+
+ System.out.println("Waiting...");
+ }
+}
+
diff --git a/java/client/src/old_test/java/org/apache/qpid/test/unit/client/connection/TestManyConnections.java b/java/client/src/old_test/java/org/apache/qpid/test/unit/client/connection/TestManyConnections.java
new file mode 100644
index 0000000000..f59b36166a
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/test/unit/client/connection/TestManyConnections.java
@@ -0,0 +1,95 @@
+/*
+ *
+ * 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.AMQException;
+import org.apache.qpid.url.URLSyntaxException;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.log4j.Logger;
+
+import junit.framework.TestCase;
+
+public class TestManyConnections extends TestCase
+{
+ private static final Logger _log = Logger.getLogger(TestManyConnections.class);
+
+ private AMQConnection[] _connections;
+
+ private void createConnection(int index, String brokerHosts, String clientID, String username, String password,
+ String vpath) throws AMQException, URLSyntaxException
+ {
+ _connections[index] = new AMQConnection(brokerHosts, username, password,
+ clientID, vpath);
+ }
+
+ private void createConnections(int count) throws AMQException, URLSyntaxException
+ {
+ _connections = new AMQConnection[count];
+ long startTime = System.currentTimeMillis();
+ for (int i = 0; i < count; i++)
+ {
+ createConnection(i, "vm://:1", "myClient" + i, "guest", "guest", "test");
+ }
+ long endTime = System.currentTimeMillis();
+ _log.info("Time to create " + count + " connections: " + (endTime - startTime) +
+ "ms");
+ }
+
+ public void testCreate10Connections() throws AMQException, URLSyntaxException
+ {
+ createConnections(10);
+ }
+
+ public void testCreate50Connections() throws AMQException, URLSyntaxException
+ {
+ createConnections(50);
+ }
+
+ public void testCreate100Connections() throws AMQException, URLSyntaxException
+ {
+ createConnections(100);
+ }
+
+ public void testCreate250Connections() throws AMQException, URLSyntaxException
+ {
+ createConnections(250);
+ }
+
+ public void testCreate500Connections() throws AMQException, URLSyntaxException
+ {
+ createConnections(500);
+ }
+
+ public void testCreate1000Connections() throws AMQException, URLSyntaxException
+ {
+ createConnections(1000);
+ }
+
+ public void testCreate5000Connections() throws AMQException, URLSyntaxException
+ {
+ createConnections(5000);
+ }
+
+ public static junit.framework.Test suite()
+ {
+ return new junit.framework.TestSuite(TestManyConnections.class);
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/PropertiesFileInitialContextFactoryTest.java b/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/PropertiesFileInitialContextFactoryTest.java
new file mode 100644
index 0000000000..5ab5722146
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/PropertiesFileInitialContextFactoryTest.java
@@ -0,0 +1,153 @@
+/*
+ *
+ * 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.jndi;
+
+import org.apache.qpid.client.AMQConnectionFactory;
+import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.client.AMQTopic;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactory;
+import java.util.Properties;
+import java.io.InputStream;
+
+
+import junit.framework.TestCase;
+
+public class PropertiesFileInitialContextFactoryTest extends TestCase
+{
+ InitialContextFactory contextFactory;
+ Properties _properties;
+ Properties _fileProperties;
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ //create simple set of hardcoded props
+ _properties = new Properties();
+ _properties.put("java.naming.factory.initial", "org.apache.qpid.jndi.PropertiesFileInitialContextFactory");
+ _properties.put("connectionfactory.local", "amqp://guest:guest@clientid/testpath?brokerlist='vm://:1'");
+ _properties.put("queue.MyQueue", "example.MyQueue");
+ _properties.put("topic.ibmStocks", "stocks.nyse.ibm");
+ _properties.put("destination.direct", "direct://amq.direct//directQueue");
+
+ //create properties from file as a more realistic test
+ _fileProperties = new Properties();
+ ClassLoader cl = this.getClass().getClassLoader();
+ InputStream is = cl.getResourceAsStream("org/apache/qpid/test/unit/jndi/example.properties");
+ _fileProperties.load(is);
+ }
+
+ /**
+ * Test using hardcoded properties
+ */
+ public void testWithoutFile()
+ {
+ Context ctx = null;
+
+ try
+ {
+ ctx = new InitialContext(_properties);
+ }
+ catch (NamingException ne)
+ {
+ fail("Error loading context:" + ne);
+ }
+
+ checkPropertiesMatch(ctx, "Using hardcoded properties: ");
+ }
+
+ /**
+ * Test using properties from example file
+ */
+ public void testWithFile()
+ {
+ Context ctx = null;
+
+ try
+ {
+ ctx = new InitialContext(_fileProperties);
+ }
+ catch (Exception e)
+ {
+ fail("Error loading context:" + e);
+ }
+
+ checkPropertiesMatch(ctx, "Using properties from file: ");
+ }
+
+ public void tearDown()
+ {
+ _properties = null;
+ _fileProperties = null;
+ }
+
+ public static junit.framework.Test suite()
+ {
+ return new junit.framework.TestSuite(PropertiesFileInitialContextFactoryTest.class);
+ }
+
+ private void checkPropertiesMatch(Context ctx, String errorInfo)
+ {
+ try
+ {
+ AMQConnectionFactory cf = (AMQConnectionFactory) ctx.lookup("local");
+ assertEquals("amqp://guest:guest@clientid/testpath?brokerlist='vm://:1'", cf.getConnectionURL().toString());
+ }
+ catch (NamingException ne)
+ {
+ fail(errorInfo + "Unable to create Connection Factory:" + ne);
+ }
+
+ try
+ {
+ AMQQueue queue = (AMQQueue) ctx.lookup("MyQueue");
+ assertEquals("example.MyQueue", queue.getRoutingKey().toString());
+ }
+ catch (NamingException ne)
+ {
+ fail(errorInfo + "Unable to create queue:" + ne);
+ }
+
+ try
+ {
+ AMQTopic topic = (AMQTopic) ctx.lookup("ibmStocks");
+ assertEquals("stocks.nyse.ibm", topic.getTopicName().toString());
+ }
+ catch (Exception ne)
+ {
+ fail(errorInfo + "Unable to create topic:" + ne);
+ }
+
+ try
+ {
+ AMQQueue direct = (AMQQueue) ctx.lookup("direct");
+ assertEquals("directQueue", direct.getRoutingKey().toString());
+ }
+ catch (NamingException ne)
+ {
+ fail(errorInfo + "Unable to create direct destination:" + ne);
+ }
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/example.properties b/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/example.properties
new file mode 100644
index 0000000000..ea9dc5ae0e
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/example.properties
@@ -0,0 +1,38 @@
+# 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.
+
+java.naming.factory.initial = org.apache.qpid.jndi.PropertiesFileInitialContextFactory
+
+# use the following property to configure the default connector
+#java.naming.provider.url - ignored.
+
+# register some connection factories
+# connectionfactory.[jndiname] = [ConnectionURL]
+connectionfactory.local = amqp://guest:guest@clientid/testpath?brokerlist='vm://:1'
+
+# register some queues in JNDI using the form
+# queue.[jndiName] = [physicalName]
+queue.MyQueue = example.MyQueue
+
+# register some topics in JNDI using the form
+# topic.[jndiName] = [physicalName]
+topic.ibmStocks = stocks.nyse.ibm
+
+# Register an AMQP destination in JNDI
+# NOTE: Qpid currently only supports direct,topics and headers
+# destination.[jniName] = [BindingURL]
+destination.direct = direct://amq.direct//directQueue
diff --git a/java/client/src/old_test/java/org/apache/qpid/topic/Config.java b/java/client/src/old_test/java/org/apache/qpid/topic/Config.java
new file mode 100644
index 0000000000..bb740f9094
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/topic/Config.java
@@ -0,0 +1,243 @@
+/*
+ *
+ * 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.topic;
+
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.config.ConnectorConfig;
+import org.apache.qpid.config.ConnectionFactoryInitialiser;
+import org.apache.qpid.config.Connector;
+import org.apache.qpid.config.AbstractConfig;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+
+class Config extends AbstractConfig implements ConnectorConfig
+{
+
+ private String host = "localhost";
+ private int port = 5672;
+ private String factory = null;
+
+ private int payload = 256;
+ private int messages = 1000;
+ private int clients = 1;
+ private int batch = 1;
+ private long delay = 1;
+ private int warmup;
+ private int ackMode= AMQSession.NO_ACKNOWLEDGE;
+ private String clientId;
+ private String subscriptionId;
+ private boolean persistent;
+
+ public Config()
+ {
+ }
+
+ int getAckMode()
+ {
+ return ackMode;
+ }
+
+ void setPayload(int payload)
+ {
+ this.payload = payload;
+ }
+
+ int getPayload()
+ {
+ return payload;
+ }
+
+ void setClients(int clients)
+ {
+ this.clients = clients;
+ }
+
+ int getClients()
+ {
+ return clients;
+ }
+
+ void setMessages(int messages)
+ {
+ this.messages = messages;
+ }
+
+ int getMessages()
+ {
+ return messages;
+ }
+
+ public String getHost()
+ {
+ return host;
+ }
+
+ public void setHost(String host)
+ {
+ this.host = host;
+ }
+
+ public int getPort()
+ {
+ return port;
+ }
+
+ public String getFactory()
+ {
+ return factory;
+ }
+
+ public void setPort(int port)
+ {
+ this.port = port;
+ }
+
+ int getBatch()
+ {
+ return batch;
+ }
+
+ void setBatch(int batch)
+ {
+ this.batch = batch;
+ }
+
+ int getWarmup()
+ {
+ return warmup;
+ }
+
+ void setWarmup(int warmup)
+ {
+ this.warmup = warmup;
+ }
+
+ public long getDelay()
+ {
+ return delay;
+ }
+
+ public void setDelay(long delay)
+ {
+ this.delay = delay;
+ }
+
+ String getClientId()
+ {
+ return clientId;
+ }
+
+ String getSubscriptionId()
+ {
+ return subscriptionId;
+ }
+
+ boolean usePersistentMessages()
+ {
+ return persistent;
+ }
+
+ public 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);
+ }
+ }
+ else if("-payload".equalsIgnoreCase(key))
+ {
+ setPayload(parseInt("Bad payload size", value));
+ }
+ else if("-messages".equalsIgnoreCase(key))
+ {
+ setMessages(parseInt("Bad message count", value));
+ }
+ else if("-clients".equalsIgnoreCase(key))
+ {
+ setClients(parseInt("Bad client count", value));
+ }
+ else if("-batch".equalsIgnoreCase(key))
+ {
+ setBatch(parseInt("Bad batch count", value));
+ }
+ else if("-delay".equalsIgnoreCase(key))
+ {
+ setDelay(parseLong("Bad batch delay", value));
+ }
+ else if("-warmup".equalsIgnoreCase(key))
+ {
+ setWarmup(parseInt("Bad warmup count", value));
+ }
+ else if("-ack".equalsIgnoreCase(key))
+ {
+ ackMode = parseInt("Bad ack mode", value);
+ }
+ else if("-factory".equalsIgnoreCase(key))
+ {
+ factory = value;
+ }
+ else if("-clientId".equalsIgnoreCase(key))
+ {
+ clientId = value;
+ }
+ else if("-subscriptionId".equalsIgnoreCase(key))
+ {
+ subscriptionId = value;
+ }
+ else if("-persistent".equalsIgnoreCase(key))
+ {
+ persistent = "true".equalsIgnoreCase(value);
+ }
+ else
+ {
+ System.out.println("Ignoring unrecognised option: " + key);
+ }
+ }
+
+ static String getAckModeDescription(int ackMode)
+ {
+ switch(ackMode)
+ {
+ case AMQSession.NO_ACKNOWLEDGE: return "NO_ACKNOWLEDGE";
+ case AMQSession.AUTO_ACKNOWLEDGE: return "AUTO_ACKNOWLEDGE";
+ case AMQSession.CLIENT_ACKNOWLEDGE: return "CLIENT_ACKNOWLEDGE";
+ case AMQSession.DUPS_OK_ACKNOWLEDGE: return "DUPS_OK_ACKNOWELDGE";
+ case AMQSession.PRE_ACKNOWLEDGE: return "PRE_ACKNOWLEDGE";
+ }
+ return "AckMode=" + ackMode;
+ }
+
+ public Connection createConnection() throws Exception
+ {
+ return new Connector().createConnection(this);
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/topic/Listener.java b/java/client/src/old_test/java/org/apache/qpid/topic/Listener.java
new file mode 100644
index 0000000000..47c608cfe4
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/topic/Listener.java
@@ -0,0 +1,141 @@
+/*
+ *
+ * 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.topic;
+
+import javax.jms.Connection;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+
+public class Listener implements MessageListener
+{
+ private final Connection _connection;
+ private final MessageProducer _controller;
+ private final javax.jms.Session _session;
+ private final MessageFactory _factory;
+ private boolean init;
+ private int count;
+ private long start;
+
+ Listener(Connection connection, int ackMode) throws Exception
+ {
+ this(connection, ackMode, null);
+ }
+
+ Listener(Connection connection, int ackMode, String name) throws Exception
+ {
+ _connection = connection;
+ _session = connection.createSession(false, ackMode);
+ _factory = new MessageFactory(_session);
+
+ //register for events
+ if(name == null)
+ {
+ _factory.createTopicConsumer().setMessageListener(this);
+ }
+ else
+ {
+ _factory.createDurableTopicConsumer(name).setMessageListener(this);
+ }
+
+ _connection.start();
+
+ _controller = _factory.createControlPublisher();
+ System.out.println("Waiting for messages " +
+ Config.getAckModeDescription(ackMode)
+ + (name == null ? "" : " (subscribed with name " + name + " and client id " + connection.getClientID() + ")")
+ + "...");
+
+ }
+
+ private void shutdown()
+ {
+ try
+ {
+ _session.close();
+ _connection.stop();
+ _connection.close();
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace(System.out);
+ }
+ }
+
+ private void report()
+ {
+ try
+ {
+ String msg = getReport();
+ _controller.send(_factory.createReportResponseMessage(msg));
+ System.out.println("Sent report: " + msg);
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace(System.out);
+ }
+ }
+
+ private String getReport()
+ {
+ long time = (System.currentTimeMillis() - start);
+ return "Received " + count + " in " + time + "ms";
+ }
+
+ public void onMessage(Message message)
+ {
+ if(!init)
+ {
+ start = System.currentTimeMillis();
+ count = 0;
+ init = true;
+ }
+
+ if(_factory.isShutdown(message))
+ {
+ shutdown();
+ }
+ else if(_factory.isReport(message))
+ {
+ //send a report:
+ report();
+ init = false;
+ }
+ else if (++count % 100 == 0)
+ {
+ System.out.println("Received " + count + " messages.");
+ }
+ }
+
+ public static void main(String[] argv) throws Exception
+ {
+ Config config = new Config();
+ config.setOptions(argv);
+
+ Connection con = config.createConnection();
+ if(config.getClientId() != null)
+ {
+ con.setClientID(config.getClientId());
+ }
+ new Listener(con, config.getAckMode(), config.getSubscriptionId());
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/topic/MessageFactory.java b/java/client/src/old_test/java/org/apache/qpid/topic/MessageFactory.java
new file mode 100644
index 0000000000..39d64069d1
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/topic/MessageFactory.java
@@ -0,0 +1,155 @@
+/*
+ *
+ * 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.topic;
+
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.client.AMQTopic;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.framing.AMQShortString;
+
+import javax.jms.*;
+
+/**
+ */
+class MessageFactory
+{
+ private static final char[] DATA = "abcdefghijklmnopqrstuvwxyz".toCharArray();
+
+ private final Session _session;
+ private final Topic _topic;
+ private final Topic _control;
+ private final byte[] _payload;
+
+
+ MessageFactory(Session session) throws JMSException
+ {
+ this(session, 256);
+ }
+
+ MessageFactory(Session session, int size) throws JMSException
+ {
+ _session = session;
+ if(session instanceof AMQSession)
+ {
+ _topic = new AMQTopic(((AMQSession)session).getDefaultTopicExchangeName(),new AMQShortString("topictest.messages"));
+ _control = new AMQTopic(((AMQSession)session).getDefaultTopicExchangeName(),new AMQShortString("topictest.control"));
+ }
+ else
+ {
+ _topic = session.createTopic("topictest.messages");
+ _control = session.createTopic("topictest.control");
+ }
+ _payload = new byte[size];
+
+ for(int i = 0; i < size; i++)
+ {
+ _payload[i] = (byte) DATA[i % DATA.length];
+ }
+ }
+
+ Topic getTopic()
+ {
+ return _topic;
+ }
+
+ Message createEventMessage() throws JMSException
+ {
+ BytesMessage msg = _session.createBytesMessage();
+ msg.writeBytes(_payload);
+ return msg;
+ }
+
+ Message createShutdownMessage() throws JMSException
+ {
+ return _session.createTextMessage("SHUTDOWN");
+ }
+
+ Message createReportRequestMessage() throws JMSException
+ {
+ return _session.createTextMessage("REPORT");
+ }
+
+ Message createReportResponseMessage(String msg) throws JMSException
+ {
+ return _session.createTextMessage(msg);
+ }
+
+ boolean isShutdown(Message m)
+ {
+ return checkText(m, "SHUTDOWN");
+ }
+
+ boolean isReport(Message m)
+ {
+ return checkText(m, "REPORT");
+ }
+
+ Object getReport(Message m)
+ {
+ try
+ {
+ return ((TextMessage) m).getText();
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace(System.out);
+ return e.toString();
+ }
+ }
+
+ MessageConsumer createTopicConsumer() throws Exception
+ {
+ return _session.createConsumer(_topic);
+ }
+
+ MessageConsumer createDurableTopicConsumer(String name) throws Exception
+ {
+ return _session.createDurableSubscriber(_topic, name);
+ }
+
+ MessageConsumer createControlConsumer() throws Exception
+ {
+ return _session.createConsumer(_control);
+ }
+
+ MessageProducer createTopicPublisher() throws Exception
+ {
+ return _session.createProducer(_topic);
+ }
+
+ MessageProducer createControlPublisher() throws Exception
+ {
+ return _session.createProducer(_control);
+ }
+
+ private static boolean checkText(Message m, String s)
+ {
+ try
+ {
+ return m instanceof TextMessage && ((TextMessage) m).getText().equals(s);
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace(System.out);
+ return false;
+ }
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/topic/Publisher.java b/java/client/src/old_test/java/org/apache/qpid/topic/Publisher.java
new file mode 100644
index 0000000000..d788029ee9
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/topic/Publisher.java
@@ -0,0 +1,175 @@
+/*
+ *
+ * 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.topic;
+
+import javax.jms.*;
+
+public class Publisher implements MessageListener
+{
+ private final Object _lock = new Object();
+ private final Connection _connection;
+ private final Session _session;
+ private final MessageFactory _factory;
+ private final MessageProducer _publisher;
+ private int _count;
+
+ Publisher(Connection connection, int size, int ackMode, boolean persistent) throws Exception
+ {
+ _connection = connection;
+ _session = _connection.createSession(false, ackMode);
+ _factory = new MessageFactory(_session, size);
+ _publisher = _factory.createTopicPublisher();
+ _publisher.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+ System.out.println("Publishing " + (persistent ? "persistent" : "non-persistent") + " messages of " + size + " bytes, " + Config.getAckModeDescription(ackMode) + ".");
+ }
+
+ private void test(Config config) throws Exception
+ {
+ test(config.getBatch(), config.getDelay(), config.getMessages(), config.getClients(), config.getWarmup());
+ }
+
+ private void test(int batches, long delay, int msgCount, int consumerCount, int warmup) throws Exception
+ {
+ _factory.createControlConsumer().setMessageListener(this);
+ _connection.start();
+
+ if(warmup > 0)
+ {
+ System.out.println("Runing warmup (" + warmup + " msgs)");
+ long time = batch(warmup, consumerCount);
+ System.out.println("Warmup completed in " + time + "ms");
+ }
+
+ long[] times = new long[batches];
+ for(int i = 0; i < batches; i++)
+ {
+ if(i > 0) Thread.sleep(delay*1000);
+ times[i] = batch(msgCount, consumerCount);
+ System.out.println("Batch " + (i+1) + " of " + batches + " completed in " + times[i] + " ms.");
+ }
+
+ long min = min(times);
+ long max = max(times);
+ System.out.println("min: " + min + ", max: " + max + " avg: " + avg(times, min, max));
+
+ //request shutdown
+ _publisher.send(_factory.createShutdownMessage());
+
+ _connection.stop();
+ _connection.close();
+ }
+
+ private long batch(int msgCount, int consumerCount) throws Exception
+ {
+ _count = consumerCount;
+ long start = System.currentTimeMillis();
+ publish(msgCount);
+ waitForCompletion(consumerCount);
+ return System.currentTimeMillis() - start;
+ }
+
+ private void publish(int count) throws Exception
+ {
+
+ //send events
+ for (int i = 0; i < count; i++)
+ {
+ _publisher.send(_factory.createEventMessage());
+ if ((i + 1) % 100 == 0)
+ {
+ System.out.println("Sent " + (i + 1) + " messages");
+ }
+ }
+
+ //request report
+ _publisher.send(_factory.createReportRequestMessage());
+ }
+
+ private void waitForCompletion(int consumers) throws Exception
+ {
+ System.out.println("Waiting for completion...");
+ synchronized (_lock)
+ {
+ while (_count > 0)
+ {
+ _lock.wait();
+ }
+ }
+ }
+
+
+ public void onMessage(Message message)
+ {
+ System.out.println("Received report " + _factory.getReport(message) + " " + --_count + " remaining");
+ if (_count == 0)
+ {
+ synchronized (_lock)
+ {
+ _lock.notify();
+ }
+ }
+ }
+
+ static long min(long[] times)
+ {
+ long min = times.length > 0 ? times[0] : 0;
+ for(int i = 0; i < times.length; i++)
+ {
+ min = Math.min(min, times[i]);
+ }
+ return min;
+ }
+
+ static long max(long[] times)
+ {
+ long max = times.length > 0 ? times[0] : 0;
+ for(int i = 0; i < times.length; i++)
+ {
+ max = Math.max(max, times[i]);
+ }
+ return max;
+ }
+
+ static long avg(long[] times, long min, long max)
+ {
+ long sum = 0;
+ for(int i = 0; i < times.length; i++)
+ {
+ sum += times[i];
+ }
+ sum -= min;
+ sum -= max;
+
+ return (sum / (times.length - 2));
+ }
+
+ public static void main(String[] argv) throws Exception
+ {
+ Config config = new Config();
+ config.setOptions(argv);
+
+ Connection con = config.createConnection();
+ int size = config.getPayload();
+ int ackMode = config.getAckMode();
+ boolean persistent = config.usePersistentMessages();
+ new Publisher(con, size, ackMode, persistent).test(config);
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/transacted/Config.java b/java/client/src/old_test/java/org/apache/qpid/transacted/Config.java
new file mode 100644
index 0000000000..bd104e5407
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/transacted/Config.java
@@ -0,0 +1,110 @@
+/*
+ *
+ * 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.transacted;
+
+import org.apache.qpid.config.ConnectorConfig;
+import org.apache.qpid.config.AbstractConfig;
+import org.apache.qpid.config.Connector;
+
+import javax.jms.Connection;
+
+class Config extends AbstractConfig implements ConnectorConfig
+{
+ private String host = "localhost";
+ private int port = 5672;
+ private String factory;
+ private boolean echo;
+ private int batch = 100;
+ private boolean persistent = true;
+
+ Config(String[] argv)
+ {
+ setOptions(argv);
+ }
+
+ Connection createConnection() throws Exception
+ {
+ return new Connector().createConnection(this);
+ }
+
+ public boolean isEchoOn()
+ {
+ return echo;
+ }
+
+ public boolean usePersistentMessages()
+ {
+ return persistent;
+ }
+
+ public int getBatchSize()
+ {
+ return batch;
+ }
+
+ public String getHost()
+ {
+ return host;
+ }
+
+ public int getPort()
+ {
+ return port;
+ }
+
+ public String getFactory()
+ {
+ return factory;
+ }
+
+ public void setOption(String key, String value)
+ {
+ if("-host".equalsIgnoreCase(key))
+ {
+ host = value;
+ }
+ else if("-port".equalsIgnoreCase(key))
+ {
+ port = parseInt("Bad port number", value);
+ }
+ else if("-factory".equalsIgnoreCase(key))
+ {
+ factory = value;
+ }
+ else if("-echo".equalsIgnoreCase(key))
+ {
+ echo = "true".equalsIgnoreCase(value);
+ }
+ else if("-persistent".equalsIgnoreCase(key))
+ {
+ persistent = "true".equalsIgnoreCase(value);
+ }
+ else if("-batch".equalsIgnoreCase(key))
+ {
+ batch = parseInt("Bad batch size", value);
+ }
+ else
+ {
+ System.out.println("Ignoring nrecognised option " + key);
+ }
+ }
+
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/transacted/Ping.java b/java/client/src/old_test/java/org/apache/qpid/transacted/Ping.java
new file mode 100644
index 0000000000..8f15bf089e
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/transacted/Ping.java
@@ -0,0 +1,45 @@
+/*
+ *
+ * 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.transacted;
+
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.client.AMQQueue;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import java.util.Arrays;
+
+public class Ping
+{
+ public static void main(String[] argv) throws Exception
+ {
+ Config config = new Config(argv);
+ Connection con = config.createConnection();
+ con.setClientID("ping");
+ new Relay(new AMQQueue(ExchangeDefaults.DIRECT_EXCHANGE_NAME, new AMQShortString("ping")), new AMQQueue(ExchangeDefaults.DIRECT_EXCHANGE_NAME, new AMQShortString("pong")), con,
+ config.isEchoOn(),
+ config.getBatchSize(),
+ config.usePersistentMessages()).start();
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/transacted/Pong.java b/java/client/src/old_test/java/org/apache/qpid/transacted/Pong.java
new file mode 100644
index 0000000000..f4f4b20d7c
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/transacted/Pong.java
@@ -0,0 +1,45 @@
+/*
+ *
+ * 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.transacted;
+
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.client.AMQQueue;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+
+public class Pong
+{
+ public static void main(String[] argv) throws Exception
+ {
+ Config config = new Config(argv);
+ Connection con = config.createConnection();
+ con.setClientID("pong");
+ new Relay(new AMQQueue(ExchangeDefaults.DIRECT_EXCHANGE_NAME, new AMQShortString("pong")), new AMQQueue(ExchangeDefaults.DIRECT_EXCHANGE_NAME, new AMQShortString("ping")), con,
+ config.isEchoOn(),
+ config.getBatchSize(),
+ config.usePersistentMessages()).start();
+
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/transacted/Relay.java b/java/client/src/old_test/java/org/apache/qpid/transacted/Relay.java
new file mode 100644
index 0000000000..cede95e5f0
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/transacted/Relay.java
@@ -0,0 +1,127 @@
+/*
+ *
+ * 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.transacted;
+
+import org.apache.qpid.client.AMQSession;
+
+import javax.jms.MessageProducer;
+import javax.jms.MessageConsumer;
+import javax.jms.Session;
+import javax.jms.Destination;
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.TextMessage;
+import javax.jms.DeliveryMode;
+
+class Relay implements Runnable
+{
+ private final Connection _con;
+ private final Session _session;
+ private final MessageConsumer _src;
+ private final MessageProducer _dest;
+ private final int _batch;
+ private final boolean _echo;
+ private int _counter;
+ private long start;
+ private boolean _running;
+
+ Relay(Destination src, Destination dest, Connection con) throws JMSException
+ {
+ this(src, dest, con, false, 100, true);
+ }
+
+ Relay(Destination src, Destination dest, Connection con, boolean echo, int batch, boolean persistent) throws JMSException
+ {
+ _echo = echo;
+ _batch = batch;
+ _con = con;
+ _session = con.createSession(true, AMQSession.NO_ACKNOWLEDGE);
+ _src = _session.createConsumer(src);
+ _dest = _session.createProducer(dest);
+ _dest.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+
+ }
+
+ public void run()
+ {
+ start = System.currentTimeMillis();
+ try{
+ while(true) relay();
+ }
+ catch(JMSException e)
+ {
+ e.printStackTrace();
+ }
+ try
+ {
+ _session.close();
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ void relay() throws JMSException
+ {
+ _dest.send(relay(_src.receive()));
+ _session.commit();
+ }
+
+ Message relay(Message in) throws JMSException
+ {
+ if(!_running)
+ {
+ System.out.println(_con.getClientID() + " started.");
+ _running = true;
+ }
+ if(++_counter % _batch == 0)
+ {
+ long time = System.currentTimeMillis() - start;
+ System.out.println(_batch + " iterations performed in " + time + " ms");
+ try
+ {
+ Thread.sleep(100);
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ start = System.currentTimeMillis();
+ }
+ if(_echo)
+ {
+ System.out.println("Received: " + ((TextMessage) in).getText());
+ }
+ return _session.createTextMessage(_con.getClientID() + _counter);
+ }
+
+ void start() throws InterruptedException, JMSException
+ {
+ Thread runner = new Thread(this);
+ runner.start();
+ _con.start();
+ System.out.println(_con.getClientID() + " waiting...");
+ runner.join();
+ _con.close();
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/transacted/Start.java b/java/client/src/old_test/java/org/apache/qpid/transacted/Start.java
new file mode 100644
index 0000000000..de718d828a
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/transacted/Start.java
@@ -0,0 +1,44 @@
+/*
+ *
+ * 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.transacted;
+
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.client.AMQQueue;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.Session;
+
+public class Start
+{
+ public static void main(String[] argv) throws Exception
+ {
+ Connection con = new Config(argv).createConnection();
+ AMQQueue ping = new AMQQueue(ExchangeDefaults.DIRECT_EXCHANGE_NAME, new AMQShortString("ping"));
+ Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ session.createProducer(ping).send(session.createTextMessage("start"));
+ session.close();
+ con.close();
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/weblogic/ServiceProvider.java b/java/client/src/old_test/java/org/apache/qpid/weblogic/ServiceProvider.java
new file mode 100644
index 0000000000..71d806b338
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/weblogic/ServiceProvider.java
@@ -0,0 +1,151 @@
+/*
+ *
+ * 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.weblogic;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQDestination;
+
+import javax.jms.*;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.Context;
+import java.net.InetAddress;
+import java.util.Hashtable;
+
+public class ServiceProvider
+{
+ private static final String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
+ private static final String JMS_FACTORY = "transientJMSConnectionFactory";
+
+ private static final Logger _logger = Logger.getLogger(ServiceProvider.class);
+
+ private static MessageProducer _destinationProducer;
+
+ private static Queue _destinationQ;
+
+ public static void main(String[] args)
+ {
+ _logger.info("Starting...");
+
+ if (args.length != 2)
+ {
+ System.out.println("Usage: <WLS URI> <service queue>");
+ System.exit(1);
+ }
+ try
+ {
+ String url = args[0];
+ String receiveQueue = args[1];
+
+ final InitialContext ctx = getInitialContext(url);
+
+ QueueConnectionFactory qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
+ QueueConnection qcon = qconFactory.createQueueConnection();
+ final QueueSession qsession = qcon.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
+ Queue receiveQ = (Queue) ctx.lookup(receiveQueue);
+
+ _logger.info("Service (queue) name is '" + receiveQ + "'...");
+
+ String selector = (args.length > 2 && args[2] != null && args[2].length() > 1) ? args[2] : null;
+
+ _logger.info("Message selector is <" + selector + ">...");
+
+ MessageConsumer consumer = qsession.createConsumer(receiveQ, selector);
+
+ consumer.setMessageListener(new MessageListener()
+ {
+ private int _messageCount;
+
+ public void onMessage(javax.jms.Message message)
+ {
+ //_logger.info("Got message '" + message + "'");
+
+ TextMessage tm = (TextMessage) message;
+
+ try
+ {
+ Queue responseQueue = (Queue)tm.getJMSReplyTo();
+ if (!responseQueue.equals(_destinationQ))
+ {
+ _destinationQ = responseQueue;
+ _logger.info("Creating destination for " + responseQueue);
+
+ try
+ {
+ _destinationProducer = qsession.createProducer(_destinationQ);
+ _destinationProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
+ }
+ catch (JMSException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ _messageCount++;
+ if (_messageCount % 1000 == 0)
+ {
+ _logger.info("Received message total: " + _messageCount);
+ _logger.info("Sending response to '" + responseQueue + "'");
+ }
+
+ String payload = "This is a response: sing together: 'Mahnah mahnah...'" + tm.getText();
+ TextMessage msg = qsession.createTextMessage(payload);
+ if (tm.propertyExists("timeSent"))
+ {
+ _logger.info("timeSent property set on message");
+ final long timeSent = tm.getLongProperty("timeSent");
+ msg.setLongProperty("timeSent", timeSent);
+ _logger.info("time taken to go from service request to provider is: " + (System.currentTimeMillis() - timeSent));
+ }
+ _destinationProducer.send(msg);
+ if (_messageCount % 1000 == 0)
+ {
+ tm.acknowledge();
+ _logger.info("Sent response to '" + responseQueue + "'");
+ }
+ }
+ catch (JMSException e)
+ {
+ _logger.error("Error sending message: " + e, e);
+ }
+ }
+ });
+ qcon.start();
+ }
+ catch (Throwable t)
+ {
+ System.err.println("Fatal error: " + t);
+ t.printStackTrace();
+ }
+
+
+ System.out.println("Waiting...");
+ }
+
+ private static InitialContext getInitialContext(String url) throws NamingException
+ {
+ Hashtable env = new Hashtable();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
+ env.put(Context.PROVIDER_URL, url);
+ return new InitialContext(env);
+ }
+}
diff --git a/java/client/src/old_test/java/org/apache/qpid/weblogic/ServiceRequestingClient.java b/java/client/src/old_test/java/org/apache/qpid/weblogic/ServiceRequestingClient.java
new file mode 100644
index 0000000000..2f64a1dde5
--- /dev/null
+++ b/java/client/src/old_test/java/org/apache/qpid/weblogic/ServiceRequestingClient.java
@@ -0,0 +1,185 @@
+/*
+ *
+ * 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.weblogic;
+
+import org.apache.log4j.Logger;
+
+import javax.jms.*;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import java.util.Hashtable;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: U806869
+ * Date: 28-May-2005
+ * Time: 21:54:51
+ * To change this template use File | Settings | File Templates.
+ */
+public class ServiceRequestingClient
+{
+ private static final Logger _log = Logger.getLogger(ServiceRequestingClient.class);
+ private static final String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
+ private static final String JMS_FACTORY = "transientJMSConnectionFactory";
+
+ private static class CallbackHandler implements MessageListener
+ {
+ private int _expectedMessageCount;
+
+ private int _actualMessageCount;
+
+ private long _startTime;
+
+ private long _averageLatency;
+
+ public CallbackHandler(int expectedMessageCount, long startTime)
+ {
+ _expectedMessageCount = expectedMessageCount;
+ _startTime = startTime;
+ }
+
+ public void onMessage(Message m)
+ {
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Message received: " + m);
+ }
+ try
+ {
+ if (m.propertyExists("timeSent"))
+ {
+ long timeSent = m.getLongProperty("timeSent");
+ long now = System.currentTimeMillis();
+ if (_averageLatency == 0)
+ {
+ _averageLatency = now - timeSent;
+ _log.info("Latency " + _averageLatency);
+ }
+ else
+ {
+ _log.info("Individual latency: " + (now-timeSent));
+ _averageLatency = (_averageLatency + (now - timeSent))/2;
+ _log.info("Average latency now: " + _averageLatency);
+ }
+ }
+ }
+ catch (JMSException e)
+ {
+ _log.error("Could not calculate latency");
+ }
+
+ _actualMessageCount++;
+ if (_actualMessageCount%1000 == 0)
+ {
+ try
+ {
+ m.acknowledge();
+ }
+ catch (JMSException e)
+ {
+ _log.error("Error acknowledging message");
+ }
+ _log.info("Received message count: " + _actualMessageCount);
+ }
+ /*if (!"henson".equals(m.toString()))
+ {
+ _log.error("Message response not correct: expected 'henson' but got " + m.toString());
+ }
+ else
+ {
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Message " + m + " received");
+ }
+ else
+ {
+ _log.info("Message received");
+ }
+ } */
+
+ if (_actualMessageCount == _expectedMessageCount)
+ {
+ long timeTaken = System.currentTimeMillis() - _startTime;
+ System.out.println("Total time taken to receive " + _expectedMessageCount+ " messages was " +
+ timeTaken + "ms, equivalent to " +
+ (_expectedMessageCount/(timeTaken/1000.0)) + " messages per second");
+ System.out.println("Average latency is: " + _averageLatency);
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception
+ {
+ if (args.length != 3)
+ {
+ System.out.println("Usage: IXPublisher <WLS URL> <sendQueue> <count> will publish count messages to ");
+ System.out.println("queue sendQueue and waits for a response on a temp queue");
+ System.exit(1);
+ }
+
+ String url = args[0];
+ String sendQueue = args[1];
+ int messageCount = Integer.parseInt(args[2]);
+
+ InitialContext ctx = getInitialContext(url);
+
+ QueueConnectionFactory qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
+ QueueConnection qcon = qconFactory.createQueueConnection();
+ QueueSession qsession = qcon.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
+ Queue sendQ = (Queue) ctx.lookup(sendQueue);
+ Queue receiveQ = qsession.createTemporaryQueue();
+ QueueSender qsender = qsession.createSender(sendQ);
+ qsender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
+ _log.debug("Queue sender created for service queue " + sendQ);
+
+ javax.jms.MessageConsumer messageConsumer = (javax.jms.MessageConsumer) qsession.createConsumer(receiveQ);
+
+ //TextMessage msg = _session.createTextMessage(tempDestination.getQueueName() + "/Presented to in conjunction with Mahnah Mahnah and the Snowths");
+ final long startTime = System.currentTimeMillis();
+
+ messageConsumer.setMessageListener(new CallbackHandler(messageCount, startTime));
+ qcon.start();
+ for (int i = 0; i < messageCount; i++)
+ {
+ TextMessage msg = qsession.createTextMessage("/Presented to in conjunction with Mahnah Mahnah and the Snowths:" + i);
+ msg.setJMSReplyTo(receiveQ);
+ if (i%1000 == 0)
+ {
+ long timeNow = System.currentTimeMillis();
+ msg.setLongProperty("timeSent", timeNow);
+ }
+ qsender.send(msg);
+ }
+
+ new Thread("foo").start();
+ //qsession.close();
+ //qcon.close();
+ }
+
+ private static InitialContext getInitialContext(String url) throws NamingException
+ {
+ Hashtable env = new Hashtable();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
+ env.put(Context.PROVIDER_URL, url);
+ return new InitialContext(env);
+ }
+}
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/AMQSession_0_10Test.java b/java/client/src/test/java/org/apache/qpid/client/AMQSession_0_10Test.java
deleted file mode 100644
index 849827216c..0000000000
--- a/java/client/src/test/java/org/apache/qpid/client/AMQSession_0_10Test.java
+++ /dev/null
@@ -1,765 +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 java.util.ArrayList;
-import java.util.List;
-
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageListener;
-import javax.jms.MessageProducer;
-
-import junit.framework.TestCase;
-
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.transport.Binary;
-import org.apache.qpid.transport.Connection;
-import org.apache.qpid.transport.Connection.SessionFactory;
-import org.apache.qpid.transport.Connection.State;
-import org.apache.qpid.transport.ExchangeBound;
-import org.apache.qpid.transport.ExchangeBoundResult;
-import org.apache.qpid.transport.ExchangeDeclare;
-import org.apache.qpid.transport.ExchangeDelete;
-import org.apache.qpid.transport.ExchangeQuery;
-import org.apache.qpid.transport.ExchangeQueryResult;
-import org.apache.qpid.transport.ExecutionErrorCode;
-import org.apache.qpid.transport.ExecutionException;
-import org.apache.qpid.transport.ExecutionResult;
-import org.apache.qpid.transport.ExecutionSync;
-import org.apache.qpid.transport.Future;
-import org.apache.qpid.transport.MessageCancel;
-import org.apache.qpid.transport.MessageFlow;
-import org.apache.qpid.transport.MessageRelease;
-import org.apache.qpid.transport.MessageSubscribe;
-import org.apache.qpid.transport.MessageTransfer;
-import org.apache.qpid.transport.Method;
-import org.apache.qpid.transport.Option;
-import org.apache.qpid.transport.ProtocolEvent;
-import org.apache.qpid.transport.QueueDelete;
-import org.apache.qpid.transport.QueueQuery;
-import org.apache.qpid.transport.QueueQueryResult;
-import org.apache.qpid.transport.Sender;
-import org.apache.qpid.transport.Session;
-import org.apache.qpid.transport.SessionAttach;
-import org.apache.qpid.transport.SessionDelegate;
-import org.apache.qpid.transport.SessionDetach;
-import org.apache.qpid.transport.SessionException;
-import org.apache.qpid.transport.SessionRequestTimeout;
-import org.apache.qpid.transport.TxCommit;
-import org.apache.qpid.transport.TxRollback;
-import org.apache.qpid.transport.TxSelect;
-
-/**
- * Tests AMQSession_0_10 methods.
- * <p>
- * The main purpose of the tests in this test suite is to check that
- * {@link SessionException} is not thrown from methods of
- * {@link AMQSession_0_10}.
- */
-public class AMQSession_0_10Test extends TestCase
-{
-
- public void testExceptionOnCommit()
- {
- AMQSession_0_10 session = createThrowingExceptionAMQSession_0_10();
- try
- {
- session.commit();
- fail("JMSException should be thrown");
- }
- catch (Exception e)
- {
- assertTrue("JMSException is expected", e instanceof JMSException);
- assertEquals("541 error code is expected", "541", ((JMSException) e).getErrorCode());
- }
- }
-
- public void testExceptionOnCreateMessageProducer()
- {
- AMQSession_0_10 session = createThrowingExceptionAMQSession_0_10();
- try
- {
- session.createMessageProducer(createDestination(), true, true, 1l);
- fail("JMSException should be thrown");
- }
- catch (Exception e)
- {
- assertTrue("JMSException is expected but got:" + e, e instanceof JMSException);
- assertEquals("541 error code is expected", "541", ((JMSException) e).getErrorCode());
- }
- }
-
- public void testExceptionOnRollback()
- {
- AMQSession_0_10 session = createThrowingExceptionAMQSession_0_10();
- try
- {
- session.rollback();
- fail("JMSException should be thrown");
- }
- catch (Exception e)
- {
- assertTrue("JMSException is expected", e instanceof JMSException);
- }
- }
-
- public void testExceptionOnRecover()
- {
- AMQSession_0_10 session = createThrowingExceptionAMQSession_0_10(javax.jms.Session.AUTO_ACKNOWLEDGE);
- try
- {
- session.recover();
- fail("JMSException should be thrown");
- }
- catch (Exception e)
- {
- assertTrue("JMSException is expected", e instanceof JMSException);
- }
- }
-
- public void testExceptionOnCreateBrowser()
- {
- AMQSession_0_10 session = createThrowingExceptionAMQSession_0_10();
- AMQQueue destination = createQueue();
- try
- {
- session.createBrowser(destination);
- fail("JMSException should be thrown");
- }
- catch (Exception e)
- {
- assertTrue("JMSException is expected", e instanceof JMSException);
- assertEquals("541 error code is expected", "541", ((JMSException) e).getErrorCode());
- }
- }
-
- public void testExceptionOnCreateConsumer()
- {
- AMQSession_0_10 session = createThrowingExceptionAMQSession_0_10();
- AMQAnyDestination destination = createDestination();
- try
- {
- session.createConsumer(destination);
- fail("JMSException should be thrown");
- }
- catch (Exception e)
- {
- assertTrue("JMSException is expected", e instanceof JMSException);
- assertEquals("541 error code is expected", "541", ((JMSException) e).getErrorCode());
- }
- }
-
- public void testExceptionOnCreateSubscriber()
- {
- AMQSession_0_10 session = createThrowingExceptionAMQSession_0_10();
- AMQAnyDestination destination = createDestination();
- try
- {
- session.createSubscriber(destination);
- fail("JMSException should be thrown");
- }
- catch (Exception e)
- {
- assertTrue("JMSException is expected", e instanceof JMSException);
- assertEquals("541 error code is expected", "541", ((JMSException) e).getErrorCode());
- }
- }
-
- public void testExceptionOnUnsubscribe()
- {
- AMQSession_0_10 session = createThrowingExceptionAMQSession_0_10();
- try
- {
- session.unsubscribe("whatever");
- fail("JMSExceptiuon should be thrown");
- }
- catch (Exception e)
- {
- assertTrue("JMSException is expected", e instanceof JMSException);
- assertEquals("541 error code is expected", "541", ((JMSException) e).getErrorCode());
- }
- }
-
- public void testCommit()
- {
- AMQSession_0_10 session = createAMQSession_0_10();
- try
- {
- session.commit();
- }
- catch (Exception e)
- {
- fail("Unexpected exception is cought:" + e.getMessage());
- }
- ProtocolEvent event = findSentProtocolEventOfClass(session, TxCommit.class, false);
- assertNotNull("TxCommit was not sent", event);
- }
-
- public void testRollback()
- {
- AMQSession_0_10 session = createAMQSession_0_10();
- try
- {
- session.rollback();
- }
- catch (Exception e)
- {
- fail("Unexpected exception is cought:" + e.getMessage());
- }
- ProtocolEvent event = findSentProtocolEventOfClass(session, TxRollback.class, false);
- assertNotNull("TxRollback was not sent", event);
- }
-
- public void testRecover()
- {
- AMQSession_0_10 session = createAMQSession_0_10(javax.jms.Session.AUTO_ACKNOWLEDGE);
- try
- {
- session.recover();
- }
- catch (Exception e)
- {
- fail("Unexpected exception is cought:" + e.getMessage());
- }
- ProtocolEvent event = findSentProtocolEventOfClass(session, MessageRelease.class, false);
- assertNotNull("MessageRelease was not sent", event);
- }
-
- public void testCreateProducer()
- {
- AMQSession_0_10 session = createAMQSession_0_10();
- try
- {
- session.createProducer(createQueue());
- }
- catch (Exception e)
- {
- fail("Unexpected exception is cought:" + e.getMessage());
- }
- ProtocolEvent event = findSentProtocolEventOfClass(session, ExchangeDeclare.class, false);
- assertNotNull("ExchangeDeclare was not sent", event);
- }
-
- public void testCreateConsumer()
- {
- AMQSession_0_10 session = createAMQSession_0_10();
- try
- {
- session.createConsumer(createQueue());
- }
- catch (Exception e)
- {
- fail("Unexpected exception is cought:" + e.getMessage());
- }
- ProtocolEvent event = findSentProtocolEventOfClass(session, MessageSubscribe.class, false);
- assertNotNull("MessageSubscribe was not sent", event);
- }
-
- public void testSync()
- {
- AMQSession_0_10 session = createAMQSession_0_10();
- try
- {
- session.sync();
- }
- catch (Exception e)
- {
- fail("Unexpected exception is cought:" + e.getMessage());
- }
- ProtocolEvent event = findSentProtocolEventOfClass(session, ExecutionSync.class, false);
- assertNotNull("ExecutionSync was not sent", event);
- }
-
- public void testRejectMessage()
- {
- AMQSession_0_10 session = createAMQSession_0_10();
- session.rejectMessage(1l, true);
- ProtocolEvent event = findSentProtocolEventOfClass(session, MessageRelease.class, false);
- assertNotNull("MessageRelease event was not sent", event);
- }
-
- public void testReleaseForRollback()
- {
- AMQSession_0_10 session = createAMQSession_0_10();
- try
- {
- session.releaseForRollback();
- }
- catch (Exception e)
- {
- fail("Unexpected exception is cought:" + e.getMessage());
- }
- ProtocolEvent event = findSentProtocolEventOfClass(session, MessageRelease.class, false);
- assertNotNull("MessageRelease event was not sent", event);
- }
-
- public void testSendQueueDelete()
- {
- AMQSession_0_10 session = createAMQSession_0_10();
- try
- {
- session.sendQueueDelete(new AMQShortString("test"));
- }
- catch (Exception e)
- {
- fail("Unexpected exception is cought:" + e.getMessage());
- }
- ProtocolEvent event = findSentProtocolEventOfClass(session, QueueDelete.class, false);
- assertNotNull("QueueDelete event was not sent", event);
- QueueDelete exchangeDelete = (QueueDelete) event;
- assertEquals("test", exchangeDelete.getQueue());
- }
-
- public void testSendConsume()
- {
- AMQSession_0_10 session = createAMQSession_0_10();
- try
- {
- BasicMessageConsumer_0_10 consumer = session.createMessageConsumer(createDestination(), 1, 1, true, false,
- null, new FieldTable(), false, true);
- session.sendConsume(consumer, new AMQShortString("test"), null, true, null, 1);
- }
- catch (Exception e)
- {
- fail("Unexpected exception is cought:" + e.getMessage());
- }
- ProtocolEvent event = findSentProtocolEventOfClass(session, MessageSubscribe.class, false);
- assertNotNull("MessageSubscribe event was not sent", event);
- }
-
- public void testCreateMessageProducer()
- {
- AMQSession_0_10 session = createAMQSession_0_10();
- try
- {
- session.createMessageProducer(createDestination(), true, true, 1l);
- }
- catch (Exception e)
- {
- fail("Unexpected exception is cought:" + e.getMessage());
- }
- ProtocolEvent event = findSentProtocolEventOfClass(session, ExchangeDeclare.class, false);
- assertNotNull("ExchangeDeclare event was not sent", event);
- }
-
- public void testSendExchangeDelete()
- {
- AMQSession_0_10 session = createAMQSession_0_10();
- try
- {
- session.sendExchangeDelete("test", true);
- }
- catch (Exception e)
- {
- fail("Unexpected exception is cought:" + e.getMessage());
- }
- ProtocolEvent event = findSentProtocolEventOfClass(session, ExchangeDelete.class, false);
- assertNotNull("ExchangeDelete event was not sent", event);
- ExchangeDelete exchangeDelete = (ExchangeDelete) event;
- assertEquals("test", exchangeDelete.getExchange());
- }
-
- public void testExceptionOnMessageConsumerReceive()
- {
- AMQSession_0_10 session = createThrowingExceptionAMQSession_0_10();
- try
- {
- BasicMessageConsumer_0_10 consumer = session.createMessageConsumer(createDestination(), 1, 1, true, false,
- null, new FieldTable(), false, true);
- session.start();
- consumer.receive(1);
- fail("JMSException should be thrown");
- }
- catch (Exception e)
- {
- assertTrue("JMSException is expected", e instanceof JMSException);
- assertEquals("541 error code is expected", "541", ((JMSException) e).getErrorCode());
- }
- }
-
- public void testMessageConsumerReceive()
- {
- AMQSession_0_10 session = createAMQSession_0_10();
- try
- {
- BasicMessageConsumer_0_10 consumer = session.createMessageConsumer(createDestination(), 1, 1, true, false,
- null, new FieldTable(), false, true);
- session.start();
- consumer.receive(1);
- }
- catch (Exception e)
- {
- fail("Unexpected exception is cought:" + e.getMessage());
- }
- ProtocolEvent event = findSentProtocolEventOfClass(session, MessageFlow.class, false);
- assertNotNull("MessageFlow event was not sent", event);
- }
-
- public void testExceptionOnMessageConsumerReceiveNoWait()
- {
- AMQSession_0_10 session = createThrowingExceptionAMQSession_0_10();
- try
- {
- BasicMessageConsumer_0_10 consumer = session.createMessageConsumer(createDestination(), 1, 1, true, false,
- null, new FieldTable(), false, true);
- session.start();
- consumer.receiveNoWait();
- fail("JMSException should be thrown");
- }
- catch (Exception e)
- {
- assertTrue("JMSException is expected", e instanceof JMSException);
- assertEquals("541 error code is expected", "541", ((JMSException) e).getErrorCode());
- }
- }
-
- public void testExceptionOnMessageConsumerSetMessageListener()
- {
- AMQSession_0_10 session = createThrowingExceptionAMQSession_0_10();
- try
- {
- BasicMessageConsumer_0_10 consumer = session.createMessageConsumer(createDestination(), 1, 1, true, false,
- null, new FieldTable(), false, true);
- consumer.setMessageListener(new MockMessageListener());
- fail("JMSException should be thrown");
- }
- catch (Exception e)
- {
- assertTrue("JMSException is expected", e instanceof JMSException);
- assertEquals("541 error code is expected", "541", ((JMSException) e).getErrorCode());
- }
- }
-
- public void testMessageConsumerSetMessageListener()
- {
- AMQSession_0_10 session = createAMQSession_0_10();
- try
- {
- BasicMessageConsumer_0_10 consumer = session.createMessageConsumer(createDestination(), 1, 1, true, false,
- null, new FieldTable(), false, true);
- consumer.setMessageListener(new MockMessageListener());
- }
- catch (Exception e)
- {
- fail("Unexpected exception is cought:" + e.getMessage());
- }
- ProtocolEvent event = findSentProtocolEventOfClass(session, MessageFlow.class, false);
- assertNotNull("MessageFlow event was not sent", event);
- }
-
- public void testMessageConsumerClose()
- {
- AMQSession_0_10 session = createAMQSession_0_10();
- try
- {
- BasicMessageConsumer_0_10 consumer = session.createMessageConsumer(createDestination(), 1, 1, true, false,
- null, new FieldTable(), false, true);
- consumer.close();
- }
- catch (Exception e)
- {
- fail("Unexpected exception is cought:" + e.getMessage());
- }
- ProtocolEvent event = findSentProtocolEventOfClass(session, MessageCancel.class, false);
- assertNotNull("MessageCancel event was not sent", event);
- }
-
- public void testExceptionOnMessageConsumerClose()
- {
- AMQSession_0_10 session = createThrowingExceptionAMQSession_0_10();
- try
- {
- BasicMessageConsumer_0_10 consumer = session.createMessageConsumer(createDestination(), 1, 1, true, false,
- null, new FieldTable(), false, true);
- consumer.close();
- fail("JMSException should be thrown");
- }
- catch (Exception e)
- {
- assertTrue("JMSException is expected", e instanceof JMSException);
- assertEquals("541 error code is expected", "541", ((JMSException) e).getErrorCode());
- }
- }
-
- public void testMessageProducerSend()
- {
- AMQSession_0_10 session = createAMQSession_0_10();
- try
- {
- MessageProducer producer = session.createProducer(createQueue());
- producer.send(session.createTextMessage("Test"));
- session.commit();
- }
- catch (Exception e)
- {
- fail("Unexpected exception is cought:" + e.getMessage());
- }
- ProtocolEvent event = findSentProtocolEventOfClass(session, MessageTransfer.class, false);
- assertNotNull("MessageTransfer event was not sent", event);
- event = findSentProtocolEventOfClass(session, ExchangeDeclare.class, false);
- assertNotNull("ExchangeDeclare event was not sent", event);
- }
-
- private AMQAnyDestination createDestination()
- {
- AMQAnyDestination destination = null;
- try
- {
- destination = new AMQAnyDestination(new AMQShortString("amq.direct"), new AMQShortString("direct"),
- new AMQShortString("test"), false, true, new AMQShortString("test"), true, null);
- }
- catch (Exception e)
- {
- fail("Failued to create destination:" + e.getMessage());
- }
- return destination;
- }
-
- private AMQQueue createQueue()
- {
- AMQQueue destination = null;
- try
- {
- destination = new AMQQueue(new AMQShortString("amq.direct"), new AMQShortString("test"),
- new AMQShortString("test"));
- }
- catch (Exception e)
- {
- fail("Failued to create destination:" + e.getMessage());
- }
- return destination;
- }
-
- private AMQSession_0_10 createThrowingExceptionAMQSession_0_10()
- {
- return createAMQSession_0_10(true, javax.jms.Session.SESSION_TRANSACTED);
- }
-
- private AMQSession_0_10 createThrowingExceptionAMQSession_0_10(int akcnowledgeMode)
- {
- return createAMQSession_0_10(true, akcnowledgeMode);
- }
-
- private ProtocolEvent findSentProtocolEventOfClass(AMQSession_0_10 session, Class<? extends ProtocolEvent> class1,
- boolean isLast)
- {
- ProtocolEvent found = null;
- List<ProtocolEvent> events = ((MockSession) session.getQpidSession()).getSender().getSendEvents();
- assertNotNull("Events list should not be null", events);
- assertFalse("Events list should not be empty", events.isEmpty());
- if (isLast)
- {
- ProtocolEvent event = events.get(events.size() - 1);
- if (event.getClass().isAssignableFrom(class1))
- {
- found = event;
- }
- }
- else
- {
- for (ProtocolEvent protocolEvent : events)
- {
- if (protocolEvent.getClass().isAssignableFrom(class1))
- {
- found = protocolEvent;
- break;
- }
- }
-
- }
- return found;
- }
-
- private AMQSession_0_10 createAMQSession_0_10()
- {
- return createAMQSession_0_10(false, javax.jms.Session.SESSION_TRANSACTED);
- }
-
- private AMQSession_0_10 createAMQSession_0_10(int acknowledgeMode)
- {
- return createAMQSession_0_10(false, acknowledgeMode);
- }
-
- private AMQSession_0_10 createAMQSession_0_10(boolean throwException, int acknowledgeMode)
- {
- AMQConnection amqConnection = null;
- try
- {
- amqConnection = new MockAMQConnection(
- "amqp://guest:guest@client/test?brokerlist='tcp://localhost:1'&maxprefetch='0'");
- }
- catch (Exception e)
- {
- fail("Failure to create a mock connection:" + e.getMessage());
- }
- boolean isTransacted = acknowledgeMode == javax.jms.Session.SESSION_TRANSACTED ? true : false;
- AMQSession_0_10 session = new AMQSession_0_10(createConnection(throwException), amqConnection, 1, isTransacted, acknowledgeMode,
- 1, 1, "test");
- return session;
- }
-
- private Connection createConnection(final boolean throwException)
- {
- MockTransportConnection connection = new MockTransportConnection();
- connection.setState(State.OPEN);
- connection.setSender(new MockSender());
- connection.setSessionFactory(new SessionFactory()
- {
-
- @Override
- public Session newSession(Connection conn, Binary name, long expiry)
- {
- return new MockSession(conn, new SessionDelegate(), name, expiry, throwException);
- }
- });
- return connection;
- }
-
- private final class MockMessageListener implements MessageListener
- {
- @Override
- public void onMessage(Message arg0)
- {
- }
- }
-
- class MockSession extends Session
- {
- private final boolean _throwException;
- private final Connection _connection;
- private final SessionDelegate _delegate;
-
- protected MockSession(Connection connection, SessionDelegate delegate, Binary name, long expiry,
- boolean throwException)
- {
- super(connection, delegate, name, expiry);
- _throwException = throwException;
- setState(State.OPEN);
- _connection = connection;
- _delegate = delegate;
- }
-
- public void invoke(Method m, Runnable postIdSettingAction)
- {
- if (_throwException)
- {
- if (m instanceof SessionAttach || m instanceof SessionRequestTimeout || m instanceof TxSelect)
- {
- // do not throw exception for SessionAttach,
- // SessionRequestTimeout and TxSelect
- // session needs to be instantiated
- return;
- }
- ExecutionException e = new ExecutionException();
- e.setErrorCode(ExecutionErrorCode.INTERNAL_ERROR);
- throw new SessionException(e);
- }
- else
- {
- super.invoke(m, postIdSettingAction);
- if (m instanceof SessionDetach)
- {
- setState(State.CLOSED);
- }
- }
- }
-
- public void sync()
- {
- // to avoid recursive calls
- setAutoSync(false);
- // simply send sync command
- super.executionSync(Option.SYNC);
- }
-
- protected <T> Future<T> invoke(Method m, Class<T> klass)
- {
- int commandId = getCommandsOut();
- Future<T> future = super.invoke(m, klass);
- ExecutionResult result = new ExecutionResult();
- result.setCommandId(commandId);
- if (m instanceof ExchangeBound)
- {
- ExchangeBoundResult struc = new ExchangeBoundResult();
- struc.setQueueNotFound(true);
- result.setValue(struc);
- }
- else if (m instanceof ExchangeQuery)
- {
- ExchangeQueryResult struc = new ExchangeQueryResult();
- result.setValue(struc);
- }
- else if (m instanceof QueueQuery)
- {
- QueueQueryResult struc = new QueueQueryResult();
- result.setValue(struc);
- }
- _delegate.executionResult(this, result);
- return future;
- }
-
- public MockSender getSender()
- {
- return (MockSender) _connection.getSender();
- }
- }
-
- class MockTransportConnection extends Connection
- {
- public void setState(State state)
- {
- super.setState(state);
- }
- }
-
- class MockSender implements Sender<ProtocolEvent>
- {
- private List<ProtocolEvent> _sendEvents = new ArrayList<ProtocolEvent>();
-
- @Override
- public void setIdleTimeout(int i)
- {
- }
-
- @Override
- public void send(ProtocolEvent msg)
- {
- _sendEvents.add(msg);
- }
-
- @Override
- public void flush()
- {
- }
-
- @Override
- public void close()
- {
- }
-
- public List<ProtocolEvent> getSendEvents()
- {
- return _sendEvents;
- }
-
- }
-
-}
diff --git a/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java b/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java
index 73e67469ae..da44822ec3 100644
--- a/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java
+++ b/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java
@@ -23,6 +23,7 @@ package org.apache.qpid.client;
import org.apache.qpid.AMQException;
import org.apache.qpid.client.state.AMQState;
import org.apache.qpid.framing.ProtocolVersion;
+import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.jms.BrokerDetails;
import org.apache.qpid.url.URLSyntaxException;
@@ -36,18 +37,53 @@ public class MockAMQConnection extends AMQConnection
super(broker, username, password, clientName, virtualHost);
}
+ public MockAMQConnection(String broker, String username, String password, String clientName, String virtualHost, SSLConfiguration sslConfig)
+ throws AMQException, URLSyntaxException
+ {
+ super(broker, username, password, clientName, virtualHost, sslConfig);
+ }
+
public MockAMQConnection(String host, int port, String username, String password, String clientName, String virtualHost)
throws AMQException, URLSyntaxException
{
super(host, port, username, password, clientName, virtualHost);
}
+ public MockAMQConnection(String host, int port, String username, String password, String clientName, String virtualHost, SSLConfiguration sslConfig)
+ throws AMQException, URLSyntaxException
+ {
+ super(host, port, username, password, clientName, virtualHost, sslConfig);
+ }
+
+ public MockAMQConnection(String host, int port, boolean useSSL, String username, String password, String clientName, String virtualHost, SSLConfiguration sslConfig)
+ throws AMQException, URLSyntaxException
+ {
+ super(host, port, useSSL, username, password, clientName, virtualHost, sslConfig);
+ }
+
public MockAMQConnection(String connection)
throws AMQException, URLSyntaxException
{
super(connection);
}
+ public MockAMQConnection(String connection, SSLConfiguration sslConfig)
+ throws AMQException, URLSyntaxException
+ {
+ super(connection, sslConfig);
+ }
+
+ public MockAMQConnection(ConnectionURL connectionURL, SSLConfiguration sslConfig)
+ throws AMQException
+ {
+ super(connectionURL, sslConfig);
+ }
+
+ protected MockAMQConnection(String username, String password, String clientName, String virtualHost)
+ {
+ super(username, password, clientName, virtualHost);
+ }
+
@Override
public ProtocolVersion makeBrokerConnection(BrokerDetails brokerDetail) throws IOException
{
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 b5c31e7c5e..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
@@ -43,9 +43,4 @@ public class TestMessageHelper
{
return new JMSStreamMessage(AMQMessageDelegateFactory.FACTORY_0_8);
}
-
- public static JMSObjectMessage newJMSObjectMessage()
- {
- return new JMSObjectMessage(AMQMessageDelegateFactory.FACTORY_0_8);
- }
}
diff --git a/java/client/src/test/java/org/apache/qpid/client/protocol/AMQProtocolHandlerTest.java b/java/client/src/test/java/org/apache/qpid/client/protocol/AMQProtocolHandlerTest.java
index e159ceb148..f520a21ba0 100644
--- a/java/client/src/test/java/org/apache/qpid/client/protocol/AMQProtocolHandlerTest.java
+++ b/java/client/src/test/java/org/apache/qpid/client/protocol/AMQProtocolHandlerTest.java
@@ -20,24 +20,23 @@
*/
package org.apache.qpid.client.protocol;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
import junit.framework.TestCase;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQAuthenticationException;
-import org.apache.qpid.client.MockAMQConnection;
-import org.apache.qpid.client.state.AMQState;
-import org.apache.qpid.framing.AMQBody;
import org.apache.qpid.framing.AMQFrame;
+import org.apache.qpid.framing.AMQBody;
import org.apache.qpid.framing.AMQMethodBody;
import org.apache.qpid.framing.amqp_8_0.BasicRecoverOkBodyImpl;
+import org.apache.qpid.AMQException;
import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.transport.TestNetworkConnection;
+import org.apache.qpid.transport.TestNetworkDriver;
+import org.apache.qpid.client.MockAMQConnection;
+import org.apache.qpid.client.AMQAuthenticationException;
+import org.apache.qpid.client.state.AMQState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
/**
* This is a test address QPID-1431 where frame listeners would fail to be notified of an incomming exception.
*
@@ -73,8 +72,8 @@ public class AMQProtocolHandlerTest extends TestCase
public void setUp() throws Exception
{
//Create a new ProtocolHandler with a fake connection.
- _handler = new AMQProtocolHandler(new MockAMQConnection("amqp://guest:guest@client/test?brokerlist='tcp://localhost:1'"));
- _handler.setNetworkConnection(new TestNetworkConnection());
+ _handler = new AMQProtocolHandler(new MockAMQConnection("amqp://guest:guest@client/test?brokerlist='vm://:1'"));
+ _handler.setNetworkDriver(new TestNetworkDriver());
AMQBody body = BasicRecoverOkBodyImpl.getFactory().newInstance(null, 1);
_blockFrame = new AMQFrame(0, body);
diff --git a/java/client/src/test/java/org/apache/qpid/client/protocol/MockIoSession.java b/java/client/src/test/java/org/apache/qpid/client/protocol/MockIoSession.java
new file mode 100644
index 0000000000..f0938a4bc0
--- /dev/null
+++ b/java/client/src/test/java/org/apache/qpid/client/protocol/MockIoSession.java
@@ -0,0 +1,312 @@
+/*
+ *
+ * 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.protocol;
+
+import org.apache.mina.common.*;
+import org.apache.mina.common.support.DefaultCloseFuture;
+import org.apache.mina.common.support.DefaultWriteFuture;
+import org.apache.mina.common.support.AbstractIoFilterChain;
+import org.apache.qpid.client.protocol.AMQProtocolSession;
+
+import java.net.SocketAddress;
+import java.net.InetSocketAddress;
+import java.util.Set;
+
+public class MockIoSession implements IoSession
+{
+ private AMQProtocolSession _protocolSession;
+
+ /**
+ * Stores the last response written
+ */
+ private Object _lastWrittenObject;
+
+ private boolean _closing;
+ private IoFilterChain _filterChain;
+
+ public MockIoSession()
+ {
+ _filterChain = new AbstractIoFilterChain(this)
+ {
+ protected void doWrite(IoSession ioSession, IoFilter.WriteRequest writeRequest) throws Exception
+ {
+
+ }
+
+ protected void doClose(IoSession ioSession) throws Exception
+ {
+
+ }
+ };
+ }
+
+ public Object getLastWrittenObject()
+ {
+ return _lastWrittenObject;
+ }
+
+ public IoService getService()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public IoServiceConfig getServiceConfig()
+ {
+ return null;
+ }
+
+ public IoHandler getHandler()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public IoSessionConfig getConfig()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public IoFilterChain getFilterChain()
+ {
+ return _filterChain;
+ }
+
+ public WriteFuture write(Object message)
+ {
+ WriteFuture wf = new DefaultWriteFuture(null);
+ _lastWrittenObject = message;
+ return wf;
+ }
+
+ public CloseFuture close()
+ {
+ _closing = true;
+ CloseFuture cf = new DefaultCloseFuture(null);
+ cf.setClosed();
+ return cf;
+ }
+
+ public Object getAttachment()
+ {
+ return _protocolSession;
+ }
+
+ public Object setAttachment(Object attachment)
+ {
+ Object current = _protocolSession;
+ _protocolSession = (AMQProtocolSession) attachment;
+ return current;
+ }
+
+ public Object getAttribute(String key)
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public Object setAttribute(String key, Object value)
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public Object setAttribute(String key)
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public Object removeAttribute(String key)
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean containsAttribute(String key)
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public Set getAttributeKeys()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public TransportType getTransportType()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean isConnected()
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean isClosing()
+ {
+ return _closing;
+ }
+
+ public CloseFuture getCloseFuture()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public SocketAddress getRemoteAddress()
+ {
+ return new InetSocketAddress("127.0.0.1", 1234); //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public SocketAddress getLocalAddress()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public SocketAddress getServiceAddress()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public int getIdleTime(IdleStatus status)
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public long getIdleTimeInMillis(IdleStatus status)
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void setIdleTime(IdleStatus status, int idleTime)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public int getWriteTimeout()
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public long getWriteTimeoutInMillis()
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void setWriteTimeout(int writeTimeout)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public TrafficMask getTrafficMask()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void setTrafficMask(TrafficMask trafficMask)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void suspendRead()
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void suspendWrite()
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void resumeRead()
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void resumeWrite()
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public long getReadBytes()
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public long getWrittenBytes()
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public long getReadMessages()
+ {
+ return 0L;
+ }
+
+ public long getWrittenMessages()
+ {
+ return 0L;
+ }
+
+ public long getWrittenWriteRequests()
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public int getScheduledWriteRequests()
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public int getScheduledWriteBytes()
+ {
+ return 0; //TODO
+ }
+
+ public long getCreationTime()
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public long getLastIoTime()
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public long getLastReadTime()
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public long getLastWriteTime()
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean isIdle(IdleStatus status)
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public int getIdleCount(IdleStatus status)
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public long getLastIdleTime(IdleStatus status)
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+}
diff --git a/java/client/src/test/java/org/apache/qpid/client/security/CallbackHandlerRegistryTest.java b/java/client/src/test/java/org/apache/qpid/client/security/CallbackHandlerRegistryTest.java
deleted file mode 100644
index cc5d48fbef..0000000000
--- a/java/client/src/test/java/org/apache/qpid/client/security/CallbackHandlerRegistryTest.java
+++ /dev/null
@@ -1,185 +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.security;
-
-import java.io.IOException;
-import java.util.Properties;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-import org.apache.qpid.jms.ConnectionURL;
-import org.apache.qpid.test.utils.QpidTestCase;
-
-
-/**
- * Tests the ability of {@link CallbackHandlerRegistry} to correctly parse
- * the properties describing the available callback handlers. Ensures also
- * that it is able to select the mechanism and create an implementation
- * given a variety of starting conditions.
- *
- */
-public class CallbackHandlerRegistryTest extends QpidTestCase
-{
- private CallbackHandlerRegistry _registry; // Object under test
-
- public void testCreateHandlerSuccess()
- {
- final Properties props = new Properties();
- props.put("TESTA.1", TestACallbackHandler.class.getName());
-
- _registry = new CallbackHandlerRegistry(props);
- assertEquals(1,_registry.getMechanisms().size());
-
- final CallbackHandler handler = _registry.createCallbackHandler("TESTA");
- assertTrue(handler instanceof TestACallbackHandler);
- }
-
- public void testCreateHandlerForUnknownMechanismName()
- {
- final Properties props = new Properties();
- props.put("TEST1.1", TestACallbackHandler.class.getName());
-
- _registry = new CallbackHandlerRegistry(props);
-
- try
- {
- _registry.createCallbackHandler("NOTFOUND");
- fail("Exception not thrown");
- }
- catch (IllegalArgumentException iae)
- {
- // PASS
- }
- }
-
- public void testSelectMechanism()
- {
- final Properties props = new Properties();
- props.put("TESTA.1", TestACallbackHandler.class.getName());
- props.put("TESTB.2", TestBCallbackHandler.class.getName());
-
- _registry = new CallbackHandlerRegistry(props);
- assertEquals(2,_registry.getMechanisms().size());
-
- final String selectedMechanism = _registry.selectMechanism("TESTA");
- assertEquals("TESTA", selectedMechanism);
- }
-
- public void testSelectReturnsFirstMutallyAvailableMechanism()
- {
- final Properties props = new Properties();
- props.put("TESTA.1", TestACallbackHandler.class.getName());
- props.put("TESTB.2", TestBCallbackHandler.class.getName());
-
- _registry = new CallbackHandlerRegistry(props);
-
- final String selectedMechanism = _registry.selectMechanism("TESTD TESTB TESTA");
- // TESTA should be returned as it is higher than TESTB in the properties file.
- assertEquals("Selected mechanism should respect the ordinal", "TESTA", selectedMechanism);
- }
-
- public void testRestrictedSelectReturnsMechanismFromRestrictedList()
- {
- final Properties props = new Properties();
- props.put("TESTA.1", TestACallbackHandler.class.getName());
- props.put("TESTB.2", TestBCallbackHandler.class.getName());
- props.put("TESTC.3", TestCCallbackHandler.class.getName());
-
- _registry = new CallbackHandlerRegistry(props);
-
- final String selectedMechanism = _registry.selectMechanism("TESTC TESTB TESTA", "TESTB TESTC");
- // TESTB should be returned as client has restricted the mechanism list to TESTB and TESTC
- assertEquals("Selected mechanism should respect the ordinal and be limitted by restricted list","TESTB", selectedMechanism);
- }
-
- public void testOldPropertyFormatRejected()
- {
- final Properties props = new Properties();
- props.put("CallbackHandler.TESTA", TestACallbackHandler.class.getName());
-
- try
- {
- new CallbackHandlerRegistry(props);
- fail("exception not thrown");
- }
- catch(IllegalArgumentException iae)
- {
- // PASS
- }
- }
-
- public void testPropertyWithNonnumericalOrdinal()
- {
- final Properties props = new Properties();
- props.put("TESTA.z", TestACallbackHandler.class.getName());
- try
- {
- new CallbackHandlerRegistry(props);
- fail("exception not thrown");
- }
- catch(IllegalArgumentException iae)
- {
- // PASS
- }
- }
-
- public void testUnexpectedCallbackImplementationsIgnored()
- {
- final Properties props = new Properties();
- props.put("TESTA.1", TestACallbackHandler.class.getName());
- props.put("TESTB.2", "NotFound");
- props.put("TESTC.3", "java.lang.String");
-
- _registry = new CallbackHandlerRegistry(props);
-
- assertEquals(1,_registry.getMechanisms().size());
- }
-
- static class TestACallbackHandler extends TestCallbackHandler
- {
- }
-
- static class TestBCallbackHandler extends TestCallbackHandler
- {
- }
-
- static class TestCCallbackHandler extends TestCallbackHandler
- {
- }
-
- static abstract class TestCallbackHandler implements AMQCallbackHandler
- {
- @Override
- public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
- {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void initialise(ConnectionURL connectionURL)
- {
- throw new UnsupportedOperationException();
- }
- }
-
-}
diff --git a/java/client/src/test/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandlerTest.java b/java/client/src/test/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandlerTest.java
deleted file mode 100644
index 9e23f722eb..0000000000
--- a/java/client/src/test/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandlerTest.java
+++ /dev/null
@@ -1,99 +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.security;
-
-import java.security.MessageDigest;
-import java.util.Arrays;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-
-import junit.framework.TestCase;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.client.MockAMQConnection;
-import org.apache.qpid.client.protocol.AMQProtocolHandler;
-import org.apache.qpid.client.protocol.AMQProtocolSession;
-
-/**
- * Unit tests for the UsernameHashPasswordCallbackHandler. This callback handler is
- * used by the CRAM-MD5-HASHED SASL mechanism.
- *
- */
-public class UsernameHashedPasswordCallbackHandlerTest extends TestCase
-{
- private AMQCallbackHandler _callbackHandler = new UsernameHashedPasswordCallbackHandler(); // Class under test
- private static final String PROMPT_UNUSED = "unused";
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
-
- final String url = "amqp://username:password@client/test?brokerlist='tcp://localhost:1'";
- _callbackHandler.initialise(new AMQConnectionURL(url));
- }
-
- /**
- * Tests that the callback handler can correctly retrieve the username from the connection url.
- */
- public void testNameCallback() throws Exception
- {
- final String expectedName = "username";
- NameCallback nameCallback = new NameCallback(PROMPT_UNUSED);
-
- assertNull("Unexpected name before test", nameCallback.getName());
- _callbackHandler.handle(new Callback[] {nameCallback});
- assertEquals("Unexpected name", expectedName, nameCallback.getName());
- }
-
- /**
- * Tests that the callback handler can correctly retrieve the password from the connection url
- * and calculate a MD5.
- */
- public void testDigestedPasswordCallback() throws Exception
- {
- final char[] expectedPasswordDigested = getHashPassword("password");
-
- PasswordCallback passwordCallback = new PasswordCallback(PROMPT_UNUSED, false);
- assertNull("Unexpected password before test", passwordCallback.getPassword());
- _callbackHandler.handle(new Callback[] {passwordCallback});
- assertTrue("Unexpected password", Arrays.equals(expectedPasswordDigested, passwordCallback.getPassword()));
- }
-
- private char[] getHashPassword(final String password) throws Exception
- {
- MessageDigest md5Digester = MessageDigest.getInstance("MD5");
- final byte[] digest = md5Digester.digest(password.getBytes("UTF-8"));
-
- char[] hash = new char[digest.length];
-
- int index = 0;
- for (byte b : digest)
- {
- hash[index++] = (char) b;
- }
-
- return hash;
- }
-}
diff --git a/java/client/src/test/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandlerTest.java b/java/client/src/test/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandlerTest.java
deleted file mode 100644
index 83ddfd72fa..0000000000
--- a/java/client/src/test/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandlerTest.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.client.security;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-
-import junit.framework.TestCase;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.client.MockAMQConnection;
-import org.apache.qpid.client.protocol.AMQProtocolHandler;
-import org.apache.qpid.client.protocol.AMQProtocolSession;
-
-/**
- * Unit tests for the UsernamePasswordCallbackHandler.
- *
- */
-public class UsernamePasswordCallbackHandlerTest extends TestCase
-{
- private AMQCallbackHandler _callbackHandler = new UsernamePasswordCallbackHandler(); // Class under test
- private static final String PROMPT_UNUSED = "unused";
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
-
- final String url = "amqp://username:password@client/test?brokerlist='tcp://localhost:1'";
-
- _callbackHandler.initialise(new AMQConnectionURL(url));
- }
-
- /**
- * Tests that the callback handler can correctly retrieve the username from the connection url.
- */
- public void testNameCallback() throws Exception
- {
- final String expectedName = "username";
- NameCallback nameCallback = new NameCallback(PROMPT_UNUSED);
-
- assertNull("Unexpected name before test", nameCallback.getName());
- _callbackHandler.handle(new Callback[] {nameCallback});
- assertEquals("Unexpected name", expectedName, nameCallback.getName());
- }
-
- /**
- * Tests that the callback handler can correctly retrieve the password from the connection url.
- */
- public void testPasswordCallback() throws Exception
- {
- final String expectedPassword = "password";
- PasswordCallback passwordCallback = new PasswordCallback(PROMPT_UNUSED, false);
- assertNull("Unexpected password before test", passwordCallback.getPassword());
- _callbackHandler.handle(new Callback[] {passwordCallback});
- assertEquals("Unexpected password", expectedPassword, new String(passwordCallback.getPassword()));
- }
-}
diff --git a/java/client/src/test/java/org/apache/qpid/client/util/ClassLoadingAwareObjectInputStreamTest.java b/java/client/src/test/java/org/apache/qpid/client/util/ClassLoadingAwareObjectInputStreamTest.java
deleted file mode 100644
index a12e4ce977..0000000000
--- a/java/client/src/test/java/org/apache/qpid/client/util/ClassLoadingAwareObjectInputStreamTest.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.client.util;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.io.ObjectOutputStream;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.qpid.test.utils.QpidTestCase;
-
-public class ClassLoadingAwareObjectInputStreamTest extends QpidTestCase
-{
- InputStream _in;
- ClassLoadingAwareObjectInputStream _claOIS;
-
- protected void setUp() throws Exception
- {
- //Create a viable input stream for instantiating the CLA OIS
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
- ObjectOutputStream out = new ObjectOutputStream(baos);
- out.writeObject("testString");
- out.flush();
- out.close();
-
-
- _in = new ByteArrayInputStream(baos.toByteArray());
-
- _claOIS = new ClassLoadingAwareObjectInputStream(_in);
- }
-
- /**
- * Test that the resolveProxyClass method returns a proxy class implementing the desired interface
- */
- public void testResolveProxyClass() throws Exception
- {
- //try to proxy an interface
- Class<?> clazz = _claOIS.resolveProxyClass(new String[]{"java.lang.CharSequence"});
-
- //verify the proxy supports the expected interface (only)
- List<Class<?>> interfaces = Arrays.asList(clazz.getInterfaces());
- assertTrue("Unexpected interfaces supported by proxy", interfaces.contains(CharSequence.class));
- assertEquals("Unexpected interfaces supported by proxy", 1, interfaces.size());
- }
-
- /**
- * Test that the resolveProxyClass method throws a ClassNotFoundException wrapping an
- * IllegalArgumentException if it is provided arguments which violate the restrictions allowed
- * by Proxy.getProxyClass (as required by the ObjectInputStream.resolveProxyClass javadoc).
- */
- public void testResolveProxyClassThrowsCNFEWrappingIAE() throws Exception
- {
- try
- {
- //try to proxy a *class* rather than an interface, which is illegal
- _claOIS.resolveProxyClass(new String[]{"java.lang.String"});
- fail("should have thrown an exception");
- }
- catch(ClassNotFoundException cnfe)
- {
- //expected, but must verify it is wrapping an IllegalArgumentException
- assertTrue(cnfe.getCause() instanceof IllegalArgumentException);
- }
- }
-}
diff --git a/java/client/src/test/java/org/apache/qpid/jms/FailoverPolicyTest.java b/java/client/src/test/java/org/apache/qpid/jms/FailoverPolicyTest.java
deleted file mode 100644
index 438995aedc..0000000000
--- a/java/client/src/test/java/org/apache/qpid/jms/FailoverPolicyTest.java
+++ /dev/null
@@ -1,338 +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.jms;
-
-import javax.jms.ConnectionConsumer;
-import javax.jms.ConnectionMetaData;
-import javax.jms.Destination;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.ServerSessionPool;
-import javax.jms.Topic;
-
-import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.jms.failover.FailoverExchangeMethod;
-import org.apache.qpid.jms.failover.FailoverMethod;
-import org.apache.qpid.jms.failover.FailoverRoundRobinServers;
-import org.apache.qpid.jms.failover.FailoverSingleServer;
-import org.apache.qpid.jms.failover.NoFailover;
-
-import junit.framework.TestCase;
-
-/**
- * Tests the ability of FailoverPolicy to instantiate the correct FailoverMethod.
- *
- * This test presently does <i>not</i> test {@link FailoverPolicy#FailoverPolicy(FailoverMethod) or
- * {@link FailoverPolicy#addMethod(FailoverMethod)} as it appears that this functionality
- * is no longer in use.
- *
- */
-public class FailoverPolicyTest extends TestCase
-{
- private FailoverPolicy _failoverPolicy = null; // class under test
- private String _url;
- private Connection _connection = null;
- private ConnectionURL _connectionUrl = null;
-
- /**
- * Tests single server method is selected for a brokerlist with one broker when
- * the failover option is not specified.
- */
- public void testBrokerListWithOneBrokerDefaultsToSingleServerPolicy() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof FailoverSingleServer);
- }
-
- /**
- * Tests round robin method is selected for a brokerlist with two brokers when
- * the failover option is not specified.
- */
- public void testBrokerListWithTwoBrokersDefaultsToRoundRobinPolicy() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672;tcp://localhost:5673'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof FailoverRoundRobinServers);
- }
-
- /**
- * Tests single server method is selected for a brokerlist with one broker when
- * the failover option passed as 'singlebroker'.
- */
- public void testExplictFailoverOptionSingleBroker() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'&failover='singlebroker'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof FailoverSingleServer);
- }
-
- /**
- * Tests round robin method is selected for a brokerlist with two brokers when
- * the failover option passed as 'roundrobin'.
- */
- public void testExplictFailoverOptionRoundrobin() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672;tcp://localhost:5673'&failover='roundrobin'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof FailoverRoundRobinServers);
- }
-
- /**
- * Tests no failover method is selected for a brokerlist with one broker when
- * the failover option passed as 'nofailover'.
- */
- public void testExplictFailoverOptionNofailover() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'&failover='nofailover'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof NoFailover);
- }
-
- /**
- * Tests failover exchange method is selected for a brokerlist with one broker when
- * the failover option passed as 'failover_exchange'.
- */
- public void testExplictFailoverOptionFailoverExchange() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'&failover='failover_exchange'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof FailoverExchangeMethod);
- }
-
- /**
- * Tests that a custom method can be selected for a brokerlist with one brokers when
- * the failover option passed as a qualified class-name.
- */
- public void testExplictFailoverOptionDynamicallyLoadedFailoverMethod() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'&failover='org.apache.qpid.jms.FailoverPolicyTest$MyFailoverMethod'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof MyFailoverMethod);
- }
-
- /**
- * Tests that an unknown method caused an exception.
- */
- public void testUnknownFailoverMethod() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'&failover='unknown'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- try
- {
- new FailoverPolicy(_connectionUrl, _connection);
- fail("Exception not thrown");
- }
- catch(IllegalArgumentException iae)
- {
- // PASS
- }
- }
-
- private Connection createStubConnection()
- {
- return new Connection()
- {
-
- @Override
- public Session createSession(boolean transacted,
- int acknowledgeMode, int prefetch) throws JMSException
- {
- return null;
- }
-
- @Override
- public Session createSession(boolean transacted,
- int acknowledgeMode, int prefetchHigh, int prefetchLow)
- throws JMSException
- {
- return null;
- }
-
- @Override
- public ConnectionListener getConnectionListener()
- {
- return null;
- }
-
- @Override
- public long getMaximumChannelCount() throws JMSException
- {
- return 0;
- }
-
- @Override
- public void setConnectionListener(ConnectionListener listener)
- {
- }
-
- @Override
- public void close() throws JMSException
- {
- }
-
- @Override
- public ConnectionConsumer createConnectionConsumer(
- Destination arg0, String arg1, ServerSessionPool arg2,
- int arg3) throws JMSException
- {
- return null;
- }
-
- @Override
- public ConnectionConsumer createDurableConnectionConsumer(
- Topic arg0, String arg1, String arg2,
- ServerSessionPool arg3, int arg4) throws JMSException
- {
- return null;
- }
-
- @Override
- public javax.jms.Session createSession(boolean arg0, int arg1)
- throws JMSException
- {
- return null;
- }
-
- @Override
- public String getClientID() throws JMSException
- {
- return null;
- }
-
- @Override
- public ExceptionListener getExceptionListener() throws JMSException
- {
- return null;
- }
-
- @Override
- public ConnectionMetaData getMetaData() throws JMSException
- {
- return null;
- }
-
- @Override
- public void setClientID(String arg0) throws JMSException
- {
- }
-
- @Override
- public void setExceptionListener(ExceptionListener arg0)
- throws JMSException
- {
- }
-
- @Override
- public void start() throws JMSException
- {
- }
-
- @Override
- public void stop() throws JMSException
- {
- }
- };
- }
-
- // Class used to test the ability of FailoverPolicy to load an implementation.
- static class MyFailoverMethod implements FailoverMethod
- {
- public MyFailoverMethod(ConnectionURL connectionDetails)
- {
- }
-
- @Override
- public void attainedConnection()
- {
- }
-
- @Override
- public boolean failoverAllowed()
- {
- return false;
- }
-
- @Override
- public BrokerDetails getCurrentBrokerDetails()
- {
- return null;
- }
-
- @Override
- public BrokerDetails getNextBrokerDetails()
- {
- return null;
- }
-
- @Override
- public String methodName()
- {
- return null;
- }
-
- @Override
- public void reset()
- {
- }
-
- @Override
- public void setBroker(BrokerDetails broker)
- {
- }
-
- @Override
- public void setRetries(int maxRetries)
- {
- }
- }
-
-}
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java
index 9095f94960..1b27ff6300 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java
@@ -43,6 +43,15 @@ public class BrokerDetailsTest extends TestCase
assertTrue(broker.getProperty("immediatedelivery").equals("true"));
}
+ public void testVMBroker() throws URLSyntaxException
+ {
+ String url = "vm://:2";
+
+ AMQBrokerDetails broker = new AMQBrokerDetails(url);
+ assertTrue(broker.getTransport().equals("vm"));
+ assertEquals(broker.getPort(), 2);
+ }
+
public void testTransportsDefaultToTCP() throws URLSyntaxException
{
String url = "localhost:5672";
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 d560c413e6..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
@@ -73,7 +73,7 @@ public class ChannelCloseMethodHandlerNoCloseOk implements StateAwareMethodListe
{
throw new AMQNoRouteException("Error: " + reason, null, null);
}
- else if (errorCode == AMQConstant.ARGUMENT_INVALID)
+ else if (errorCode == AMQConstant.INVALID_ARGUMENT)
{
_logger.debug("Broker responded with Invalid Argument.");
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 4624b36fea..2be3720c20 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
@@ -300,6 +300,53 @@ public class ConnectionURLTest extends TestCase
assertTrue(connectionurl.getOption("immediatedelivery").equals("true"));
}
+ public void testSinglevmURL() throws URLSyntaxException
+ {
+ String url = "amqp://guest:guest@/test?brokerlist='vm://:2'";
+
+ 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("vm"));
+ assertTrue(service.getHost().equals(""));
+ assertTrue(service.getPort() == 2);
+
+ }
+
+ public void testFailoverVMURL() throws URLSyntaxException
+ {
+ String url = "amqp://ritchiem:bob@/test?brokerlist='vm://:2;vm://:3',failover='roundrobin'";
+
+ ConnectionURL connectionurl = new AMQConnectionURL(url);
+
+ assertTrue(connectionurl.getFailoverMethod().equals("roundrobin"));
+ assertTrue(connectionurl.getUsername().equals("ritchiem"));
+ assertTrue(connectionurl.getPassword().equals("bob"));
+ assertTrue(connectionurl.getVirtualHost().equals("/test"));
+
+ assertTrue(connectionurl.getBrokerCount() == 2);
+
+ BrokerDetails service = connectionurl.getBrokerDetails(0);
+
+ assertTrue(service.getTransport().equals("vm"));
+ assertTrue(service.getHost().equals(""));
+ assertTrue(service.getPort() == 2);
+
+ service = connectionurl.getBrokerDetails(1);
+ assertTrue(service.getTransport().equals("vm"));
+ assertTrue(service.getHost().equals(""));
+ assertTrue(service.getPort() == 3);
+ }
+
+
public void testNoVirtualHostURL()
{
String url = "amqp://user@?brokerlist='tcp://localhost:5672'";
@@ -440,6 +487,27 @@ public class ConnectionURLTest extends TestCase
}
+ public void testSocketProtocol() throws URLSyntaxException
+ {
+ String url = "amqp://guest:guest@id/test" + "?brokerlist='socket://VM-Unique-socketID'";
+
+ try
+ {
+ AMQConnectionURL curl = new AMQConnectionURL(url);
+ assertNotNull(curl);
+ assertEquals(1, curl.getBrokerCount());
+ assertNotNull(curl.getBrokerDetails(0));
+ assertEquals(BrokerDetails.SOCKET, curl.getBrokerDetails(0).getTransport());
+ assertEquals("VM-Unique-socketID", curl.getBrokerDetails(0).getHost());
+ assertEquals("URL does not toString as expected",
+ url.replace(":guest", ":********"), curl.toString());
+ }
+ catch (URLSyntaxException e)
+ {
+ fail(e.getMessage());
+ }
+ }
+
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'";
@@ -481,37 +549,6 @@ public class ConnectionURLTest extends TestCase
assertTrue("String representation should contain options and values", url.toString().contains("maxprefetch='12345'"));
}
- public void testHostNamesWithUnderScore() throws URLSyntaxException
- {
- String url = "amqp://guest:guest@clientid/test?brokerlist='tcp://under_score:6672'";
-
- ConnectionURL connectionurl = new AMQConnectionURL(url);
-
- 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("under_score"));
- assertTrue(service.getPort() == 6672);
-
- url = "amqp://guest:guest@clientid/test?brokerlist='tcp://under_score'";
-
- connectionurl = new AMQConnectionURL(url);
-
- assertTrue(connectionurl.getUsername().equals("guest"));
- assertTrue(connectionurl.getPassword().equals("guest"));
- assertTrue(connectionurl.getVirtualHost().equals("/test"));
-
- assertTrue(connectionurl.getBrokerCount() == 1);
- service = connectionurl.getBrokerDetails(0);
- assertTrue(service.getTransport().equals("tcp"));
- assertTrue(service.getHost().equals("under_score"));
- assertTrue(service.getPort() == 5672);
- }
-
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/message/ObjectMessageUnitTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/message/ObjectMessageUnitTest.java
deleted file mode 100644
index e37970e9a2..0000000000
--- a/java/client/src/test/java/org/apache/qpid/test/unit/client/message/ObjectMessageUnitTest.java
+++ /dev/null
@@ -1,105 +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 java.util.ArrayList;
-import java.util.Arrays;
-
-import org.apache.qpid.client.message.JMSObjectMessage;
-import org.apache.qpid.client.message.TestMessageHelper;
-import org.apache.qpid.test.utils.QpidTestCase;
-
-public class ObjectMessageUnitTest extends QpidTestCase
-{
- private JMSObjectMessage _om;
-
- protected void setUp() throws Exception
- {
- super.setUp();
- _om = TestMessageHelper.newJMSObjectMessage();
- }
-
- /**
- * Test that setObject with a primitive works
- */
- public void testSetObjectWithBooleanPrimitive() throws Exception
- {
- _om.setObject(true);
-
- //make the message readable
- Object object = _om.getObject();
-
- assertTrue("Unexpected type returned", object instanceof Boolean);
- assertEquals("Unexpected value returned", true, object);
- }
-
- /**
- * Test that setObject with a serializable Object works
- */
- public void testSetObjectWithString() throws Exception
- {
- _om.setObject("test string");
-
- //make the message readable
- Object object = _om.getObject();
-
- assertTrue("Unexpected type returned", object instanceof String);
- assertEquals("Unexpected value returned", "test string", object);
- }
-
- /**
- * Test that setObject with a Collection of serializable's works, returning
- * the items in the list when deserialized and ignoring any values
- * added to the collection after setObject() is called on the message.
- */
- public void testSetObjectWithArrayListOfInteger() throws Exception
- {
- ArrayList<Integer> list = new ArrayList<Integer>();
- list.add(1234);
- list.add(Integer.MIN_VALUE);
- list.add(Integer.MAX_VALUE);
-
- _om.setObject(list);
-
- //add something extra to the list now, and check it isn't in the value read back
- list.add(0);
-
- //make the message readable
-
- //retrieve the Object
- Object object = _om.getObject();
-
- ArrayList<?> returnedList = null;
- if(object instanceof ArrayList<?>)
- {
- returnedList = (ArrayList<?>) object;
- }
- else
- {
- fail("returned object was not an ArrayList");
- }
-
- //verify the extra added Integer was not present, then remove it from original list again and compare contents with the returned list
- assertFalse("returned list should not have had the value added after setObject() was used", returnedList.contains(0));
- list.remove(Integer.valueOf(0));
- assertTrue("list contents were not equal", Arrays.equals(list.toArray(), returnedList.toArray()));
- }
-}
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/jndi/ConnectionFactoryTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/jndi/ConnectionFactoryTest.java
index 20496026ce..9e76b0d468 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/jndi/ConnectionFactoryTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/jndi/ConnectionFactoryTest.java
@@ -21,10 +21,10 @@
package org.apache.qpid.test.unit.jndi;
import junit.framework.TestCase;
-
import org.apache.qpid.client.AMQConnectionFactory;
import org.apache.qpid.jms.BrokerDetails;
import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.url.URLSyntaxException;
public class ConnectionFactoryTest extends TestCase
{
@@ -34,9 +34,21 @@ public class ConnectionFactoryTest extends TestCase
public static final String URL = "amqp://guest:guest@clientID/test?brokerlist='tcp://localhost:5672'";
public static final String URL_STAR_PWD = "amqp://guest:********@clientID/test?brokerlist='tcp://localhost:5672'";
- public void testConnectionURLStringMasksPassword() throws Exception
+ public void testConnectionURLString()
{
- AMQConnectionFactory factory = new AMQConnectionFactory(URL);
+ AMQConnectionFactory factory = new AMQConnectionFactory();
+
+ assertNull("ConnectionURL should have no value at start",
+ factory.getConnectionURL());
+
+ try
+ {
+ factory.setConnectionURLString(URL);
+ }
+ catch (URLSyntaxException e)
+ {
+ fail(e.getMessage());
+ }
//URL will be returned with the password field swapped for '********'
assertEquals("Connection URL not correctly set", URL_STAR_PWD, factory.getConnectionURLString());
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/jndi/JNDIPropertyFileTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/jndi/JNDIPropertyFileTest.java
index 2052312f54..a1b14d5723 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/jndi/JNDIPropertyFileTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/jndi/JNDIPropertyFileTest.java
@@ -24,7 +24,6 @@ import java.util.Properties;
import javax.jms.Queue;
import javax.jms.Topic;
-import javax.naming.ConfigurationException;
import javax.naming.Context;
import javax.naming.InitialContext;
@@ -68,22 +67,4 @@ public class JNDIPropertyFileTest extends TestCase
assertEquals("Topic" + i + "WithSpace",bindingKey.asString());
}
}
-
- public void testConfigurationErrors() throws Exception
- {
- Properties properties = new Properties();
- properties.put("java.naming.factory.initial", "org.apache.qpid.jndi.PropertiesFileInitialContextFactory");
- properties.put("destination.my-queue","amq.topic/test;create:always}");
-
- try
- {
- ctx = new InitialContext(properties);
- fail("A configuration exception should be thrown with details about the address syntax error");
- }
- catch(ConfigurationException e)
- {
- assertTrue("Incorrect exception", e.getMessage().contains("Failed to parse entry: amq.topic/test;create:always}"));
- }
-
- }
}
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
index 6759b43387..47c0359b94 100644
--- 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
@@ -20,24 +20,17 @@
*/
package org.apache.qpid.test.unit.message;
-import java.util.Map;
-
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.TemporaryQueue;
-import javax.jms.Topic;
-import javax.jms.TopicSubscriber;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQDestination;
-import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.client.BasicMessageConsumer_0_8;
-import org.apache.qpid.client.BasicMessageProducer_0_8;
-import org.apache.qpid.client.failover.FailoverException;
+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>
{
@@ -64,12 +57,7 @@ public class TestAMQSession extends AMQSession<BasicMessageConsumer_0_8, BasicMe
}
- public void commitImpl() throws AMQException, FailoverException
- {
-
- }
-
- public void acknowledgeImpl()
+ public void sendCommit() throws AMQException, FailoverException
{
}
@@ -129,7 +117,7 @@ public class TestAMQSession extends AMQSession<BasicMessageConsumer_0_8, BasicMe
}
- public BasicMessageProducer_0_8 createMessageProducer(Destination destination, boolean mandatory, boolean immediate, long producerId)
+ public BasicMessageProducer_0_8 createMessageProducer(Destination destination, boolean mandatory, boolean immediate, boolean waitUntilSent, long producerId)
{
return null;
}
@@ -207,10 +195,4 @@ public class TestAMQSession extends AMQSession<BasicMessageConsumer_0_8, BasicMe
{
return false;
}
-
- @Override
- public AMQException getLastException()
- {
- return null;
- }
}