summaryrefslogtreecommitdiff
path: root/qpid/java
diff options
context:
space:
mode:
authorKeith Wall <kwall@apache.org>2014-01-14 14:46:35 +0000
committerKeith Wall <kwall@apache.org>2014-01-14 14:46:35 +0000
commit840bf7469dc7b18d74eaa275bb23ed09dd0e168b (patch)
treeeb4ef3da5fdbeb57d89f4ef1f0d0e175c4285e3f /qpid/java
parent4e99d2f6a47801531ddd443fc120fee79e0568b2 (diff)
downloadqpid-python-840bf7469dc7b18d74eaa275bb23ed09dd0e168b.tar.gz
NO-JIRA: Merge latest changes back from trunk.
Changes merged with command: svn merge -r 1549894:1558036 https://svn.apache.org/repos/asf/qpid/trunk git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/java-broker-bdb-ha@1558056 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java')
-rw-r--r--qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java400
-rw-r--r--qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java92
-rw-r--r--qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageConsumerImpl.java17
-rw-r--r--qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageProducerImpl.java16
-rw-r--r--qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/SessionImpl.java18
-rw-r--r--qpid/java/amqp-1-0-client-websocket/build.xml39
-rw-r--r--qpid/java/amqp-1-0-client-websocket/pom.xml163
-rw-r--r--qpid/java/amqp-1-0-client-websocket/resources/LICENSE204
-rw-r--r--qpid/java/amqp-1-0-client-websocket/resources/NOTICE5
-rw-r--r--qpid/java/amqp-1-0-client-websocket/resources/README.txt7
-rw-r--r--qpid/java/amqp-1-0-client-websocket/src/main/java/org/apache/qpid/amqp_1_0/client/websocket/WebSocketProvider.java322
-rw-r--r--qpid/java/amqp-1-0-client-websocket/src/main/java/org/apache/qpid/amqp_1_0/client/websocket/WebSocketTransportProviderFactory.java42
-rw-r--r--qpid/java/amqp-1-0-client-websocket/src/main/resources/META-INF/services/org.apache.qpid.amqp_1_0.client.TransportProviderFactory19
-rw-r--r--qpid/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Respond.java5
-rw-r--r--qpid/java/amqp-1-0-client/pom.xml11
-rw-r--r--qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java362
-rw-r--r--qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/ConnectionErrorException.java8
-rw-r--r--qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java49
-rw-r--r--qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SSLUtil.java215
-rw-r--r--qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Sender.java179
-rw-r--r--qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TCPTransportProviderFactory.java39
-rw-r--r--qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TCPTransportProvier.java203
-rw-r--r--qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransportProvider.java37
-rw-r--r--qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransportProviderFactory.java29
-rw-r--r--qpid/java/amqp-1-0-client/src/main/resources/META-INF/services/org.apache.qpid.amqp_1_0.client.TransportProviderFactory19
-rw-r--r--qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolTypeConstructor.java15
-rw-r--r--qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ConnectionHandler.java81
-rw-r--r--qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ExceptionHandler.java (renamed from qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SocketExceptionHandler.java)4
-rw-r--r--qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameHandler.java4
-rw-r--r--qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEndpoint.java54
-rw-r--r--qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/LinkEndpoint.java18
-rw-r--r--qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Predicate.java26
-rw-r--r--qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionEndpoint.java30
-rw-r--r--qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Error.java13
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java24
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/add.html16
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/virtualhost/store/bdb/add.html16
-rw-r--r--qpid/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HAClusterManagementTest.java10
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java3
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DefaultExchange.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java4
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DirectExchangeType.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java6
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeType.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/FilterSupport.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersBinding.java2
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java3
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeType.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java2
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/TopicExchangeType.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/filter/FilterManagerFactory.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Connection.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Transport.java5
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java124
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java4
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java7
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java2
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/ExchangeType.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/TransportProviderFactory.java35
-rwxr-xr-xqpid/java/broker-core/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java46
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AMQQueue.java2
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/BaseQueue.java1
-rwxr-xr-xqpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java17
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/SubjectCreator.java17
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCMessageStore.java12
-rwxr-xr-xqpid/java/broker-core/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java3
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationStoreHelper.java3
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java12
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java22
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/subscription/Subscription.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/AcceptingTransport.java27
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransport.java146
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransportProvider.java41
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransportProviderFactory.java55
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TransportProvider.java38
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java10
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/BindingRecoverer.java3
-rw-r--r--qpid/java/broker-core/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.TransportProviderFactory19
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java1
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/DefaultExchangeFactoryTest.java1
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/FanoutExchangeTest.java2
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/HeadersExchangeTest.java1
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java2
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java1
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/InboundMessageAdapterTest.java1
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java2
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java2
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/TestMessageMetaData.java20
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java1
-rw-r--r--qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java1
-rwxr-xr-xqpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/MessageMetaData_0_10.java1
-rw-r--r--qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/MessageTransferMessage.java1
-rwxr-xr-xqpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ProtocolEngine_0_10.java10
-rw-r--r--qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java8
-rw-r--r--qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerSessionDelegate.java14
-rw-r--r--qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java4
-rw-r--r--qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/handler/ExchangeBoundHandler.java23
-rw-r--r--qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngineTest.java20
-rw-r--r--qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java5
-rw-r--r--qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java1
-rw-r--r--qpid/java/broker-plugins/amqp-msg-conv-0-8-to-0-10/src/main/java/org/apache/qpid/server/protocol/converter/v0_8_v0_10/MessageConverter_0_10_to_0_8.java20
-rw-r--r--qpid/java/broker-plugins/derby-store/src/main/java/resources/virtualhost/store/derby/add.html16
-rw-r--r--qpid/java/broker-plugins/jdbc-provider-bone/src/main/java/resources/virtualhost/store/pool/bonecp/add.html16
-rw-r--r--qpid/java/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/store/jdbc/add.html16
-rw-r--r--qpid/java/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/store/pool/none/add.html17
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java84
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java38
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java1
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java7
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/addPort.html6
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/footer.html4
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Connection.js10
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js19
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/showConnection.html14
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/showMessage.html8
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/standard/add.html16
-rw-r--r--qpid/java/broker-plugins/memory-store/src/main/java/resources/virtualhost/store/memory/add.html17
-rw-r--r--qpid/java/broker-plugins/websocket/build.xml32
-rw-r--r--qpid/java/broker-plugins/websocket/pom.xml158
-rw-r--r--qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketProvider.java315
-rw-r--r--qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketTransportProvider.java51
-rw-r--r--qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketTransportProviderFactory.java56
-rw-r--r--qpid/java/broker-plugins/websocket/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.TransportProviderFactory19
-rw-r--r--qpid/java/build.deps3
-rw-r--r--qpid/java/build.xml2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java14
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractAMQMessageDelegate.java5
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/transport/TestNetworkConnection.java5
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java6
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java2
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java43
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java15
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IdleTimeoutTickerTest.java5
-rw-r--r--qpid/java/ivy.nexus.xml6
-rw-r--r--qpid/java/jca/README-GERONIMO.txt18
-rw-r--r--qpid/java/jca/README-JBOSS-EAP6.txt18
-rw-r--r--qpid/java/jca/README-JBOSS.txt18
-rw-r--r--qpid/java/jca/README.txt18
-rw-r--r--qpid/java/jca/example/README-EXAMPLE.txt18
-rw-r--r--qpid/java/jca/example/README-GERONIMO.txt18
-rw-r--r--qpid/java/jca/example/README-GLASSFISH.txt18
-rw-r--r--qpid/java/jca/example/README-JBOSS.txt18
-rw-r--r--qpid/java/jca/example/README-JBOSS7.txt18
-rw-r--r--qpid/java/jca/example/conf/glassfish-ejb-jar.xml20
-rw-r--r--qpid/java/jca/example/conf/glassfish-resources.xml20
-rw-r--r--qpid/java/jca/example/conf/glassfish-web.xml20
-rw-r--r--qpid/java/module.xml12
-rw-r--r--qpid/java/pom.xml29
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java5
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MessageGroupQueueTest.java141
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ExchangeManagementTest.java20
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java5
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestHttpsClientCertAuthTest.java89
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/PreferencesRestTest.java20
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java2
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java37
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java7
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/JMSDestinationTest.java110
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java23
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java5
166 files changed, 4506 insertions, 888 deletions
diff --git a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java
index f46840e9ae..f8af2d388e 100644
--- a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java
+++ b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java
@@ -26,16 +26,27 @@ import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.net.URLStreamHandler;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.Map;
import javax.jms.JMSException;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
+
+import org.apache.qpid.amqp_1_0.client.SSLUtil;
import org.apache.qpid.amqp_1_0.jms.ConnectionFactory;
public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnectionFactory, QueueConnectionFactory
{
+ private final String _protocol;
private String _host;
private int _port;
private String _username;
@@ -49,6 +60,13 @@ public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnection
private boolean _useBinaryMessageId = Boolean.parseBoolean(System.getProperty("qpid.use_binary_message_id", "true"));
private boolean _syncPublish = Boolean.parseBoolean(System.getProperty("qpid.sync_publish", "false"));
private int _maxSessions = Integer.getInteger("qpid.max_sessions", 0);
+ private int _maxPrefetch;
+ private String _keyStorePath;
+ private String _keyStorePassword;
+ private String _keyStoreCertAlias;
+ private String _trustStorePath;
+ private String _trustStorePassword;
+ private SSLContext _sslContext;
public ConnectionFactoryImpl(final String host,
@@ -98,6 +116,20 @@ public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnection
final boolean ssl,
final int maxSessions)
{
+ this(ssl?"amqps":"amqp",host,port,username,password,clientId,remoteHost,ssl,maxSessions);
+ }
+
+ public ConnectionFactoryImpl(final String protocol,
+ final String host,
+ final int port,
+ final String username,
+ final String password,
+ final String clientId,
+ final String remoteHost,
+ final boolean ssl,
+ final int maxSessions)
+ {
+ _protocol = protocol;
_host = host;
_port = port;
_username = username;
@@ -113,118 +145,342 @@ public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnection
return createConnection(_username, _password);
}
- public ConnectionImpl createConnection(final String username, final String password) throws JMSException
+ public ConnectionImpl createConnection(String username, final String password) throws JMSException
{
- ConnectionImpl connection = new ConnectionImpl(_host, _port, username, password, _clientId, _remoteHost, _ssl, _maxSessions);
+ synchronized (this)
+ {
+ if(_ssl && _sslContext == null)
+ {
+ try
+ {
+ _sslContext = SSLUtil.buildSslContext(_keyStoreCertAlias,_keyStorePath,
+ KeyStore.getDefaultType(),
+ _keyStorePassword,
+ KeyManagerFactory.getDefaultAlgorithm(),
+ _trustStorePath,_trustStorePassword,
+ KeyStore.getDefaultType(),
+ TrustManagerFactory.getDefaultAlgorithm());
+ if(username == null && _keyStoreCertAlias != null)
+ {
+ X509Certificate[] certs = SSLUtil.getClientCertificates(_keyStoreCertAlias,
+ _keyStorePath,
+ _keyStorePassword,
+ KeyStore.getDefaultType(),
+ KeyManagerFactory.getDefaultAlgorithm());
+ if(certs != null && certs.length != 0)
+ {
+ username = certs[0].getSubjectDN().getName();
+ }
+ }
+
+ }
+ catch (GeneralSecurityException e)
+ {
+ final JMSException jmsException = new JMSException("Unable to create SSL context");
+ jmsException.setLinkedException(e);
+ jmsException.initCause(e);
+ throw jmsException;
+ }
+ catch (IOException e)
+ {
+ final JMSException jmsException = new JMSException("Unable to create SSL context");
+ jmsException.setLinkedException(e);
+ jmsException.initCause(e);
+ throw jmsException; }
+ }
+ }
+ ConnectionImpl connection = new ConnectionImpl(_protocol,_host, _port, username, password, _clientId, _remoteHost, _sslContext, _maxSessions);
connection.setQueuePrefix(_queuePrefix);
connection.setTopicPrefix(_topicPrefix);
connection.setUseBinaryMessageId(_useBinaryMessageId);
connection.setSyncPublish(_syncPublish);
+ if(_maxPrefetch != 0)
+ {
+ connection.setMaxPrefetch(_maxPrefetch);
+ }
return connection;
}
+ public void setMaxPrefetch(final int maxPrefetch)
+ {
+ _maxPrefetch = maxPrefetch;
+ }
+
+ public void setKeyStorePath(final String keyStorePath)
+ {
+ _keyStorePath = keyStorePath;
+ }
+
+ public void setKeyStorePassword(final String keyStorePassword)
+ {
+ _keyStorePassword = keyStorePassword;
+ }
+
+ public void setKeyStoreCertAlias(final String keyStoreCertAlias)
+ {
+ _keyStoreCertAlias = keyStoreCertAlias;
+ }
+
+ public void setTrustStorePath(final String trustStorePath)
+ {
+ _trustStorePath = trustStorePath;
+ }
+
+ public void setTrustStorePassword(final String trustStorePassword)
+ {
+ _trustStorePassword = trustStorePassword;
+ }
+
+ private static class ConnectionOptions
+ {
+ String username;
+ String password;
+ String clientId;
+ String remoteHost;
+
+ boolean binaryMessageId = true;
+ boolean syncPublish;
+ int maxSessions;
+ public boolean ssl;
+ public int maxPrefetch;
+ public String trustStorePath;
+ public String trustStorePassword;
+ public String keyStorePath;
+ public String keyStorePassword;
+ public String keyStoreCertAlias;
+ }
+
+
+
+ private static abstract class OptionSetter
+ {
+
+ private static final Map<String, OptionSetter> OPTION_SETTER_MAP = new HashMap<String, OptionSetter>();
+ private final String _name;
+ private final String _description;
+
+ public OptionSetter(String name, String description)
+ {
+ OPTION_SETTER_MAP.put(name.toLowerCase(), this);
+ _name = name;
+ _description = description;
+ }
+
+ public abstract void setOption(ConnectionOptions options, String value) throws MalformedURLException;
+
+ public static void parseOptions(URL url, ConnectionOptions options) throws MalformedURLException
+ {
+ String query = url.getQuery();
+ if(query != null)
+ {
+ for(String param : query.split("&"))
+ {
+
+ String[] keyValuePair = param.split("=",2);
+ OptionSetter setter = OPTION_SETTER_MAP.get(keyValuePair[0]);
+ if(setter != null)
+ {
+ setter.setOption(options, keyValuePair[1]);
+ }
+ else
+ {
+ throw new MalformedURLException("Unknown URL option: '"+keyValuePair[0]+"' in connection URL");
+ }
+
+ }
+ }
+ }
+ }
+
+ private static final OptionSetter[] _options =
+ {
+ new OptionSetter("clientid", "JMS client id / AMQP container id")
+ {
+ public void setOption(ConnectionOptions options, String value)
+ {
+ options.clientId = value;
+ }
+ },
+ new OptionSetter("ssl", "Set to \"true\" to use SSL encryption")
+ {
+ public void setOption(ConnectionOptions options, String value)
+ {
+ options.ssl = Boolean.valueOf(value);
+ }
+ },
+ new OptionSetter("remote-host", "AMQP remote host")
+ {
+ public void setOption(ConnectionOptions options, String value)
+ {
+ options.remoteHost = value;
+ }
+ },
+ new OptionSetter("binary-messageid", "Use binary (rather than String) message ids")
+ {
+ public void setOption(ConnectionOptions options, String value)
+ {
+ options.binaryMessageId = Boolean.parseBoolean(value);
+ }
+ },
+ new OptionSetter("sync-publish", "Wait for acknowledge when sending messages")
+ {
+ public void setOption(ConnectionOptions options, String value)
+ {
+ options.syncPublish = Boolean.parseBoolean(value);
+ }
+ },
+ new OptionSetter("max-sessions", "set maximum number of sessions allowed")
+ {
+ public void setOption(ConnectionOptions options, String value)
+ {
+ options.maxSessions = Integer.parseInt(value);
+ }
+ },
+ new OptionSetter("max-prefetch", "set maximum number of messages prefetched on a link")
+ {
+ public void setOption(ConnectionOptions options, String value)
+ {
+ options.maxPrefetch = Integer.parseInt(value);
+ }
+ },
+ new OptionSetter("trust-store","")
+ {
+ public void setOption(final ConnectionOptions options, final String value) throws MalformedURLException
+ {
+ options.trustStorePath = value;
+ }
+ },
+ new OptionSetter("trust-store-password","")
+ {
+ public void setOption(final ConnectionOptions options, final String value) throws MalformedURLException
+ {
+ options.trustStorePassword = value;
+ }
+ },
+ new OptionSetter("key-store","")
+ {
+ public void setOption(final ConnectionOptions options, final String value) throws MalformedURLException
+ {
+ options.keyStorePath = value;
+ }
+ },
+ new OptionSetter("key-store-password","")
+ {
+ public void setOption(final ConnectionOptions options, final String value) throws MalformedURLException
+ {
+ options.keyStorePassword = value;
+ }
+ },
+ new OptionSetter("ssl-cert-alias","")
+ {
+ public void setOption(final ConnectionOptions options, final String value) throws MalformedURLException
+ {
+ options.keyStoreCertAlias = value;
+ }
+ }
+ };
+
public static ConnectionFactoryImpl createFromURL(final String urlString) throws MalformedURLException
{
URL url = new URL(null, urlString, new URLStreamHandler()
- {
- @Override
- protected URLConnection openConnection(URL u) throws IOException
- {
- throw new UnsupportedOperationException();
- }
- });
+ {
+ @Override
+ protected URLConnection openConnection(URL u) throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+ });
String protocol = url.getProtocol();
- if(protocol == null || "".equals(protocol))
+ if (protocol == null || "".equals(protocol))
{
protocol = "amqp";
}
- else if(!protocol.equals("amqp") && !protocol.equals("amqps"))
- {
- throw new MalformedURLException("Protocol '"+protocol+"' unknown. Must be one of 'amqp' or 'amqps'.");
- }
String host = url.getHost();
int port = url.getPort();
- boolean ssl = false;
+ final ConnectionOptions options = new ConnectionOptions();
- if(port == -1)
+ if (port == -1)
{
- if("amqps".equals(protocol))
+ if ("amqps".equals(protocol))
{
port = 5671;
- ssl = true;
+ options.ssl = true;
}
- else
+ else if("amqp".equals(protocol))
{
port = 5672;
}
+ else if("ws".equals(protocol))
+ {
+ port = 80;
+ }
+ else if("wss".equals(protocol))
+ {
+ port = 443;
+ }
}
- else if("amqps".equals(protocol))
+ else if ("amqps".equals(protocol) || "wss".equals(protocol))
{
- ssl = true;
+ options.ssl = true;
}
- String userInfo = url.getUserInfo();
- String username = null;
- String password = null;
- String clientId = null;
- String remoteHost = null;
- boolean binaryMessageId = true;
- boolean syncPublish = false;
- int maxSessions = 0;
+ String userInfo = url.getUserInfo();
- if(userInfo != null)
+ if (userInfo != null)
{
- String[] components = userInfo.split(":",2);
- username = URLDecoder.decode(components[0]);
- if(components.length == 2)
+ String[] components = userInfo.split(":", 2);
+ options.username = URLDecoder.decode(components[0]);
+ if (components.length == 2)
{
- password = URLDecoder.decode(components[1]);
- }
- }
- String query = url.getQuery();
- if(query != null)
- {
- for(String param : query.split("&"))
- {
- String[] keyValuePair = param.split("=",2);
- if(keyValuePair[0].equalsIgnoreCase("clientid"))
- {
- clientId = keyValuePair[1];
- }
- else if(keyValuePair[0].equalsIgnoreCase("ssl"))
- {
- ssl = Boolean.valueOf(keyValuePair[1]);
- }
- else if(keyValuePair[0].equalsIgnoreCase("remote-host"))
- {
- remoteHost = keyValuePair[1];
- }
- else if (keyValuePair[0].equalsIgnoreCase("binary-messageid"))
- {
- binaryMessageId = Boolean.parseBoolean(keyValuePair[1]);
- }
- else if (keyValuePair[0].equalsIgnoreCase("sync-publish"))
- {
- syncPublish = Boolean.parseBoolean(keyValuePair[1]);
- }
- else if(keyValuePair[0].equalsIgnoreCase("max-sessions"))
- {
- maxSessions = Integer.parseInt(keyValuePair[1]);
- }
+ options.password = URLDecoder.decode(components[1]);
}
}
- if(remoteHost == null)
+ OptionSetter.parseOptions(url, options);
+
+ if (options.remoteHost == null)
{
- remoteHost = host;
+ options.remoteHost = host;
}
ConnectionFactoryImpl connectionFactory =
- new ConnectionFactoryImpl(host, port, username, password, clientId, remoteHost, ssl, maxSessions);
- connectionFactory.setUseBinaryMessageId(binaryMessageId);
- connectionFactory.setSyncPublish(syncPublish);
+ new ConnectionFactoryImpl(protocol,
+ host,
+ port,
+ options.username,
+ options.password,
+ options.clientId,
+ options.remoteHost,
+ options.ssl,
+ options.maxSessions);
+ connectionFactory.setUseBinaryMessageId(options.binaryMessageId);
+ connectionFactory.setSyncPublish(options.syncPublish);
+ if (options.maxPrefetch != 0)
+ {
+ connectionFactory.setMaxPrefetch(options.maxPrefetch);
+ }
+ if (options.keyStorePath != null)
+ {
+ connectionFactory.setKeyStorePath(options.keyStorePath);
+ }
+ if (options.keyStorePassword != null)
+ {
+ connectionFactory.setKeyStorePassword(options.keyStorePassword);
+ }
+ if (options.keyStoreCertAlias != null)
+ {
+ connectionFactory.setKeyStoreCertAlias(options.keyStoreCertAlias);
+ }
+ if (options.trustStorePath != null)
+ {
+ connectionFactory.setTrustStorePath(options.trustStorePath);
+ }
+ if (options.trustStorePassword != null)
+ {
+ connectionFactory.setTrustStorePassword(options.trustStorePassword);
+ }
return connectionFactory;
@@ -287,4 +543,6 @@ public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnection
{
_syncPublish = syncPublish;
}
+
+
}
diff --git a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java
index 976ae10c56..7ce445a9b2 100644
--- a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java
+++ b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java
@@ -28,7 +28,9 @@ import org.apache.qpid.amqp_1_0.transport.Container;
import javax.jms.*;
import javax.jms.IllegalStateException;
import javax.jms.Queue;
+import javax.net.ssl.SSLContext;
+import java.security.NoSuchAlgorithmException;
import java.util.*;
import org.apache.qpid.amqp_1_0.type.Symbol;
@@ -38,6 +40,8 @@ import org.apache.qpid.amqp_1_0.type.transport.Error;
public class ConnectionImpl implements Connection, QueueConnection, TopicConnection
{
+ private final String _protocol;
+ private final SSLContext _sslContext;
private ConnectionMetaData _connectionMetaData;
private volatile ExceptionListener _exceptionListener;
@@ -54,13 +58,18 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect
private final String _username;
private final String _password;
private String _remoteHost;
- private final boolean _ssl;
private String _clientId;
private String _queuePrefix;
private String _topicPrefix;
private boolean _useBinaryMessageId = Boolean.parseBoolean(System.getProperty("qpid.use_binary_message_id", "true"));
private boolean _syncPublish = Boolean.parseBoolean(System.getProperty("qpid.sync_publish", "false"));
private int _maxSessions;
+ private int _maxPrefetch;
+
+ public void setMaxPrefetch(final int maxPrefetch)
+ {
+ _maxPrefetch = maxPrefetch;
+ }
private static enum State
{
@@ -87,15 +96,50 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect
this(host, port, username, password, clientId, remoteHost, ssl,0);
}
+
public ConnectionImpl(String host, int port, String username, String password, String clientId, String remoteHost, boolean ssl, int maxSessions) throws JMSException
{
+ this(ssl?"amqps":"amqp",host,port,username,password,clientId,remoteHost,ssl,maxSessions);
+ }
+
+ public ConnectionImpl(String protocol, String host, int port, String username, String password, String clientId, String remoteHost, boolean ssl, int maxSessions) throws JMSException
+ {
+ this(protocol,
+ host,
+ port,
+ username,
+ password,
+ clientId,
+ remoteHost,
+ ssl ? getDefaultSSLContext() : null,
+ maxSessions);
+ }
+
+ private static SSLContext getDefaultSSLContext() throws JMSException
+ {
+ try
+ {
+ return SSLContext.getDefault();
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ JMSException jmsException = new JMSException(e.getMessage());
+ jmsException.setLinkedException(e);
+ jmsException.initCause(e);
+ throw jmsException;
+ }
+ }
+
+ public ConnectionImpl(String protocol, String host, int port, String username, String password, String clientId, String remoteHost, SSLContext sslContext, int maxSessions) throws JMSException
+ {
+ _protocol = protocol;
_host = host;
_port = port;
_username = username;
_password = password;
_clientId = clientId;
_remoteHost = remoteHost;
- _ssl = ssl;
+ _sslContext = sslContext;
_maxSessions = maxSessions;
}
@@ -109,11 +153,11 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect
_state = State.STOPPED;
Container container = _clientId == null ? new Container() : new Container(_clientId);
- // TODO - authentication, containerId, clientId, ssl?, etc
+
try
{
- _conn = new org.apache.qpid.amqp_1_0.client.Connection(_host,
- _port, _username, _password, container, _remoteHost, _ssl,
+ _conn = new org.apache.qpid.amqp_1_0.client.Connection(_protocol, _host,
+ _port, _username, _password, container, _remoteHost, _sslContext,
_maxSessions - 1);
_conn.setConnectionErrorTask(new ConnectionErrorTask());
// TODO - retrieve negotiated AMQP version
@@ -182,6 +226,10 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect
SessionImpl session = new SessionImpl(this, acknowledgeMode);
session.setQueueSession(_isQueueConnection);
session.setTopicSession(_isTopicConnection);
+ if(_maxPrefetch != 0)
+ {
+ session.setMaxPrefetch(_maxPrefetch);
+ }
boolean connectionStarted = false;
synchronized(_lock)
@@ -370,21 +418,47 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect
_lock.notifyAll();
}
-
+
+ List<JMSException> errors = new ArrayList<JMSException>();
+
if (sessions != null)
{
for(SessionImpl session : sessions)
{
- session.close();
+ try
+ {
+ session.close();
+ }
+ catch(JMSException e)
+ {
+ errors.add(e);
+ }
}
for(CloseTask task : closeTasks)
{
task.onClose();
}
- if(closeConnection) {
- _conn.close();
+ if(closeConnection)
+ {
+ try
+ {
+ _conn.close();
+ }
+ catch (ConnectionErrorException e)
+ {
+ final JMSException jmsException = new JMSException("Error while closing connection: " + e.getMessage());
+ jmsException.setLinkedException(e);
+ throw jmsException;
+ }
}
}
+
+ if(!errors.isEmpty())
+ {
+ final JMSException jmsException = new JMSException("Error while closing connection: " + errors.get(0).getMessage());
+ jmsException.setLinkedException(errors.get(0));
+ throw jmsException;
+ }
}
private void checkClosed() throws IllegalStateException
diff --git a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageConsumerImpl.java b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageConsumerImpl.java
index fd6f09d162..96ee1e984d 100644
--- a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageConsumerImpl.java
+++ b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageConsumerImpl.java
@@ -76,6 +76,7 @@ public class MessageConsumerImpl implements MessageConsumer, QueueReceiver, Topi
private Binary _lastTxnUpdate;
private final List<Message> _recoverReplayMessages = new ArrayList<Message>();
private final List<Message> _replaymessages = new ArrayList<Message>();
+ private int _maxPrefetch = 100;
MessageConsumerImpl(final Destination destination,
final SessionImpl session,
@@ -117,6 +118,10 @@ public class MessageConsumerImpl implements MessageConsumer, QueueReceiver, Topi
throw new InvalidDestinationException("Invalid destination class " + destination.getClass().getName());
}
_session = session;
+ if(session.getMaxPrefetch() != 0)
+ {
+ _maxPrefetch = session.getMaxPrefetch();
+ }
_receiver = createClientReceiver();
_receiver.setRemoteErrorListener(new Runnable()
@@ -442,7 +447,7 @@ public class MessageConsumerImpl implements MessageConsumer, QueueReceiver, Topi
public void start()
{
- _receiver.setCredit(UnsignedInteger.valueOf(100), true);
+ _receiver.setCredit(UnsignedInteger.valueOf(getMaxPrefetch()), true);
}
public Queue getQueue() throws JMSException
@@ -487,4 +492,14 @@ public class MessageConsumerImpl implements MessageConsumer, QueueReceiver, Topi
}
}
}
+
+ public int getMaxPrefetch()
+ {
+ return _maxPrefetch;
+ }
+
+ public void setMaxPrefetch(final int maxPrefetch)
+ {
+ _maxPrefetch = maxPrefetch;
+ }
}
diff --git a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageProducerImpl.java b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageProducerImpl.java
index cee4f4f6f2..e459575974 100644
--- a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageProducerImpl.java
+++ b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageProducerImpl.java
@@ -34,6 +34,8 @@ import javax.jms.*;
import javax.jms.IllegalStateException;
import javax.jms.Message;
import java.util.UUID;
+import java.util.concurrent.TimeoutException;
+
import org.apache.qpid.amqp_1_0.type.messaging.Accepted;
import org.apache.qpid.amqp_1_0.type.messaging.Rejected;
import org.apache.qpid.amqp_1_0.type.messaging.Source;
@@ -221,7 +223,7 @@ public class MessageProducerImpl implements MessageProducer, QueueSender, TopicP
}
catch (Sender.SenderClosingException e)
{
- final JMSException jmsException = new JMSException("error closing");
+ final JMSException jmsException = new JMSException("Error closing producer: " + e.getMessage());
jmsException.setLinkedException(e);
throw jmsException;
}
@@ -299,8 +301,8 @@ public class MessageProducerImpl implements MessageProducer, QueueSender, TopicP
final org.apache.qpid.amqp_1_0.client.Message clientMessage = new org.apache.qpid.amqp_1_0.client.Message(msg.getSections());
DispositionAction action = null;
-
- if(_syncPublish)
+ final boolean doSync = _syncPublish || (deliveryMode == DeliveryMode.PERSISTENT && _session.getTxn() == null);
+ if(doSync)
{
action = new DispositionAction(_sender);
}
@@ -315,8 +317,14 @@ public class MessageProducerImpl implements MessageProducer, QueueSender, TopicP
jmsException.setLinkedException(e);
throw jmsException;
}
+ catch (TimeoutException e)
+ {
+ JMSException jmsException = new JMSException("Timed out while waiting to get credit to send");
+ jmsException.setLinkedException(e);
+ throw jmsException;
+ }
- if(_syncPublish && !action.wasAccepted(_syncPublishTimeout))
+ if(doSync && !action.wasAccepted(_syncPublishTimeout))
{
if (action.getOutcome() instanceof Rejected)
{
diff --git a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/SessionImpl.java b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/SessionImpl.java
index 3fa1032111..a1cf0ef4e7 100644
--- a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/SessionImpl.java
+++ b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/SessionImpl.java
@@ -81,6 +81,7 @@ public class SessionImpl implements Session, QueueSession, TopicSession
private boolean _isQueueSession;
private boolean _isTopicSession;
private Transaction _txn;
+ private int _maxPrefetch;
protected SessionImpl(final ConnectionImpl connection, final AcknowledgeMode acknowledgeMode) throws JMSException
{
@@ -523,6 +524,13 @@ public class SessionImpl implements Session, QueueSession, TopicSession
messageConsumer = new TopicSubscriberImpl(name, true, (org.apache.qpid.amqp_1_0.jms.Topic) topic, this,
selector,
noLocal);
+
+ if(_dispatcherThread == null)
+ {
+ _dispatcherThread = new Thread(_dispatcher);
+ _dispatcherThread.start();
+ }
+
addConsumer(messageConsumer);
if(_connection.isStarted())
{
@@ -836,6 +844,16 @@ public class SessionImpl implements Session, QueueSession, TopicSession
return _txn;
}
+ public void setMaxPrefetch(final int maxPrefetch)
+ {
+ _maxPrefetch = maxPrefetch;
+ }
+
+ public int getMaxPrefetch()
+ {
+ return _maxPrefetch;
+ }
+
private class Dispatcher implements Runnable
{
diff --git a/qpid/java/amqp-1-0-client-websocket/build.xml b/qpid/java/amqp-1-0-client-websocket/build.xml
new file mode 100644
index 0000000000..2d538aab66
--- /dev/null
+++ b/qpid/java/amqp-1-0-client-websocket/build.xml
@@ -0,0 +1,39 @@
+<!--
+ -
+ - 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.
+ -
+ -->
+<project name="AMQP 1.0 Client WebSocket transport" default="build">
+
+ <property name="module.genpom" value="true"/>
+ <property name="module.depends" value="amqp-1-0-common amqp-1-0-client"/>
+ <property name="release.exclude.module.deps" value="true"/>
+
+ <import file="../module.xml"/>
+
+ <target name="release-bin-copy-readme">
+ <copy todir="${module.release}" overwrite="true" failonerror="true">
+ <fileset file="${basedir}/README.txt" />
+ </copy>
+ </target>
+
+ <target name="release-bin-other" depends="release-bin-copy-readme"/>
+
+ <target name="release-bin" depends="release-bin-tasks"/>
+
+</project>
diff --git a/qpid/java/amqp-1-0-client-websocket/pom.xml b/qpid/java/amqp-1-0-client-websocket/pom.xml
new file mode 100644
index 0000000000..205e0d5ab7
--- /dev/null
+++ b/qpid/java/amqp-1-0-client-websocket/pom.xml
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.qpid</groupId>
+ <artifactId>qpid-project</artifactId>
+ <version>0.26-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>qpid-amqp-1-0-client-websocket</artifactId>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.qpid</groupId>
+ <artifactId>qpid-amqp-1-0-client</artifactId>
+ <version>0.26-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.qpid</groupId>
+ <artifactId>qpid-amqp-1-0-common</artifactId>
+ <version>0.26-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-servlet_2.5_spec</artifactId>
+ <version>1.2</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ <version>7.6.10.v20130312</version>
+ <scope>compile</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.jetty.orbit</groupId>
+ <artifactId>javax.servlet</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-continuation</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-http</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-continuation</artifactId>
+ <version>7.6.10.v20130312</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-security</artifactId>
+ <version>7.6.10.v20130312</version>
+ <scope>compile</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-http</artifactId>
+ <version>7.6.10.v20130312</version>
+ <scope>compile</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-io</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-io</artifactId>
+ <version>7.6.10.v20130312</version>
+ <scope>compile</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-util</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-servlet</artifactId>
+ <version>7.6.10.v20130312</version>
+ <scope>compile</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-security</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-util</artifactId>
+ <version>7.6.10.v20130312</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-websocket</artifactId>
+ <version>7.6.10.v20130312</version>
+ <scope>compile</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-util</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-io</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-http</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+
+ <build>
+ </build>
+
+</project>
diff --git a/qpid/java/amqp-1-0-client-websocket/resources/LICENSE b/qpid/java/amqp-1-0-client-websocket/resources/LICENSE
new file mode 100644
index 0000000000..de4b130f35
--- /dev/null
+++ b/qpid/java/amqp-1-0-client-websocket/resources/LICENSE
@@ -0,0 +1,204 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed 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.
+
+
diff --git a/qpid/java/amqp-1-0-client-websocket/resources/NOTICE b/qpid/java/amqp-1-0-client-websocket/resources/NOTICE
new file mode 100644
index 0000000000..8d1c3f3122
--- /dev/null
+++ b/qpid/java/amqp-1-0-client-websocket/resources/NOTICE
@@ -0,0 +1,5 @@
+Apache Qpid
+Copyright 2006-2012 Apache Software Foundation
+This product includes software developed at
+Apache Software Foundation (http://www.apache.org/)
+
diff --git a/qpid/java/amqp-1-0-client-websocket/resources/README.txt b/qpid/java/amqp-1-0-client-websocket/resources/README.txt
new file mode 100644
index 0000000000..35d25050fe
--- /dev/null
+++ b/qpid/java/amqp-1-0-client-websocket/resources/README.txt
@@ -0,0 +1,7 @@
+
+Documentation
+--------------
+All of our user documentation can be accessed at:
+
+http://qpid.apache.org/documentation.html
+
diff --git a/qpid/java/amqp-1-0-client-websocket/src/main/java/org/apache/qpid/amqp_1_0/client/websocket/WebSocketProvider.java b/qpid/java/amqp-1-0-client-websocket/src/main/java/org/apache/qpid/amqp_1_0/client/websocket/WebSocketProvider.java
new file mode 100644
index 0000000000..1805b593f1
--- /dev/null
+++ b/qpid/java/amqp-1-0-client-websocket/src/main/java/org/apache/qpid/amqp_1_0/client/websocket/WebSocketProvider.java
@@ -0,0 +1,322 @@
+/*
+ *
+ * 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.amqp_1_0.client.websocket;
+
+import org.apache.qpid.amqp_1_0.client.ConnectionException;
+import org.apache.qpid.amqp_1_0.client.TransportProvider;
+import org.apache.qpid.amqp_1_0.codec.FrameWriter;
+import org.apache.qpid.amqp_1_0.framing.AMQFrame;
+import org.apache.qpid.amqp_1_0.framing.ConnectionHandler;
+import org.apache.qpid.amqp_1_0.framing.ExceptionHandler;
+import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint;
+import org.apache.qpid.amqp_1_0.type.FrameBody;
+import org.apache.qpid.amqp_1_0.type.SaslFrameBody;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.eclipse.jetty.websocket.WebSocket;
+import org.eclipse.jetty.websocket.WebSocketClient;
+import org.eclipse.jetty.websocket.WebSocketClientFactory;
+
+import javax.net.ssl.SSLContext;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.util.concurrent.TimeUnit;
+
+class WebSocketProvider implements TransportProvider
+{
+ public static final String AMQP_WEBSOCKET_SUBPROTOCOL = "AMQPWSB10";
+
+ private static final byte AMQP_HEADER_FRAME_TYPE = (byte) 222;
+ private static int _connections;
+ private static QueuedThreadPool _threadPool;
+ private final String _transport;
+ private static WebSocketClientFactory _factory;
+
+ public WebSocketProvider(final String transport)
+ {
+ _transport = transport;
+ }
+
+ private static synchronized WebSocketClientFactory getWebSocketClientFactory(SSLContext context) throws Exception
+ {
+ if(_threadPool == null)
+ {
+ _threadPool = new QueuedThreadPool();
+ }
+ if(context != null)
+ {
+ WebSocketClientFactory factory = new WebSocketClientFactory(_threadPool);
+ SslContextFactory sslContextFactory = factory.getSslContextFactory();
+
+
+ sslContextFactory.setSslContext(context);
+
+ factory.start();
+
+ return factory;
+ }
+ else
+ {
+ if(_factory == null)
+ {
+ _factory = new WebSocketClientFactory(_threadPool);
+ _factory.start();
+ }
+ _connections++;
+ return _factory;
+ }
+ }
+
+
+ private static synchronized void removeClient(final WebSocketClientFactory factory) throws Exception
+ {
+
+ if(factory == _factory)
+ {
+ if(--_connections == 0)
+ {
+ _factory.stop();
+ _factory = null;
+ }
+ }
+ else
+ {
+ factory.stop();
+ }
+ }
+
+ @Override
+ public void connect(final ConnectionEndpoint conn,
+ final String address,
+ final int port,
+ final SSLContext sslContext, final ExceptionHandler exceptionHandler) throws ConnectionException
+ {
+
+ try
+ {
+ final WebSocketClientFactory webSocketClientFactory = getWebSocketClientFactory(sslContext);
+ WebSocketClient client = webSocketClientFactory.newWebSocketClient();
+ // Configure the client
+ client.setProtocol(AMQP_WEBSOCKET_SUBPROTOCOL);
+
+
+ ConnectionHandler.FrameOutput<FrameBody> out = new ConnectionHandler.FrameOutput<FrameBody>(conn);
+
+ final ConnectionHandler.FrameSource src;
+
+ if(conn.requiresSASL())
+ {
+ ConnectionHandler.FrameOutput<SaslFrameBody> saslOut = new ConnectionHandler.FrameOutput<SaslFrameBody>(conn);
+
+ src = new ConnectionHandler.SequentialFrameSource(new HeaderFrameSource((byte)'A',
+ (byte)'M',
+ (byte)'Q',
+ (byte)'P',
+ (byte)3,
+ (byte)1,
+ (byte)0,
+ (byte)0),
+ saslOut,
+ new HeaderFrameSource((byte)'A',
+ (byte)'M',
+ (byte)'Q',
+ (byte)'P',
+ (byte)0,
+ (byte)1,
+ (byte)0,
+ (byte)0),
+ out);
+
+ conn.setSaslFrameOutput(saslOut);
+ }
+ else
+ {
+ src = new ConnectionHandler.SequentialFrameSource(new HeaderFrameSource((byte)'A',
+ (byte)'M',
+ (byte)'Q',
+ (byte)'P',
+ (byte)0,
+ (byte)1,
+ (byte)0,
+ (byte)0),
+ out);
+ }
+
+ final ConnectionHandler handler = new ConnectionHandler(conn);
+ conn.setFrameOutputHandler(out);
+ final URI uri = new URI(_transport +"://"+ address+":"+ port +"/");
+ WebSocket.Connection connection = client.open(uri, new WebSocket.OnBinaryMessage()
+ {
+ public void onOpen(Connection connection)
+ {
+
+ Thread outputThread = new Thread(new FrameOutputThread(connection, src, conn, exceptionHandler, webSocketClientFactory));
+ outputThread.setDaemon(true);
+ outputThread.start();
+ }
+
+ public void onClose(int closeCode, String message)
+ {
+ conn.inputClosed();
+ }
+
+ @Override
+ public void onMessage(final byte[] data, final int offset, final int length)
+ {
+ handler.parse(ByteBuffer.wrap(data,offset,length).slice());
+ }
+ }).get(5, TimeUnit.SECONDS);
+ }
+ catch (Exception e)
+ {
+ throw new ConnectionException(e);
+ }
+
+ }
+
+
+
+ public static class HeaderFrameSource implements ConnectionHandler.FrameSource
+ {
+
+ private final ByteBuffer _buffer;
+ private boolean _closed;
+
+ public HeaderFrameSource(byte... headerBytes)
+ {
+ _buffer = ByteBuffer.wrap(headerBytes);
+ }
+
+
+ @Override
+ public AMQFrame getNextFrame(final boolean wait)
+ {
+ if(_closed)
+ {
+ return null;
+ }
+ else
+ {
+ _closed = true;
+ return new HeaderFrame(_buffer);
+ }
+ }
+
+ public boolean closed()
+ {
+ return _closed;
+ }
+
+ }
+
+
+ private static class HeaderFrame extends AMQFrame
+ {
+
+ public HeaderFrame(final ByteBuffer buffer)
+ {
+ super(null,buffer);
+ }
+
+ @Override
+ public short getChannel()
+ {
+ return 0;
+ }
+
+ @Override
+ public byte getFrameType()
+ {
+ return AMQP_HEADER_FRAME_TYPE;
+ }
+ }
+
+ private class FrameOutputThread implements Runnable
+ {
+ private final WebSocket.Connection _connection;
+ private final ConnectionHandler.FrameSource _frameSource;
+ private final ExceptionHandler _exceptionHandler;
+ private final FrameWriter _frameWriter;
+ private final byte[] _buffer;
+ private final WebSocketClientFactory _factory;
+
+ public FrameOutputThread(final WebSocket.Connection connection,
+ final ConnectionHandler.FrameSource src,
+ final ConnectionEndpoint conn,
+ final ExceptionHandler exceptionHandler, final WebSocketClientFactory factory)
+ {
+ _connection = connection;
+ _frameSource = src;
+ _exceptionHandler = exceptionHandler;
+ _frameWriter = new FrameWriter(conn.getDescribedTypeRegistry());
+ _buffer = new byte[conn.getMaxFrameSize()];
+ _factory = factory;
+ }
+
+ @Override
+ public void run()
+ {
+
+ final FrameWriter frameWriter = _frameWriter;
+ final ByteBuffer buffer = ByteBuffer.wrap(_buffer);
+ try
+ {
+
+ while(_connection.isOpen() && !_frameSource.closed())
+ {
+ AMQFrame frame = _frameSource.getNextFrame(true);
+ if(frame instanceof HeaderFrame)
+ {
+ _connection.sendMessage(frame.getPayload().array(),
+ frame.getPayload().arrayOffset(),
+ frame.getPayload().remaining());
+ }
+ else if(frame != null)
+ {
+ frameWriter.setValue(frame);
+ buffer.clear();
+ int length = frameWriter.writeToBuffer(buffer);
+ _connection.sendMessage(_buffer,0,length);
+ }
+ }
+ if(_frameSource.closed() && _connection.isOpen())
+ {
+ _connection.close();
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ try
+ {
+ removeClient(_factory);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/java/amqp-1-0-client-websocket/src/main/java/org/apache/qpid/amqp_1_0/client/websocket/WebSocketTransportProviderFactory.java b/qpid/java/amqp-1-0-client-websocket/src/main/java/org/apache/qpid/amqp_1_0/client/websocket/WebSocketTransportProviderFactory.java
new file mode 100644
index 0000000000..0e0dfa14d6
--- /dev/null
+++ b/qpid/java/amqp-1-0-client-websocket/src/main/java/org/apache/qpid/amqp_1_0/client/websocket/WebSocketTransportProviderFactory.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.amqp_1_0.client.websocket;
+
+import org.apache.qpid.amqp_1_0.client.TransportProvider;
+import org.apache.qpid.amqp_1_0.client.TransportProviderFactory;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+public class WebSocketTransportProviderFactory implements TransportProviderFactory
+{
+ @Override
+ public Collection<String> getSupportedTransports()
+ {
+ return Arrays.asList("ws", "wss");
+ }
+
+ @Override
+ public TransportProvider getProvider(final String transport)
+ {
+ return new WebSocketProvider(transport);
+ }
+}
diff --git a/qpid/java/amqp-1-0-client-websocket/src/main/resources/META-INF/services/org.apache.qpid.amqp_1_0.client.TransportProviderFactory b/qpid/java/amqp-1-0-client-websocket/src/main/resources/META-INF/services/org.apache.qpid.amqp_1_0.client.TransportProviderFactory
new file mode 100644
index 0000000000..b5993fd7b0
--- /dev/null
+++ b/qpid/java/amqp-1-0-client-websocket/src/main/resources/META-INF/services/org.apache.qpid.amqp_1_0.client.TransportProviderFactory
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+org.apache.qpid.amqp_1_0.client.websocket.WebSocketTransportProviderFactory \ No newline at end of file
diff --git a/qpid/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Respond.java b/qpid/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Respond.java
index 1e4bcfc7d7..e29323eb80 100644
--- a/qpid/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Respond.java
+++ b/qpid/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Respond.java
@@ -27,6 +27,8 @@ import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Random;
+import java.util.concurrent.TimeoutException;
+
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.qpid.amqp_1_0.type.Section;
@@ -280,7 +282,8 @@ public class Respond extends Util
}
}
- private void respond(Message m) throws Sender.SenderCreationException, ConnectionClosedException, LinkDetachedException
+ private void respond(Message m)
+ throws Sender.SenderCreationException, ConnectionClosedException, LinkDetachedException, TimeoutException
{
List<Section> sections = m.getPayload();
String replyTo = null;
diff --git a/qpid/java/amqp-1-0-client/pom.xml b/qpid/java/amqp-1-0-client/pom.xml
index 13430c0c22..1d6a444d6d 100644
--- a/qpid/java/amqp-1-0-client/pom.xml
+++ b/qpid/java/amqp-1-0-client/pom.xml
@@ -35,6 +35,17 @@
</dependencies>
<build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/java</directory>
+ <includes>
+ <include>resources/</include>
+ </includes>
+ </resource>
+ </resources>
</build>
</project>
diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java
index 6074f9b868..6157ec53f6 100644
--- a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java
+++ b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java
@@ -20,33 +20,27 @@
*/
package org.apache.qpid.amqp_1_0.client;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-import java.nio.ByteBuffer;
+import java.security.NoSuchAlgorithmException;
import java.security.Principal;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import java.util.ServiceLoader;
+import java.util.concurrent.TimeoutException;
-import javax.net.ssl.SSLSocketFactory;
-
-import org.apache.qpid.amqp_1_0.framing.SocketExceptionHandler;
+import org.apache.qpid.amqp_1_0.framing.ExceptionHandler;
import org.apache.qpid.amqp_1_0.framing.ConnectionHandler;
-import org.apache.qpid.amqp_1_0.transport.AMQPTransport;
import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint;
import org.apache.qpid.amqp_1_0.transport.Container;
-import org.apache.qpid.amqp_1_0.transport.StateChangeListener;
-import org.apache.qpid.amqp_1_0.type.Binary;
+import org.apache.qpid.amqp_1_0.transport.Predicate;
import org.apache.qpid.amqp_1_0.type.FrameBody;
import org.apache.qpid.amqp_1_0.type.SaslFrameBody;
import org.apache.qpid.amqp_1_0.type.UnsignedInteger;
+import org.apache.qpid.amqp_1_0.type.transport.AmqpError;
import org.apache.qpid.amqp_1_0.type.transport.ConnectionError;
import org.apache.qpid.amqp_1_0.type.transport.Error;
-public class Connection implements SocketExceptionHandler
+import javax.net.ssl.SSLContext;
+
+public class Connection implements ExceptionHandler
{
- private static final Logger RAW_LOGGER = Logger.getLogger("RAW");
private static final int MAX_FRAME_SIZE = 65536;
private String _address;
@@ -145,6 +139,20 @@ public class Connection implements SocketExceptionHandler
}
+ public Connection(final String protocol,
+ final String address,
+ final int port,
+ final String username,
+ final String password,
+ final Container container,
+ final String remoteHost,
+ final SSLContext sslContext,
+ final int channelMax) throws ConnectionException
+ {
+ this(protocol, address, port, username, password, MAX_FRAME_SIZE,container,remoteHost,sslContext,
+ channelMax);
+ }
+
public Connection(final String address,
final int port,
final String username,
@@ -155,141 +163,119 @@ public class Connection implements SocketExceptionHandler
boolean ssl,
int channelMax) throws ConnectionException
{
+ this(ssl?"amqp":"amqps",address,port,username,password,maxFrameSize,container,remoteHostname,getSslContext(ssl),channelMax);
+ }
- _address = address;
-
+ private static SSLContext getSslContext(final boolean ssl) throws ConnectionException
+ {
try
{
- final Socket s;
- if(ssl)
- {
- s = SSLSocketFactory.getDefault().createSocket(address, port);
- }
- else
- {
- s = new Socket(address, port);
- }
-
-
- Principal principal = username == null ? null : new Principal()
- {
-
- public String getName()
- {
- return username;
- }
- };
- _conn = new ConnectionEndpoint(container, principal, password);
- if(channelMax >= 0)
- {
- _conn.setChannelMax((short)channelMax);
- }
- _conn.setDesiredMaxFrameSize(UnsignedInteger.valueOf(maxFrameSize));
- _conn.setRemoteAddress(s.getRemoteSocketAddress());
- _conn.setRemoteHostname(remoteHostname);
-
-
+ return ssl ? SSLContext.getDefault() : null;
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new ConnectionException(e);
+ }
+ }
- ConnectionHandler.FrameOutput<FrameBody> out = new ConnectionHandler.FrameOutput<FrameBody>(_conn);
+ public Connection(final String protocol,
+ final String address,
+ final int port,
+ final String username,
+ final String password,
+ final int maxFrameSize,
+ final Container container,
+ final String remoteHostname,
+ SSLContext sslContext,
+ int channelMax) throws ConnectionException
+ {
+ _address = address;
- final OutputStream outputStream = s.getOutputStream();
- ConnectionHandler.BytesSource src;
+ Principal principal = username == null ? null : new Principal()
+ {
- if(_conn.requiresSASL())
- {
- ConnectionHandler.FrameOutput<SaslFrameBody> saslOut = new ConnectionHandler.FrameOutput<SaslFrameBody>(_conn);
-
- src = new ConnectionHandler.SequentialBytesSource(new ConnectionHandler.HeaderBytesSource(_conn, (byte)'A',
- (byte)'M',
- (byte)'Q',
- (byte)'P',
- (byte)3,
- (byte)1,
- (byte)0,
- (byte)0),
- new ConnectionHandler.FrameToBytesSourceAdapter(saslOut,_conn.getDescribedTypeRegistry()),
- new ConnectionHandler.HeaderBytesSource(_conn, (byte)'A',
- (byte)'M',
- (byte)'Q',
- (byte)'P',
- (byte)0,
- (byte)1,
- (byte)0,
- (byte)0),
- new ConnectionHandler.FrameToBytesSourceAdapter(out,_conn.getDescribedTypeRegistry())
- );
-
- _conn.setSaslFrameOutput(saslOut);
- }
- else
+ public String getName()
{
- src = new ConnectionHandler.SequentialBytesSource(new ConnectionHandler.HeaderBytesSource(_conn,(byte)'A',
- (byte)'M',
- (byte)'Q',
- (byte)'P',
- (byte)0,
- (byte)1,
- (byte)0,
- (byte)0),
- new ConnectionHandler.FrameToBytesSourceAdapter(out,_conn.getDescribedTypeRegistry())
- );
+ return username;
}
+ };
+ _conn = new ConnectionEndpoint(container, principal, password);
+ if(channelMax >= 0)
+ {
+ _conn.setChannelMax((short)channelMax);
+ }
+ _conn.setDesiredMaxFrameSize(UnsignedInteger.valueOf(maxFrameSize));
+ _conn.setRemoteHostname(remoteHostname);
+ ConnectionHandler.FrameOutput<FrameBody> out = new ConnectionHandler.FrameOutput<FrameBody>(_conn);
- ConnectionHandler.BytesOutputHandler outputHandler = new ConnectionHandler.BytesOutputHandler(outputStream, src, _conn, this);
- Thread outputThread = new Thread(outputHandler);
- outputThread.setDaemon(true);
- outputThread.start();
- _conn.setFrameOutputHandler(out);
+ ConnectionHandler.BytesSource src;
+ if(_conn.requiresSASL())
+ {
+ ConnectionHandler.FrameOutput<SaslFrameBody> saslOut = new ConnectionHandler.FrameOutput<SaslFrameBody>(_conn);
+
+ src = new ConnectionHandler.SequentialBytesSource(new ConnectionHandler.HeaderBytesSource(_conn, (byte)'A',
+ (byte)'M',
+ (byte)'Q',
+ (byte)'P',
+ (byte)3,
+ (byte)1,
+ (byte)0,
+ (byte)0),
+ new ConnectionHandler.FrameToBytesSourceAdapter(saslOut,_conn.getDescribedTypeRegistry()),
+ new ConnectionHandler.HeaderBytesSource(_conn, (byte)'A',
+ (byte)'M',
+ (byte)'Q',
+ (byte)'P',
+ (byte)0,
+ (byte)1,
+ (byte)0,
+ (byte)0),
+ new ConnectionHandler.FrameToBytesSourceAdapter(out,_conn.getDescribedTypeRegistry())
+ );
+
+ _conn.setSaslFrameOutput(saslOut);
+ }
+ else
+ {
+ src = new ConnectionHandler.SequentialBytesSource(new ConnectionHandler.HeaderBytesSource(_conn,(byte)'A',
+ (byte)'M',
+ (byte)'Q',
+ (byte)'P',
+ (byte)0,
+ (byte)1,
+ (byte)0,
+ (byte)0),
+ new ConnectionHandler.FrameToBytesSourceAdapter(out,_conn.getDescribedTypeRegistry())
+ );
+ }
+ TransportProvider transportProvider = getTransportProvider(protocol);
- final ConnectionHandler handler = new ConnectionHandler(_conn);
- final InputStream inputStream = s.getInputStream();
+ transportProvider.connect(_conn,address,port, sslContext, this);
- Thread inputThread = new Thread(new Runnable()
- {
- public void run()
- {
- try
- {
- doRead(handler, inputStream);
- }
- finally
- {
- if(_conn.closedForInput() && _conn.closedForOutput())
- {
- try
- {
- synchronized (outputStream)
- {
- s.close();
- }
- }
- catch (IOException e)
- {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
- }
- }
- });
+ _conn.open();
- inputThread.setDaemon(true);
- inputThread.start();
+ }
- _conn.open();
+ private TransportProvider getTransportProvider(final String protocol) throws ConnectionException
+ {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ ServiceLoader<TransportProviderFactory> providerFactories = ServiceLoader.load(TransportProviderFactory.class, classLoader);
- }
- catch (IOException e)
+ for(TransportProviderFactory tpf : providerFactories)
{
- throw new ConnectionException(e);
+ if(tpf.getSupportedTransports().contains(protocol))
+ {
+ return tpf.getProvider(protocol);
+ }
}
-
+ throw new ConnectionException("Unknown protocol: " + protocol);
}
private Connection(ConnectionEndpoint endpoint)
@@ -298,45 +284,6 @@ public class Connection implements SocketExceptionHandler
}
- private void doRead(final AMQPTransport transport, final InputStream inputStream)
- {
- byte[] buf = new byte[2<<15];
- ByteBuffer bbuf = ByteBuffer.wrap(buf);
- final Object lock = new Object();
- transport.setInputStateChangeListener(new StateChangeListener(){
-
- public void onStateChange(final boolean active)
- {
- synchronized(lock)
- {
- lock.notifyAll();
- }
- }
- });
-
- try
- {
- int read;
- while((read = inputStream.read(buf)) != -1)
- {
- bbuf.position(0);
- bbuf.limit(read);
-
- while(bbuf.hasRemaining() && transport.isOpenForInput())
- {
- transport.processBytes(bbuf);
- }
-
-
- }
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
-
- }
-
public Session createSession() throws ConnectionException
{
checkNotClosed();
@@ -357,84 +304,47 @@ public class Connection implements SocketExceptionHandler
return _conn;
}
- public void awaitOpen()
+ public void awaitOpen() throws TimeoutException, InterruptedException
{
- synchronized(getEndpoint().getLock())
+ getEndpoint().waitUntil(new Predicate()
{
- while(!getEndpoint().isOpen() && !getEndpoint().isClosed())
+ @Override
+ public boolean isSatisfied()
{
- try
- {
- getEndpoint().getLock().wait();
- }
- catch (InterruptedException e)
- {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
+ return getEndpoint().isOpen() || getEndpoint().isClosed();
}
- }
+ });
}
- private void doRead(final ConnectionHandler handler, final InputStream inputStream)
+ public void close() throws ConnectionErrorException
{
- byte[] buf = new byte[2<<15];
-
+ _conn.close();
try
{
- int read;
- boolean done = false;
- while(!handler.isDone() && (read = inputStream.read(buf)) != -1)
+ _conn.waitUntil(new Predicate()
{
- ByteBuffer bbuf = ByteBuffer.wrap(buf, 0, read);
- Binary b = new Binary(buf,0,read);
-
- if(RAW_LOGGER.isLoggable(Level.FINE))
- {
- RAW_LOGGER.fine("RECV [" + _conn.getRemoteAddress() + "] : " + b.toString());
- }
- while(bbuf.hasRemaining() && !handler.isDone())
+ @Override
+ public boolean isSatisfied()
{
- handler.parse(bbuf);
+ return _conn.closedForInput();
}
-
-
- }
- if(!handler.isDone())
- {
- _conn.inputClosed();
- if(_conn.getConnectionEventListener() != null)
- {
- _conn.getConnectionEventListener().closeReceived();
- }
- }
+ });
}
- catch (IOException e)
+ catch (InterruptedException e)
{
- _conn.inputClosed();
- e.printStackTrace();
+ throw new ConnectionErrorException(AmqpError.INTERNAL_ERROR, "Interrupted while waiting for connection closure");
}
- }
-
- public void close()
- {
- _conn.close();
-
- synchronized (_conn.getLock())
+ catch (TimeoutException e)
{
- while(!_conn.closedForInput())
- {
- try
- {
- _conn.getLock().wait();
- }
- catch (InterruptedException e)
- {
-
- }
- }
+ throw new ConnectionErrorException(AmqpError.INTERNAL_ERROR, "Timed out while waiting for connection closure");
}
+ if(_conn.getRemoteError() != null)
+ {
+ throw new ConnectionErrorException(_conn.getRemoteError());
+ }
+
}
/**
@@ -458,7 +368,7 @@ public class Connection implements SocketExceptionHandler
}
@Override
- public void processSocketException(Exception exception)
+ public void handleException(Exception exception)
{
Error socketError = new Error();
socketError.setDescription(exception.getClass() + ": " + exception.getMessage());
diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/ConnectionErrorException.java b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/ConnectionErrorException.java
index baf3de8991..302060776a 100644
--- a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/ConnectionErrorException.java
+++ b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/ConnectionErrorException.java
@@ -20,15 +20,21 @@
*/
package org.apache.qpid.amqp_1_0.client;
+import org.apache.qpid.amqp_1_0.type.ErrorCondition;
import org.apache.qpid.amqp_1_0.type.transport.Error;
public class ConnectionErrorException extends ConnectionException
{
protected final Error _remoteError;
+ public ConnectionErrorException(ErrorCondition condition,final String description)
+ {
+ this(new Error(condition, description));
+ }
+
public ConnectionErrorException(Error remoteError)
{
- super();
+ super(remoteError.getDescription());
_remoteError = remoteError;
}
diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java
index 5175d1d847..d76899a88b 100644
--- a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java
+++ b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java
@@ -23,6 +23,7 @@ package org.apache.qpid.amqp_1_0.client;
import org.apache.qpid.amqp_1_0.messaging.SectionDecoder;
import org.apache.qpid.amqp_1_0.transport.DeliveryStateHandler;
import org.apache.qpid.amqp_1_0.transport.LinkEndpoint;
+import org.apache.qpid.amqp_1_0.transport.Predicate;
import org.apache.qpid.amqp_1_0.transport.ReceivingLinkEndpoint;
import org.apache.qpid.amqp_1_0.transport.ReceivingLinkListener;
@@ -38,6 +39,7 @@ import org.apache.qpid.amqp_1_0.type.transport.Error;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.TimeoutException;
public class Receiver implements DeliveryStateHandler
{
@@ -137,36 +139,47 @@ public class Receiver implements DeliveryStateHandler
_endpoint.setLocalUnsettled(unsettled);
_endpoint.attach();
- synchronized(_endpoint.getLock())
+ try
{
- while(!_endpoint.isAttached() && !_endpoint.isDetached())
+ _endpoint.waitUntil(new Predicate()
{
- try
- {
- _endpoint.getLock().wait();
- }
- catch (InterruptedException e)
+
+ @Override
+ public boolean isSatisfied()
{
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ return _endpoint.isAttached() || _endpoint.isDetached();
}
- }
+ });
+ }
+ catch (TimeoutException e)
+ {
+ throw new ConnectionErrorException(AmqpError.INTERNAL_ERROR,"Timeout waiting for attach");
+ }
+ catch (InterruptedException e)
+ {
+ throw new ConnectionErrorException(AmqpError.INTERNAL_ERROR,"Interrupted while waiting for attach");
}
if(_endpoint.getSource() == null)
{
- synchronized(_endpoint.getLock())
+ try
{
- while(!_endpoint.isDetached())
+ _endpoint.waitUntil(new Predicate()
{
- try
- {
- _endpoint.getLock().wait();
- }
- catch (InterruptedException e)
+ @Override
+ public boolean isSatisfied()
{
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ return _endpoint.isDetached();
}
- }
+ });
+ }
+ catch (TimeoutException e)
+ {
+ throw new ConnectionErrorException(AmqpError.INTERNAL_ERROR,"Timeout waiting for detach following failed attach");
+ }
+ catch (InterruptedException e)
+ {
+ throw new ConnectionErrorException(AmqpError.INTERNAL_ERROR,"Interrupted whil waiting for detach following failed attach");
}
throw new ConnectionErrorException(getError());
}
diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SSLUtil.java b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SSLUtil.java
new file mode 100644
index 0000000000..70e5d08f15
--- /dev/null
+++ b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SSLUtil.java
@@ -0,0 +1,215 @@
+/*
+ *
+ * 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.amqp_1_0.client;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509ExtendedKeyManager;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+public class SSLUtil
+{
+ public static final String TRANSPORT_LAYER_SECURITY_CODE = "TLS";
+
+ public static SSLContext buildSslContext(final String certAlias,
+ final String keyStorePath,
+ final String keyStoreType,
+ final String keyStorePassword,
+ final String keyManagerFactoryAlgorithm,
+ final String trustStorePath,
+ final String trustStorePassword,
+ final String trustStoreType,
+ final String trustManagerFactoryAlgorithm) throws GeneralSecurityException, IOException
+ {
+
+ final SSLContext sslContext = SSLContext
+ .getInstance(TRANSPORT_LAYER_SECURITY_CODE);
+
+ final TrustManager[] trustManagers;
+ final KeyManager[] keyManagers;
+
+ if (trustStorePath != null)
+ {
+ final KeyStore ts = getInitializedKeyStore(trustStorePath, trustStorePassword, trustStoreType);
+ final TrustManagerFactory tmf = TrustManagerFactory.getInstance(trustManagerFactoryAlgorithm);
+
+ tmf.init(ts);
+
+ trustManagers = tmf.getTrustManagers();
+ }
+ else
+ {
+ trustManagers = null;
+ }
+
+ if (keyStorePath != null)
+ {
+ if (certAlias != null)
+ {
+ keyManagers = new KeyManager[] { new QpidClientX509KeyManager(
+ certAlias, keyStorePath, keyStoreType, keyStorePassword,
+ keyManagerFactoryAlgorithm) };
+ }
+ else
+ {
+ final KeyStore ks = SSLUtil.getInitializedKeyStore(keyStorePath, keyStorePassword, keyStoreType);
+
+ char[] keyStoreCharPassword = keyStorePassword == null ? null : keyStorePassword.toCharArray();
+ // Set up key manager factory to use our key store
+ final KeyManagerFactory kmf = KeyManagerFactory.getInstance(keyManagerFactoryAlgorithm);
+ kmf.init(ks, keyStoreCharPassword);
+ keyManagers = kmf.getKeyManagers();
+ }
+ }
+ else
+ {
+ keyManagers = null;
+ }
+
+
+ sslContext.init(keyManagers, trustManagers, null);
+
+ return sslContext;
+ }
+
+ public static X509Certificate[] getClientCertificates(final String alias,
+ final String keyStorePath,
+ final String keyStorePassword,
+ final String keyStoreType,
+ final String keyManagerFactoryAlgorithm)
+ throws GeneralSecurityException, IOException
+ {
+ return (new QpidClientX509KeyManager(alias,keyStorePath,keyStoreType,keyStorePassword,keyManagerFactoryAlgorithm)).getCertificateChain(alias);
+ }
+
+ public static KeyStore getInitializedKeyStore(String storePath, String storePassword, String keyStoreType) throws GeneralSecurityException, IOException
+ {
+ KeyStore ks = KeyStore.getInstance(keyStoreType);
+ InputStream in = null;
+ try
+ {
+ File f = new File(storePath);
+ if (f.exists())
+ {
+ in = new FileInputStream(f);
+ }
+ else
+ {
+ in = Thread.currentThread().getContextClassLoader().getResourceAsStream(storePath);
+ }
+ if (in == null && !"PKCS11".equalsIgnoreCase(keyStoreType)) // PKCS11 will not require an explicit path
+ {
+ throw new IOException("Unable to load keystore resource: " + storePath);
+ }
+
+ char[] storeCharPassword = storePassword == null ? null : storePassword.toCharArray();
+
+ ks.load(in, storeCharPassword);
+ }
+ finally
+ {
+ if (in != null)
+ {
+ //noinspection EmptyCatchBlock
+ try
+ {
+ in.close();
+ }
+ catch (IOException ignored)
+ {
+ }
+ }
+ }
+ return ks;
+ }
+
+ public static class QpidClientX509KeyManager extends X509ExtendedKeyManager
+ {
+
+ private X509ExtendedKeyManager delegate;
+ private String alias;
+
+ public QpidClientX509KeyManager(String alias, String keyStorePath, String keyStoreType,
+ String keyStorePassword, String keyManagerFactoryAlgorithmName) throws
+ GeneralSecurityException,
+ IOException
+ {
+ this.alias = alias;
+ KeyStore ks = getInitializedKeyStore(keyStorePath, keyStorePassword, keyStoreType);
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(keyManagerFactoryAlgorithmName);
+ kmf.init(ks, keyStorePassword.toCharArray());
+ this.delegate = (X509ExtendedKeyManager) kmf.getKeyManagers()[0];
+ }
+
+ public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket)
+ {
+ return alias;
+ }
+
+ public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket)
+ {
+ return delegate.chooseServerAlias(keyType, issuers, socket);
+ }
+
+ public X509Certificate[] getCertificateChain(String alias)
+ {
+ return delegate.getCertificateChain(alias);
+ }
+
+ public String[] getClientAliases(String keyType, Principal[] issuers)
+ {
+ return new String[]{alias};
+ }
+
+ public PrivateKey getPrivateKey(String alias)
+ {
+ return delegate.getPrivateKey(alias);
+ }
+
+ public String[] getServerAliases(String keyType, Principal[] issuers)
+ {
+ return delegate.getServerAliases(keyType, issuers);
+ }
+
+ public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine)
+ {
+ return alias;
+ }
+
+ public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine)
+ {
+ return delegate.chooseEngineServerAlias(keyType, issuers, engine);
+ }
+ }
+}
diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Sender.java b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Sender.java
index e891c5cbe7..1addad2235 100644
--- a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Sender.java
+++ b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Sender.java
@@ -24,6 +24,7 @@ import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructor;
import org.apache.qpid.amqp_1_0.messaging.SectionEncoder;
import org.apache.qpid.amqp_1_0.transport.DeliveryStateHandler;
import org.apache.qpid.amqp_1_0.transport.LinkEndpoint;
+import org.apache.qpid.amqp_1_0.transport.Predicate;
import org.apache.qpid.amqp_1_0.transport.SendingLinkEndpoint;
import org.apache.qpid.amqp_1_0.transport.SendingLinkListener;
import org.apache.qpid.amqp_1_0.type.*;
@@ -39,10 +40,15 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.TimeoutException;
+
import org.apache.qpid.amqp_1_0.type.transport.Error;
public class Sender implements DeliveryStateHandler
{
+ private static final long UNSETTLED_MESSAGE_TIMEOUT_MULTIPLIER = 1000l;
+ private static final long DEFAULT_CREDIT_TIMEOUT = 30000l;
+
private SendingLinkEndpoint _endpoint;
private int _id;
private Session _session;
@@ -150,17 +156,26 @@ public class Sender implements DeliveryStateHandler
synchronized(_endpoint.getLock())
{
- while(!(_endpoint.isAttached() || _endpoint.isDetached()))
+ try
{
- try
- {
- _endpoint.getLock().wait();
- }
- catch (InterruptedException e)
- {
- throw new SenderCreationException(e);
- }
+ _endpoint.waitUntil(new Predicate()
+ {
+ @Override
+ public boolean isSatisfied()
+ {
+ return _endpoint.isAttached() || _endpoint.isDetached();
+ }
+ });
+ }
+ catch (TimeoutException e)
+ {
+ throw new SenderCreationException(e);
}
+ catch (InterruptedException e)
+ {
+ throw new SenderCreationException(e);
+ }
+
if (session.getEndpoint().isEnded())
{
throw new SenderCreationException("Session is closed while creating link, target: " + target.getAddress());
@@ -225,22 +240,22 @@ public class Sender implements DeliveryStateHandler
return _endpoint.getTarget();
}
- public void send(Message message) throws LinkDetachedException
+ public void send(Message message) throws LinkDetachedException, TimeoutException
{
send(message, null, null);
}
- public void send(Message message, final OutcomeAction action) throws LinkDetachedException
+ public void send(Message message, final OutcomeAction action) throws LinkDetachedException, TimeoutException
{
send(message, null, action);
}
- public void send(Message message, final Transaction txn) throws LinkDetachedException
+ public void send(Message message, final Transaction txn) throws LinkDetachedException, TimeoutException
{
send(message, txn, null);
}
- public void send(Message message, final Transaction txn, OutcomeAction action) throws LinkDetachedException
+ public void send(Message message, final Transaction txn, OutcomeAction action) throws LinkDetachedException, TimeoutException
{
List<Section> sections = message.getPayload();
@@ -290,19 +305,26 @@ public class Sender implements DeliveryStateHandler
xfr.setSettled(message.getSettled() || _endpoint.getSendingSettlementMode() == SenderSettleMode.SETTLED);
}
final Object lock = _endpoint.getLock();
+
synchronized(lock)
{
- while(!_endpoint.hasCreditToSend() && !_endpoint.isDetached())
+
+ try
{
- try
- {
- lock.wait();
- }
- catch (InterruptedException e)
- {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
+ _endpoint.waitUntil(new Predicate()
+ {
+ @Override
+ public boolean isSatisfied()
+ {
+ return _endpoint.hasCreditToSend() || _endpoint.isDetached();
+ }
+ }, getCreditTimeout());
}
+ catch (InterruptedException e)
+ {
+ throw new TimeoutException("Interrupted while waiting for credit");
+ }
+
if(_endpoint.isDetached())
{
throw new LinkDetachedException(_error);
@@ -312,27 +334,24 @@ public class Sender implements DeliveryStateHandler
_outcomeActions.put(message.getDeliveryTag(), action);
}
_endpoint.transfer(xfr);
- //TODO - rationalise sending of flows
- // _endpoint.sendFlow();
}
if(_windowSize != 0)
{
- synchronized(lock)
+ try
{
-
-
- while(_endpoint.getUnsettledCount() >= _windowSize)
- {
- try
- {
- lock.wait();
- }
- catch (InterruptedException e)
- {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
+ _endpoint.waitUntil(new Predicate()
+ {
+ @Override
+ public boolean isSatisfied()
+ {
+ return _endpoint.getUnsettledCount() < _windowSize;
+ }
+ }, getUnsettledTimeout());
+ }
+ catch (InterruptedException e)
+ {
+ throw new TimeoutException("Interrupted while waiting for the window to expand to allow sending");
}
}
@@ -340,48 +359,80 @@ public class Sender implements DeliveryStateHandler
}
+ private long getCreditTimeout()
+ {
+ return _endpoint.getSyncTimeout() < DEFAULT_CREDIT_TIMEOUT ? DEFAULT_CREDIT_TIMEOUT : _endpoint.getSyncTimeout();
+ }
+
public void close() throws SenderClosingException
{
+ boolean unsettledDeliveries = false;
if(_windowSize != 0)
{
- synchronized(_endpoint.getLock())
- {
-
+ long timeout = getUnsettledTimeout();
- while(_endpoint.getUnsettledCount() > 0)
+ try
+ {
+ _endpoint.waitUntil(new Predicate()
{
- try
- {
- _endpoint.getLock().wait();
- }
- catch (InterruptedException e)
+ @Override
+ public boolean isSatisfied()
{
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ return _endpoint.getUnsettledCount() == 0;
}
- }
+ }, timeout);
+ }
+ catch (InterruptedException e)
+ {
+ unsettledDeliveries = true;
+ }
+ catch (TimeoutException e)
+ {
+ unsettledDeliveries = true;
}
}
_session.removeSender(this);
_endpoint.setSource(null);
- _endpoint.detach();
+ _endpoint.close();
_closed = true;
- synchronized(_endpoint.getLock())
+ try
{
- while(!_endpoint.isDetached())
+ _endpoint.waitUntil(new Predicate()
{
- try
- {
- _endpoint.getLock().wait();
- }
- catch (InterruptedException e)
+ @Override
+ public boolean isSatisfied()
{
- throw new SenderClosingException(e);
+ return _endpoint.isDetached();
}
- }
+ });
+ }
+ catch (TimeoutException e)
+ {
+ throw new SenderClosingException("Timed out attempting to detach link", e);
}
+ catch (InterruptedException e)
+ {
+ throw new SenderClosingException("Interrupted while attempting to detach link", e);
+ }
+ if(unsettledDeliveries && _endpoint.getUnsettledCount() > 0)
+ {
+ throw new SenderClosingException("Some messages may not have been received by the recipient");
+ }
+ }
+
+ private long getUnsettledTimeout()
+ {
+ long timeout = _endpoint.getSyncTimeout();
+
+ // give a generous timeout where there are unsettled messages
+ if(timeout < _endpoint.getUnsettledCount() * UNSETTLED_MESSAGE_TIMEOUT_MULTIPLIER)
+ {
+ timeout = _endpoint.getUnsettledCount() * UNSETTLED_MESSAGE_TIMEOUT_MULTIPLIER;
+ }
+ return timeout;
}
public boolean isClosed()
@@ -468,10 +519,20 @@ public class Sender implements DeliveryStateHandler
public class SenderClosingException extends Exception
{
+ public SenderClosingException(final String message, final Throwable cause)
+ {
+ super(message, cause);
+ }
+
public SenderClosingException(Throwable e)
{
super(e);
}
+
+ public SenderClosingException(final String message)
+ {
+ super(message);
+ }
}
public static interface OutcomeAction
diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TCPTransportProviderFactory.java b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TCPTransportProviderFactory.java
new file mode 100644
index 0000000000..2327a3860a
--- /dev/null
+++ b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TCPTransportProviderFactory.java
@@ -0,0 +1,39 @@
+/*
+ *
+ * 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.amqp_1_0.client;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+public class TCPTransportProviderFactory implements TransportProviderFactory
+{
+ @Override
+ public Collection<String> getSupportedTransports()
+ {
+ return Arrays.asList("amqp","amqps");
+ }
+
+ @Override
+ public TransportProvider getProvider(final String transport)
+ {
+ return new TCPTransportProvier(transport);
+ }
+}
diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TCPTransportProvier.java b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TCPTransportProvier.java
new file mode 100644
index 0000000000..6cc749d11d
--- /dev/null
+++ b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TCPTransportProvier.java
@@ -0,0 +1,203 @@
+/*
+ *
+ * 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.amqp_1_0.client;
+
+import org.apache.qpid.amqp_1_0.framing.ConnectionHandler;
+import org.apache.qpid.amqp_1_0.framing.ExceptionHandler;
+import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint;
+import org.apache.qpid.amqp_1_0.type.FrameBody;
+import org.apache.qpid.amqp_1_0.type.SaslFrameBody;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+
+class TCPTransportProvier implements TransportProvider
+{
+ private final String _transport;
+
+ public TCPTransportProvier(final String transport)
+ {
+ _transport = transport;
+ }
+
+ @Override
+ public void connect(final ConnectionEndpoint conn,
+ final String address,
+ final int port,
+ final SSLContext sslContext,
+ final ExceptionHandler exceptionHandler) throws ConnectionException
+ {
+ try
+ {
+ final Socket s;
+ if(sslContext != null)
+ {
+ final SSLSocketFactory socketFactory = sslContext.getSocketFactory();
+
+ SSLSocket sslSocket = (SSLSocket) socketFactory.createSocket(address, port);
+
+ s=sslSocket;
+ }
+ else
+ {
+ s = new Socket(address, port);
+ }
+
+ conn.setRemoteAddress(s.getRemoteSocketAddress());
+
+
+
+ ConnectionHandler.FrameOutput<FrameBody> out = new ConnectionHandler.FrameOutput<FrameBody>(conn);
+
+ ConnectionHandler.BytesSource src;
+
+ if(conn.requiresSASL())
+ {
+ ConnectionHandler.FrameOutput<SaslFrameBody> saslOut = new ConnectionHandler.FrameOutput<SaslFrameBody>(conn);
+
+ src = new ConnectionHandler.SequentialBytesSource(new ConnectionHandler.HeaderBytesSource(conn, (byte)'A',
+ (byte)'M',
+ (byte)'Q',
+ (byte)'P',
+ (byte)3,
+ (byte)1,
+ (byte)0,
+ (byte)0),
+ new ConnectionHandler.FrameToBytesSourceAdapter(saslOut,conn.getDescribedTypeRegistry()),
+ new ConnectionHandler.HeaderBytesSource(conn, (byte)'A',
+ (byte)'M',
+ (byte)'Q',
+ (byte)'P',
+ (byte)0,
+ (byte)1,
+ (byte)0,
+ (byte)0),
+ new ConnectionHandler.FrameToBytesSourceAdapter(out,conn.getDescribedTypeRegistry())
+ );
+
+ conn.setSaslFrameOutput(saslOut);
+ }
+ else
+ {
+ src = new ConnectionHandler.SequentialBytesSource(new ConnectionHandler.HeaderBytesSource(conn,(byte)'A',
+ (byte)'M',
+ (byte)'Q',
+ (byte)'P',
+ (byte)0,
+ (byte)1,
+ (byte)0,
+ (byte)0),
+ new ConnectionHandler.FrameToBytesSourceAdapter(out,conn.getDescribedTypeRegistry())
+ );
+ }
+
+
+ final OutputStream outputStream = s.getOutputStream();
+ ConnectionHandler.BytesOutputHandler outputHandler =
+ new ConnectionHandler.BytesOutputHandler(outputStream, src, conn, exceptionHandler);
+ Thread outputThread = new Thread(outputHandler);
+ outputThread.setDaemon(true);
+ outputThread.start();
+ conn.setFrameOutputHandler(out);
+
+
+ final ConnectionHandler handler = new ConnectionHandler(conn);
+ final InputStream inputStream = s.getInputStream();
+
+ Thread inputThread = new Thread(new Runnable()
+ {
+
+ public void run()
+ {
+ try
+ {
+ doRead(conn, handler, inputStream);
+ }
+ finally
+ {
+ if(conn.closedForInput() && conn.closedForOutput())
+ {
+ try
+ {
+ synchronized (outputStream)
+ {
+ s.close();
+ }
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ }
+ }
+ }
+ });
+
+ inputThread.setDaemon(true);
+ inputThread.start();
+
+ }
+ catch (IOException e)
+ {
+ throw new ConnectionException(e);
+ }
+ }
+ private void doRead(final ConnectionEndpoint conn, final ConnectionHandler handler, final InputStream inputStream)
+ {
+ byte[] buf = new byte[2<<15];
+
+
+ try
+ {
+ int read;
+ boolean done = false;
+ while(!handler.isDone() && (read = inputStream.read(buf)) != -1)
+ {
+ ByteBuffer bbuf = ByteBuffer.wrap(buf, 0, read);
+ while(bbuf.hasRemaining() && !handler.isDone())
+ {
+ handler.parse(bbuf);
+ }
+
+
+ }
+ if(!handler.isDone())
+ {
+ conn.inputClosed();
+ if(conn.getConnectionEventListener() != null)
+ {
+ conn.getConnectionEventListener().closeReceived();
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ conn.inputClosed();
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransportProvider.java b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransportProvider.java
new file mode 100644
index 0000000000..2c11d6b6ef
--- /dev/null
+++ b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransportProvider.java
@@ -0,0 +1,37 @@
+/*
+ *
+ * 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.amqp_1_0.client;
+
+import org.apache.qpid.amqp_1_0.framing.ConnectionHandler;
+import org.apache.qpid.amqp_1_0.framing.ExceptionHandler;
+import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint;
+import org.apache.qpid.amqp_1_0.type.FrameBody;
+
+import javax.net.ssl.SSLContext;
+
+public interface TransportProvider
+{
+ void connect(ConnectionEndpoint conn,
+ String address,
+ int port,
+ SSLContext sslContext,
+ ExceptionHandler exceptionHandler) throws ConnectionException;
+}
diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransportProviderFactory.java b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransportProviderFactory.java
new file mode 100644
index 0000000000..82999c5ccc
--- /dev/null
+++ b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransportProviderFactory.java
@@ -0,0 +1,29 @@
+/*
+ *
+ * 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.amqp_1_0.client;
+
+import java.util.Collection;
+
+public interface TransportProviderFactory
+{
+ Collection<String> getSupportedTransports();
+ TransportProvider getProvider(String transport);
+}
diff --git a/qpid/java/amqp-1-0-client/src/main/resources/META-INF/services/org.apache.qpid.amqp_1_0.client.TransportProviderFactory b/qpid/java/amqp-1-0-client/src/main/resources/META-INF/services/org.apache.qpid.amqp_1_0.client.TransportProviderFactory
new file mode 100644
index 0000000000..ffde030b30
--- /dev/null
+++ b/qpid/java/amqp-1-0-client/src/main/resources/META-INF/services/org.apache.qpid.amqp_1_0.client.TransportProviderFactory
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+org.apache.qpid.amqp_1_0.client.TCPTransportProviderFactory \ No newline at end of file
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolTypeConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolTypeConstructor.java
index b846b16722..b96e1ab47b 100644
--- a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolTypeConstructor.java
+++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolTypeConstructor.java
@@ -66,20 +66,7 @@ public class SymbolTypeConstructor extends VariableWidthTypeConstructor
if(symbolVal == null)
{
ByteBuffer dup = in.duplicate();
- try
- {
- dup.limit(in.position()+size);
- }
- catch (IllegalArgumentException e)
- {
- System.err.println("in.position(): " + in.position());
- System.err.println("size: " + size);
- System.err.println("dup.position(): " + dup.position());
- System.err.println("dup.capacity(): " + dup.capacity());
- System.err.println("dup.limit(): " + dup.limit());
- throw e;
-
- }
+ dup.limit(in.position()+size);
CharBuffer charBuf = ASCII.decode(dup);
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ConnectionHandler.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ConnectionHandler.java
index 119dd6bf3a..54a4f22d48 100644
--- a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ConnectionHandler.java
+++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ConnectionHandler.java
@@ -65,6 +65,12 @@ public class ConnectionHandler
public boolean parse(ByteBuffer in)
{
+ if(RAW_LOGGER.isLoggable(Level.FINE))
+ {
+ Binary b = new Binary(in.array(),in.arrayOffset()+in.position(),in.remaining());
+ RAW_LOGGER.fine("RECV [" + _connection.getRemoteAddress() + "] : " + b.toString());
+ }
+
while(in.hasRemaining() && !isDone())
{
_delegate = _delegate.parse(in);
@@ -376,6 +382,47 @@ public class ConnectionHandler
}
+ public static class SequentialFrameSource implements FrameSource
+ {
+ private Queue<FrameSource> _sources = new LinkedList<FrameSource>();
+
+ public SequentialFrameSource(FrameSource... sources)
+ {
+ _sources.addAll(Arrays.asList(sources));
+ }
+
+ public synchronized void addSource(FrameSource source)
+ {
+ _sources.add(source);
+ }
+
+ @Override
+ public synchronized AMQFrame getNextFrame(final boolean wait)
+ {
+ FrameSource src = _sources.peek();
+ while (src != null && src.closed())
+ {
+ _sources.poll();
+ src = _sources.peek();
+ }
+
+ if(src != null)
+ {
+ return src.getNextFrame(wait);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public boolean closed()
+ {
+ return _sources.isEmpty();
+ }
+ }
+
+
public static class BytesOutputHandler implements Runnable, BytesProcessor
{
@@ -383,28 +430,28 @@ public class ConnectionHandler
private BytesSource _bytesSource;
private boolean _closed;
private ConnectionEndpoint _conn;
- private SocketExceptionHandler _exceptionHandler;
-
- public BytesOutputHandler(OutputStream outputStream, BytesSource source, ConnectionEndpoint conn, SocketExceptionHandler exceptionHandler)
- {
- _outputStream = outputStream;
- _bytesSource = source;
- _conn = conn;
- _exceptionHandler = exceptionHandler;
- }
+ private ExceptionHandler _exceptionHandler;
- public void run()
- {
+ public BytesOutputHandler(OutputStream outputStream, BytesSource source, ConnectionEndpoint conn, ExceptionHandler exceptionHandler)
+ {
+ _outputStream = outputStream;
+ _bytesSource = source;
+ _conn = conn;
+ _exceptionHandler = exceptionHandler;
+ }
- final BytesSource bytesSource = _bytesSource;
+ public void run()
+ {
- while(!(_closed || bytesSource.closed()))
- {
- _bytesSource.getBytes(this, true);
- }
+ final BytesSource bytesSource = _bytesSource;
+ while(!(_closed || bytesSource.closed()))
+ {
+ _bytesSource.getBytes(this, true);
}
+ }
+
public void processBytes(final ByteBuffer buf)
{
try
@@ -423,7 +470,7 @@ public class ConnectionHandler
catch (IOException e)
{
_closed = true;
- _exceptionHandler.processSocketException(e);
+ _exceptionHandler.handleException(e);
}
}
}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SocketExceptionHandler.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ExceptionHandler.java
index 540aee0f8d..3adf3c0b18 100644
--- a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SocketExceptionHandler.java
+++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ExceptionHandler.java
@@ -23,9 +23,9 @@ package org.apache.qpid.amqp_1_0.framing;
/**
* Callback interface for processing socket exceptions.
*/
-public interface SocketExceptionHandler
+public interface ExceptionHandler
{
- public void processSocketException(Exception exception);
+ public void handleException(Exception exception);
}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameHandler.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameHandler.java
index 83cb36246a..bc16ba14e0 100644
--- a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameHandler.java
+++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameHandler.java
@@ -127,9 +127,9 @@ public class FrameHandler implements ProtocolHandler
break;
}
- else if(size > _connection.getMaxFrameSize())
+ else if(size > _connection.getDesiredMaxFrameSize().intValue())
{
- frameParsingError = createFramingError("specified frame size %d larger than maximum frame header size %d", size, _connection.getMaxFrameSize());
+ frameParsingError = createFramingError("specified frame size %d larger than maximum frame header size %d", size, _connection.getDesiredMaxFrameSize().intValue());
state = State.ERROR;
break;
}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEndpoint.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEndpoint.java
index a3c4ad7b5a..9c93c1f0a5 100644
--- a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEndpoint.java
+++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEndpoint.java
@@ -40,10 +40,8 @@ import org.apache.qpid.amqp_1_0.type.transport.*;
import org.apache.qpid.amqp_1_0.type.transport.Error;
import org.apache.qpid.amqp_1_0.type.codec.AMQPDescribedTypeRegistry;
-import javax.security.sasl.Sasl;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
-import javax.security.sasl.SaslServerFactory;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
@@ -51,7 +49,7 @@ import java.nio.charset.Charset;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Enumeration;
+import java.util.concurrent.TimeoutException;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -71,6 +69,7 @@ public class ConnectionEndpoint implements DescribedTypeConstructorRegistry.Sour
private static final short DEFAULT_CHANNEL_MAX = Integer.getInteger("amqp.channel_max", 255).shortValue();
private static final int DEFAULT_MAX_FRAME = Integer.getInteger("amqp.max_frame_size", 1 << 15);
+ private static final long DEFAULT_SYNC_TIMEOUT = Long.getLong("amqp.connection_sync_timeout",5000l);
private ConnectionState _state = ConnectionState.UNOPENED;
@@ -104,7 +103,7 @@ public class ConnectionEndpoint implements DescribedTypeConstructorRegistry.Sour
private UnsignedInteger _handleMax = UnsignedInteger.MAX_VALUE;
private ConnectionEventListener _connectionEventListener = ConnectionEventListener.DEFAULT;
private String _password;
- private final boolean _requiresSASLClient;
+ private boolean _requiresSASLClient;
private final boolean _requiresSASLServer;
@@ -122,6 +121,7 @@ public class ConnectionEndpoint implements DescribedTypeConstructorRegistry.Sour
private Error _remoteError;
private Map _properties;
+ private long _syncTimeout = DEFAULT_SYNC_TIMEOUT;
public ConnectionEndpoint(Container container, SaslServerProvider cbs)
{
@@ -140,6 +140,14 @@ public class ConnectionEndpoint implements DescribedTypeConstructorRegistry.Sour
_requiresSASLServer = false;
}
+ public void setPrincipal(Principal user)
+ {
+ if(_user == null)
+ {
+ _user = user;
+ _requiresSASLClient = user != null;
+ }
+ }
public synchronized void open()
{
@@ -1054,4 +1062,42 @@ public class ConnectionEndpoint implements DescribedTypeConstructorRegistry.Sour
{
_channelMax = channelMax;
}
+
+ public long getSyncTimeout()
+ {
+ return _syncTimeout;
+ }
+
+ public void setSyncTimeout(final long syncTimeout)
+ {
+ _syncTimeout = syncTimeout;
+ }
+
+ public void waitUntil(Predicate predicate) throws InterruptedException, TimeoutException
+ {
+ waitUntil(predicate, _syncTimeout);
+ }
+
+ public void waitUntil(Predicate predicate, long timeout) throws InterruptedException, TimeoutException
+ {
+ long endTime = System.currentTimeMillis() + timeout;
+
+ synchronized(getLock())
+ {
+ while(!predicate.isSatisfied())
+ {
+ getLock().wait(timeout);
+
+ if(!predicate.isSatisfied())
+ {
+ timeout = endTime - System.currentTimeMillis();
+ if(timeout <= 0l)
+ {
+ throw new TimeoutException();
+ }
+ }
+ }
+ }
+
+ }
}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/LinkEndpoint.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/LinkEndpoint.java
index 32fffd545a..301dd0695a 100644
--- a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/LinkEndpoint.java
+++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/LinkEndpoint.java
@@ -28,6 +28,7 @@ import org.apache.qpid.amqp_1_0.type.transport.Error;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.TimeoutException;
public abstract class LinkEndpoint<T extends LinkEventListener>
{
@@ -324,6 +325,23 @@ public abstract class LinkEndpoint<T extends LinkEventListener>
return _session.getLock();
}
+
+ public long getSyncTimeout()
+ {
+ return _session.getSyncTimeout();
+ }
+
+ public void waitUntil(Predicate predicate) throws TimeoutException, InterruptedException
+ {
+ _session.waitUntil(predicate);
+ }
+
+ public void waitUntil(Predicate predicate, long timeout) throws TimeoutException, InterruptedException
+ {
+ _session.waitUntil(predicate, timeout);
+ }
+
+
public void attach()
{
synchronized(getLock())
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Predicate.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Predicate.java
new file mode 100644
index 0000000000..3acd576527
--- /dev/null
+++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Predicate.java
@@ -0,0 +1,26 @@
+/*
+ *
+ * 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.amqp_1_0.transport;
+
+public interface Predicate
+{
+ boolean isSatisfied();
+}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionEndpoint.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionEndpoint.java
index f7a3cd3800..c37c52c6ea 100644
--- a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionEndpoint.java
+++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionEndpoint.java
@@ -35,6 +35,7 @@ import org.apache.qpid.amqp_1_0.type.transport.Error;
import java.nio.ByteBuffer;
import java.util.*;
+import java.util.concurrent.TimeoutException;
public class SessionEndpoint
{
@@ -579,19 +580,7 @@ public class SessionEndpoint
if(payload != null && payloadSent < payload.remaining())
{
payload = payload.duplicate();
-try
-{
payload.position(payload.position()+payloadSent);
-}
-catch(IllegalArgumentException e)
-{
- System.err.println("UNEXPECTED");
- System.err.println("Payload Position: " + payload.position());
- System.err.println("Payload Sent: " + payloadSent);
- System.err.println("Payload Remaining: " + payload.remaining());
- throw e;
-
-}
Transfer secondTransfer = new Transfer();
@@ -618,6 +607,23 @@ catch(IllegalArgumentException e)
return _connection.getLock();
}
+
+ public long getSyncTimeout()
+ {
+ return _connection.getSyncTimeout();
+ }
+
+ public void waitUntil(Predicate predicate) throws TimeoutException, InterruptedException
+ {
+ _connection.waitUntil(predicate);
+ }
+
+ public void waitUntil(Predicate predicate, long timeout) throws TimeoutException, InterruptedException
+ {
+ _connection.waitUntil(predicate, timeout);
+ }
+
+
public ReceivingLinkEndpoint createReceivingLinkEndpoint(final String name,
String targetAddr,
String sourceAddr,
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Error.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Error.java
index 6e1af84cc9..11319f738b 100644
--- a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Error.java
+++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Error.java
@@ -31,8 +31,7 @@ import java.util.Map;
import org.apache.qpid.amqp_1_0.type.*;
public class Error
- {
-
+{
private ErrorCondition _condition;
@@ -40,6 +39,16 @@ public class Error
private Map _info;
+ public Error()
+ {
+ }
+
+ public Error(final ErrorCondition condition, final String description)
+ {
+ _condition = condition;
+ _description = description;
+ }
+
public ErrorCondition getCondition()
{
return _condition;
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java
index abe71fb78c..2816667fc6 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java
@@ -36,6 +36,7 @@ import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQStoreException;
import org.apache.qpid.server.message.EnqueableMessage;
@@ -84,6 +85,8 @@ public class BDBMessageStore implements MessageStore, DurableConfigurationStore
private static final String[] DATABASE_NAMES = new String[] { CONFIGURED_OBJECTS_DB_NAME, MESSAGE_META_DATA_DB_NAME,
MESSAGE_CONTENT_DB_NAME, DELIVERY_DB_NAME, BRIDGEDB_NAME, LINKDB_NAME, XID_DB_NAME, CONFIG_VERSION_DB_NAME };
+ private final AtomicBoolean _closed = new AtomicBoolean(false);
+
private EnvironmentFacade _environmentFacade;
private final AtomicLong _messageId = new AtomicLong(0);
@@ -282,16 +285,19 @@ public class BDBMessageStore implements MessageStore, DurableConfigurationStore
@Override
public void close() throws AMQStoreException
{
- _stateManager.attainState(State.CLOSING);
- try
- {
- closeEnvironment();
- }
- catch(DatabaseException e)
- {
- throw new AMQStoreException("Exception occured on message store close", e);
+ if (_closed.compareAndSet(false, true))
+ {
+ _stateManager.attainState(State.CLOSING);
+ try
+ {
+ closeEnvironment();
+ }
+ catch(DatabaseException e)
+ {
+ throw new AMQStoreException("Exception occured on message store close", e);
+ }
+ _stateManager.attainState(State.CLOSED);
}
- _stateManager.attainState(State.CLOSED);
}
private void closeEnvironment()
diff --git a/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/add.html b/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/add.html
index ec5356e2a0..2a88832bdb 100644
--- a/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/add.html
+++ b/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/add.html
@@ -1,3 +1,19 @@
+<!--
+ ~ 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.
+ -->
<table class="tableContainer-table tableContainer-table-horiz">
<tr>
<td class="tableContainer-labelCell" style="width: 300px;"><strong>Path to store location*: </strong></td>
diff --git a/qpid/java/bdbstore/src/main/java/resources/virtualhost/store/bdb/add.html b/qpid/java/bdbstore/src/main/java/resources/virtualhost/store/bdb/add.html
index 2ed5b35c10..ead232d0b1 100644
--- a/qpid/java/bdbstore/src/main/java/resources/virtualhost/store/bdb/add.html
+++ b/qpid/java/bdbstore/src/main/java/resources/virtualhost/store/bdb/add.html
@@ -1,3 +1,19 @@
+<!--
+ ~ 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.
+ -->
<table class="tableContainer-table tableContainer-table-horiz">
<tr>
<td class="tableContainer-labelCell" style="width: 300px;"><strong>Path to store location*: </strong></td>
diff --git a/qpid/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HAClusterManagementTest.java b/qpid/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HAClusterManagementTest.java
index ef1b1cc42b..c190498a36 100644
--- a/qpid/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HAClusterManagementTest.java
+++ b/qpid/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HAClusterManagementTest.java
@@ -215,12 +215,10 @@ public class HAClusterManagementTest extends QpidBrokerTestCase
catch(RuntimeException rte)
{
//check cause was BDBs EnvironmentFailureException
- boolean isExpectedException = rte.getMessage().contains(EnvironmentFailureException.class.getName());
- if (!isExpectedException)
- {
- rte.printStackTrace();
- }
- assertTrue("Unexpected exception message:" + rte.getMessage(), isExpectedException);
+ assertTrue("Message '"+rte.getMessage()+"' does not contain '"
+ + EnvironmentFailureException.class.getName()
+ + "'.",
+ rte.getMessage().contains(EnvironmentFailureException.class.getName()));
// PASS
}
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java
index 7de0ebe1de..f180e4532c 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java
@@ -29,8 +29,6 @@ import java.util.Set;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.configuration.BrokerProperties;
import org.apache.qpid.server.configuration.ConfigurationEntryStore;
import org.apache.qpid.server.configuration.BrokerConfigurationStoreCreator;
import org.apache.qpid.server.configuration.store.ManagementModeStoreHandler;
@@ -125,6 +123,7 @@ public class Broker
}
catch(Exception e)
{
+ LOGGER.fatal("Exception during startup", e);
try
{
_applicationRegistry.close();
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
index c30ebe17be..ac2fa5e60d 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
@@ -25,7 +25,6 @@ import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQInternalException;
import org.apache.qpid.AMQSecurityException;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.logging.actors.CurrentActor;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DefaultExchange.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DefaultExchange.java
index aed2ddb8cf..5aea60f1b5 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DefaultExchange.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DefaultExchange.java
@@ -31,7 +31,6 @@ import org.apache.qpid.AMQException;
import org.apache.qpid.AMQInternalException;
import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.exchange.ExchangeDefaults;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.logging.actors.CurrentActor;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java
index 612fa855a4..994f6730e0 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java
@@ -26,7 +26,6 @@ import org.apache.qpid.AMQException;
import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.AMQUnknownExchangeType;
import org.apache.qpid.exchange.ExchangeDefaults;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.model.UUIDGenerator;
import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.plugin.QpidServiceLoader;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
index 1e022c994e..4571ec09af 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
@@ -26,11 +26,7 @@ import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQInvalidArgumentException;
-import org.apache.qpid.common.AMQPFilterTypes;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.binding.Binding;
-import org.apache.qpid.server.filter.JMSSelectorFilter;
import org.apache.qpid.server.filter.MessageFilter;
import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.plugin.ExchangeType;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DirectExchangeType.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DirectExchangeType.java
index d61d10155e..99c913ad07 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DirectExchangeType.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DirectExchangeType.java
@@ -24,7 +24,6 @@ import java.util.UUID;
import org.apache.qpid.AMQException;
import org.apache.qpid.exchange.ExchangeDefaults;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.virtualhost.VirtualHost;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java
index f364691666..f4a3fd940d 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java
@@ -21,7 +21,6 @@
package org.apache.qpid.server.exchange;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.plugin.ExchangeType;
import java.util.Collection;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java
index 53ee7de661..7b4dbf925b 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java
@@ -21,7 +21,6 @@
package org.apache.qpid.server.exchange;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
import java.util.Collection;
import java.util.UUID;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java
index cd830d69a9..6665fe5a9d 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java
@@ -22,17 +22,12 @@ package org.apache.qpid.server.exchange;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQInvalidArgumentException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.filter.MessageFilter;
import org.apache.qpid.server.message.InboundMessage;
@@ -41,7 +36,6 @@ import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.BaseQueue;
import java.util.ArrayList;
-import java.util.concurrent.ConcurrentHashMap;
public class FanoutExchange extends AbstractExchange
{
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeType.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeType.java
index ac864df02c..9fc0d1f071 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeType.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeType.java
@@ -24,7 +24,6 @@ import java.util.UUID;
import org.apache.qpid.AMQException;
import org.apache.qpid.exchange.ExchangeDefaults;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.virtualhost.VirtualHost;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/FilterSupport.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/FilterSupport.java
index e78516cf69..9968ae6f5e 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/FilterSupport.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/FilterSupport.java
@@ -30,7 +30,6 @@ import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.filter.SelectorParsingException;
import org.apache.qpid.filter.selector.ParseException;
import org.apache.qpid.filter.selector.TokenMgrError;
-import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.filter.JMSSelectorFilter;
import org.apache.qpid.server.filter.MessageFilter;
import org.apache.qpid.server.message.InboundMessage;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersBinding.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersBinding.java
index eb4a84a5b9..474c0862ad 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersBinding.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersBinding.java
@@ -23,8 +23,6 @@ package org.apache.qpid.server.exchange;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQInvalidArgumentException;
-import org.apache.qpid.framing.AMQTypedValue;
-import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.filter.MessageFilter;
import org.apache.qpid.server.message.AMQMessageHeader;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
index 41dd7e010c..977ac7249e 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
@@ -22,10 +22,7 @@ package org.apache.qpid.server.exchange;
import org.apache.log4j.Logger;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.binding.Binding;
-import org.apache.qpid.server.message.AMQMessageHeader;
import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.queue.AMQQueue;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeType.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeType.java
index 42d04f5a97..097a7bd5bd 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeType.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeType.java
@@ -24,7 +24,6 @@ import java.util.UUID;
import org.apache.qpid.AMQException;
import org.apache.qpid.exchange.ExchangeDefaults;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.virtualhost.VirtualHost;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java
index 6b8b84f5dd..7085d72390 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java
@@ -29,8 +29,6 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQInvalidArgumentException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.exchange.topic.TopicExchangeResult;
import org.apache.qpid.server.exchange.topic.TopicMatcherResult;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/TopicExchangeType.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/TopicExchangeType.java
index 3bbae700be..c1f42017bf 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/TopicExchangeType.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/TopicExchangeType.java
@@ -24,7 +24,6 @@ import java.util.UUID;
import org.apache.qpid.AMQException;
import org.apache.qpid.exchange.ExchangeDefaults;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.virtualhost.VirtualHost;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/filter/FilterManagerFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/filter/FilterManagerFactory.java
index 07049a6c97..dda3973ed8 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/filter/FilterManagerFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/filter/FilterManagerFactory.java
@@ -28,7 +28,6 @@ import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.filter.SelectorParsingException;
import org.apache.qpid.filter.selector.ParseException;
import org.apache.qpid.filter.selector.TokenMgrError;
-import org.apache.qpid.framing.FieldTable;
import java.util.Map;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Connection.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Connection.java
index 3139850892..31d40c7c3e 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Connection.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Connection.java
@@ -79,6 +79,7 @@ public interface Connection extends ConfiguredObject
public static final String REMOTE_PROCESS_PID = "remoteProcessPid";
public static final String SESSION_COUNT_LIMIT = "sessionCountLimit";
public static final String TRANSPORT = "transport";
+ /** Name of port associated with the connection */
public static final String PORT = "port";
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Transport.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Transport.java
index ae6e5ac43a..7338e5046a 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Transport.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Transport.java
@@ -25,7 +25,10 @@ import java.util.EnumSet;
public enum Transport
{
TCP,
- SSL;
+ SSL,
+ WS,
+ WSS,
+ SCTP;
public static Transport valueOfObject(Object transportObject)
{
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java
index a4ce95e5aa..c255ce2f4a 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java
@@ -19,12 +19,8 @@
*/
package org.apache.qpid.server.model.adapter;
-import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-
-import java.net.InetSocketAddress;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
@@ -42,21 +38,21 @@ import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.messages.BrokerMessages;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.KeyStore;
-import org.apache.qpid.server.model.Port;
import org.apache.qpid.server.model.Protocol;
import org.apache.qpid.server.model.Transport;
import org.apache.qpid.server.model.TrustStore;
import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
+import org.apache.qpid.server.plugin.TransportProviderFactory;
import org.apache.qpid.server.protocol.AmqpProtocolVersion;
-import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory;
-import org.apache.qpid.transport.NetworkTransportConfiguration;
-import org.apache.qpid.transport.network.IncomingNetworkTransport;
+import org.apache.qpid.server.transport.AcceptingTransport;
+import org.apache.qpid.server.transport.TransportProvider;
import org.apache.qpid.transport.network.security.ssl.QpidMultipleTrustManager;
public class AmqpPortAdapter extends PortAdapter
{
private final Broker _broker;
- private IncomingNetworkTransport _transport;
+ private AcceptingTransport _transport;
public AmqpPortAdapter(UUID id, Broker broker, Map<String, Object> attributes, Map<String, Object> defaultAttributes, TaskExecutor taskExecutor)
{
@@ -70,42 +66,36 @@ public class AmqpPortAdapter extends PortAdapter
Collection<Transport> transports = getTransports();
Set<AmqpProtocolVersion> supported = convertFromModelProtocolsToAmqp(getProtocols());
- SSLContext sslContext = null;
- if (transports.contains(Transport.SSL))
+ TransportProvider transportProvider = null;
+ final HashSet<Transport> transportSet = new HashSet<Transport>(transports);
+ for(TransportProviderFactory tpf : (new QpidServiceLoader<TransportProviderFactory>()).instancesOf(TransportProviderFactory.class))
{
- sslContext = createSslContext();
+ if(tpf.getSupportedTransports().contains(transports))
+ {
+ transportProvider = tpf.getTransportProvider(transportSet);
+ }
}
- AmqpProtocolVersion defaultSupportedProtocolReply = getDefaultAmqpSupportedReply();
-
- String bindingAddress = (String) getAttribute(Port.BINDING_ADDRESS);
- if (WILDCARD_ADDRESS.equals(bindingAddress))
+ if(transportProvider == null)
{
- bindingAddress = null;
+ throw new IllegalConfigurationException("No transport providers found which can satisfy the requirement to support the transports: " + transports);
}
- Integer port = (Integer) getAttribute(Port.PORT);
- InetSocketAddress bindingSocketAddress = null;
- if ( bindingAddress == null )
- {
- bindingSocketAddress = new InetSocketAddress(port);
- }
- else
+
+ SSLContext sslContext = null;
+ if (transports.contains(Transport.SSL) || transports.contains(Transport.WSS))
{
- bindingSocketAddress = new InetSocketAddress(bindingAddress, port);
+ sslContext = createSslContext();
}
- final NetworkTransportConfiguration settings = new ServerNetworkTransportConfiguration(
- bindingSocketAddress, (Boolean)getAttribute(TCP_NO_DELAY),
- (Integer)getAttribute(SEND_BUFFER_SIZE), (Integer)getAttribute(RECEIVE_BUFFER_SIZE),
- (Boolean)getAttribute(NEED_CLIENT_AUTH), (Boolean)getAttribute(WANT_CLIENT_AUTH));
+ AmqpProtocolVersion defaultSupportedProtocolReply = getDefaultAmqpSupportedReply();
- _transport = org.apache.qpid.transport.network.Transport.getIncomingTransportInstance();
- final MultiVersionProtocolEngineFactory protocolEngineFactory = new MultiVersionProtocolEngineFactory(
- _broker, transports.contains(Transport.TCP) ? sslContext : null,
- settings.wantClientAuth(), settings.needClientAuth(),
- supported, defaultSupportedProtocolReply, this, transports.contains(Transport.TCP) ? Transport.TCP : Transport.SSL);
+ _transport = transportProvider.createTransport(transportSet,
+ sslContext,
+ this,
+ supported,
+ defaultSupportedProtocolReply);
- _transport.accept(settings, protocolEngineFactory, transports.contains(Transport.TCP) ? null : sslContext);
+ _transport.start();
for(Transport transport : getTransports())
{
CurrentActor.get().message(BrokerMessages.LISTENING(String.valueOf(transport), getPort()));
@@ -210,68 +200,4 @@ public class AmqpPortAdapter extends PortAdapter
}
return null;
}
-
- class ServerNetworkTransportConfiguration implements NetworkTransportConfiguration
- {
- private final InetSocketAddress _bindingSocketAddress;
- private final Boolean _tcpNoDelay;
- private final Integer _sendBufferSize;
- private final Integer _receiveBufferSize;
- private final boolean _needClientAuth;
- private final boolean _wantClientAuth;
-
- public ServerNetworkTransportConfiguration(
- InetSocketAddress bindingSocketAddress, boolean tcpNoDelay,
- int sendBufferSize, int receiveBufferSize,
- boolean needClientAuth, boolean wantClientAuth)
- {
- _bindingSocketAddress = bindingSocketAddress;
- _tcpNoDelay = tcpNoDelay;
- _sendBufferSize = sendBufferSize;
- _receiveBufferSize = receiveBufferSize;
- _needClientAuth = needClientAuth;
- _wantClientAuth = wantClientAuth;
- }
-
- @Override
- public boolean wantClientAuth()
- {
- return _wantClientAuth;
- }
-
- @Override
- public boolean needClientAuth()
- {
- return _needClientAuth;
- }
-
- @Override
- public Boolean getTcpNoDelay()
- {
- return _tcpNoDelay;
- }
-
- @Override
- public Integer getSendBufferSize()
- {
- return _sendBufferSize;
- }
-
- @Override
- public Integer getReceiveBufferSize()
- {
- return _receiveBufferSize;
- }
-
- @Override
- public InetSocketAddress getAddress()
- {
- return _bindingSocketAddress;
- }
- };
-
- public String toString()
- {
- return getName();
- }
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java
index e8bacb2712..dd5fc67b48 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java
@@ -35,6 +35,7 @@ import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.Connection;
import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.Port;
import org.apache.qpid.server.model.Session;
import org.apache.qpid.server.model.State;
import org.apache.qpid.server.model.Statistics;
@@ -226,7 +227,8 @@ final class ConnectionAdapter extends AbstractAdapter implements Connection
}
else if(name.equals(PORT))
{
- return String.valueOf(_connection.getPort());
+ Port port = _connection.getPort();
+ return String.valueOf(port == null ? null : port.getName());
}
return super.getAttribute(name);
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java
index 0547f961d0..3e7d03b5ac 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java
@@ -556,4 +556,11 @@ public class PortAdapter extends AbstractAdapter implements Port
return trustStores;
}
+
+ @Override
+ public String toString()
+ {
+ return getClass().getSimpleName() + " [id=" + getId() + ", name=" + getName() + ", port=" + getPort() + "]";
+ }
+
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java
index 8dc446e5b2..25a8cc93ad 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java
@@ -111,7 +111,7 @@ public class PortFactory
throw new IllegalConfigurationException("Can't create port which requests SSL client certificates but has no trust stores configured.");
}
- if(useClientAuth && !port.getTransports().contains(Transport.SSL))
+ if(useClientAuth && !(port.getTransports().contains(Transport.SSL) || port.getTransports().contains(Transport.WSS)))
{
throw new IllegalConfigurationException("Can't create port which requests SSL client certificates but doesn't use SSL transport.");
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/ExchangeType.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/ExchangeType.java
index ab19fa196e..423b76ab8e 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/ExchangeType.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/ExchangeType.java
@@ -23,7 +23,6 @@ package org.apache.qpid.server.plugin;
import java.util.UUID;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.virtualhost.VirtualHost;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/TransportProviderFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/TransportProviderFactory.java
new file mode 100644
index 0000000000..81a6adc40e
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/TransportProviderFactory.java
@@ -0,0 +1,35 @@
+/*
+ *
+ * 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.server.plugin;
+
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.transport.TransportProvider;
+
+import java.util.Set;
+
+public interface TransportProviderFactory extends Pluggable
+{
+ Set<Set<Transport>> getSupportedTransports();
+
+ TransportProvider getTransportProvider(Set<Transport> transports);
+
+
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java
index 47b578c4ef..01b220fd79 100755
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java
@@ -30,6 +30,8 @@ import java.util.Set;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSocket;
+
import org.apache.log4j.Logger;
import org.apache.qpid.protocol.ServerProtocolEngine;
import org.apache.qpid.server.logging.actors.CurrentActor;
@@ -38,6 +40,7 @@ import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.Port;
import org.apache.qpid.server.model.Transport;
import org.apache.qpid.server.plugin.ProtocolEngineCreator;
+import org.apache.qpid.transport.Binary;
import org.apache.qpid.transport.Sender;
import org.apache.qpid.transport.network.NetworkConnection;
import org.apache.qpid.transport.network.security.SSLStatus;
@@ -143,11 +146,6 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
private static final int MINIMUM_REQUIRED_HEADER_BYTES = 8;
- public void setNetworkConnection(NetworkConnection networkConnection)
- {
- setNetworkConnection(networkConnection, networkConnection.getSender());
- }
-
public void setNetworkConnection(NetworkConnection network, Sender<ByteBuffer> sender)
{
_network = network;
@@ -274,9 +272,9 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
public void received(ByteBuffer msg)
{
-
_lastReadTime = System.currentTimeMillis();
- ByteBuffer msgheader = msg.duplicate();
+ ByteBuffer msgheader = msg.duplicate().slice();
+
if(_header.remaining() > msgheader.limit())
{
msg.position(msg.limit());
@@ -329,6 +327,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
}
}
+
if(newDelegate == null && looksLikeSSL(headerBytes))
{
if(_sslContext != null)
@@ -475,7 +474,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
SSLStatus sslStatus = new SSLStatus();
_sslReceiver = new SSLReceiver(_engine,_decryptEngine,sslStatus);
_sslSender = new SSLBufferingSender(_engine,_sender,sslStatus);
- _decryptEngine.setNetworkConnection(new SSLNetworkConnection(_engine,_network, _sslSender));
+ _decryptEngine.setNetworkConnection(new SSLNetworkConnection(_engine,_network, _sslSender), _sslSender);
}
@Override
@@ -592,6 +591,9 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
private final NetworkConnection _network;
private final SSLBufferingSender _sslSender;
private final SSLEngine _engine;
+ private Principal _principal;
+ private boolean _principalChecked;
+ private final Object _lock = new Object();
public SSLNetworkConnection(SSLEngine engine, NetworkConnection network,
SSLBufferingSender sslSender)
@@ -647,21 +649,25 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
}
@Override
- public void setPeerPrincipal(Principal principal)
- {
- _network.setPeerPrincipal(principal);
- }
-
- @Override
public Principal getPeerPrincipal()
{
- try
- {
- return _engine.getSession().getPeerPrincipal();
- }
- catch (SSLPeerUnverifiedException e)
+ synchronized (_lock)
{
- return null;
+ if(!_principalChecked)
+ {
+ try
+ {
+ _principal = _engine.getSession().getPeerPrincipal();
+ }
+ catch (SSLPeerUnverifiedException e)
+ {
+ _principal = null;
+ }
+
+ _principalChecked = true;
+ }
+
+ return _principal;
}
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AMQQueue.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
index ceebe4f965..c00881ca94 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
@@ -21,7 +21,6 @@
package org.apache.qpid.server.queue;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.configuration.QueueConfiguration;
import org.apache.qpid.server.exchange.Exchange;
@@ -35,7 +34,6 @@ import org.apache.qpid.server.virtualhost.VirtualHost;
import java.util.Collection;
import java.util.List;
-import java.util.Map;
import java.util.Set;
public interface AMQQueue extends Comparable<AMQQueue>, ExchangeReferrer, TransactionLogResource, BaseQueue
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/BaseQueue.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/BaseQueue.java
index 6145570b0c..7aba1a2342 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/BaseQueue.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/BaseQueue.java
@@ -22,7 +22,6 @@
package org.apache.qpid.server.queue;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.store.TransactionLogResource;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java
index 2a78ee430c..df26037eed 100755
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java
@@ -21,7 +21,6 @@
package org.apache.qpid.server.queue;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.message.AMQMessageHeader;
import org.apache.qpid.server.message.InboundMessage;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
index fb36433799..b002419064 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
@@ -38,7 +38,6 @@ import java.util.concurrent.atomic.AtomicLong;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQSecurityException;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.pool.ReferenceCountingExecutorService;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.configuration.BrokerProperties;
@@ -734,7 +733,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
&& mightAssign(sub, entry)
&& !sub.wouldSuspend(entry))
{
- if (sub.acquires() && !(assign(sub, entry) && entry.acquire(sub)))
+ if (sub.acquires() && !assign(sub, entry))
{
// restore credit here that would have been taken away by wouldSuspend since we didn't manage
// to acquire the entry for this subscription
@@ -755,10 +754,18 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
private boolean assign(final Subscription sub, final QueueEntry entry)
{
- return _messageGroupManager == null || _messageGroupManager.acceptMessage(sub, entry);
+ if(_messageGroupManager == null)
+ {
+ //no grouping, try to acquire immediately.
+ return entry.acquire(sub);
+ }
+ else
+ {
+ //the group manager is responsible for acquiring the message if/when appropriate
+ return _messageGroupManager.acceptMessage(sub, entry);
+ }
}
-
private boolean mightAssign(final Subscription sub, final QueueEntry entry)
{
if(_messageGroupManager == null || !sub.acquires())
@@ -1646,7 +1653,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
{
if (!sub.wouldSuspend(node))
{
- if (sub.acquires() && !(assign(sub, node) && node.acquire(sub)))
+ if (sub.acquires() && !assign(sub, node))
{
// restore credit here that would have been taken away by wouldSuspend since we didn't manage
// to acquire the entry for this subscription
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/SubjectCreator.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/SubjectCreator.java
index 244ab0dd94..066c05b898 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/SubjectCreator.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/SubjectCreator.java
@@ -37,6 +37,7 @@ import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationS
import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManager;
/**
* Creates a {@link Subject} formed by the {@link Principal}'s returned from:
@@ -129,6 +130,17 @@ public class SubjectCreator
}
}
+ public Subject createSubjectWithGroups(Principal principal)
+ {
+ Subject authenticationSubject = new Subject();
+
+ authenticationSubject.getPrincipals().add(principal);
+ authenticationSubject.getPrincipals().addAll(getGroupPrincipals(principal.getName()));
+ authenticationSubject.setReadOnly();
+
+ return authenticationSubject;
+ }
+
public Subject createSubjectWithGroups(String username)
{
Subject authenticationSubject = new Subject();
@@ -159,4 +171,9 @@ public class SubjectCreator
{
return _authenticationManager instanceof AnonymousAuthenticationManager;
}
+
+ public boolean isExternalAuthenticationAllowed()
+ {
+ return _authenticationManager instanceof ExternalAuthenticationManager;
+ }
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCMessageStore.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCMessageStore.java
index 4a32d0a27e..96f6983402 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCMessageStore.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCMessageStore.java
@@ -79,7 +79,7 @@ abstract public class AbstractJDBCMessageStore implements MessageStore, DurableC
private static final int DB_VERSION = 7;
private final AtomicLong _messageId = new AtomicLong(0);
- private AtomicBoolean _closed = new AtomicBoolean(false);
+ private final AtomicBoolean _closed = new AtomicBoolean(false);
private static final String CREATE_DB_VERSION_TABLE = "CREATE TABLE "+ DB_VERSION_TABLE_NAME + " ( version int not null )";
private static final String INSERT_INTO_DB_VERSION = "INSERT INTO "+ DB_VERSION_TABLE_NAME + " ( version ) VALUES ( ? )";
@@ -683,12 +683,14 @@ abstract public class AbstractJDBCMessageStore implements MessageStore, DurableC
@Override
public void close() throws AMQStoreException
{
- _closed.getAndSet(true);
- _stateManager.attainState(State.CLOSING);
+ if (_closed.compareAndSet(false, true))
+ {
+ _stateManager.attainState(State.CLOSING);
- doClose();
+ doClose();
- _stateManager.attainState(State.CLOSED);
+ _stateManager.attainState(State.CLOSED);
+ }
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java
index a3534d3fa5..c6ebe90802 100755
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java
@@ -20,9 +20,6 @@
*/
package org.apache.qpid.server.store;
-import org.apache.qpid.framing.FieldTable;
-
-import java.nio.ByteBuffer;
import java.util.Map;
import java.util.UUID;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationStoreHelper.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationStoreHelper.java
index d311685375..a688b493e1 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationStoreHelper.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationStoreHelper.java
@@ -29,14 +29,11 @@ import java.util.Map;
import java.util.Set;
import org.apache.qpid.AMQStoreException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.model.Binding;
import org.apache.qpid.server.model.Exchange;
import org.apache.qpid.server.model.LifetimePolicy;
import org.apache.qpid.server.model.Queue;
import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.queue.QueueArgumentsConverter;
public class DurableConfigurationStoreHelper
{
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java
index efedad1181..ae7e11afa4 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java
@@ -63,6 +63,18 @@ public class AssignedSubscriptionMessageGroupManager implements MessageGroupMana
public boolean acceptMessage(Subscription sub, QueueEntry entry)
{
+ if(assignMessage(sub, entry))
+ {
+ return entry.acquire(sub);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ private boolean assignMessage(Subscription sub, QueueEntry entry)
+ {
Object groupVal = entry.getMessage().getMessageHeader().getHeader(_groupId);
if(groupVal == null)
{
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java
index f38e23b342..55110c46de 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java
@@ -136,9 +136,21 @@ public class DefinedGroupMessageGroupManager implements MessageGroupManager
public synchronized boolean acceptMessage(final Subscription sub, final QueueEntry entry)
{
+ if(assignMessage(sub, entry))
+ {
+ return entry.acquire(sub);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ private boolean assignMessage(final Subscription sub, final QueueEntry entry)
+ {
Object groupId = getKey(entry);
Group group = _groupMap.get(groupId);
-
+
if(group == null || !group.isValid())
{
group = new Group(groupId, sub);
@@ -152,11 +164,10 @@ public class DefinedGroupMessageGroupManager implements MessageGroupManager
{
return false;
}
-
}
-
+
Subscription assignedSub = group.getSubscription();
-
+
if(assignedSub == sub)
{
entry.addStateChangeListener(new GroupStateChangeListener(group, entry));
@@ -167,8 +178,7 @@ public class DefinedGroupMessageGroupManager implements MessageGroupManager
return false;
}
}
-
-
+
public synchronized QueueEntry findEarliestAssignedAvailableEntry(final Subscription sub)
{
EntryFinder visitor = new EntryFinder(sub);
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/subscription/Subscription.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/subscription/Subscription.java
index 36d49d8279..fde3d3809c 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/subscription/Subscription.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/subscription/Subscription.java
@@ -22,7 +22,6 @@ package org.apache.qpid.server.subscription;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.queue.AMQQueue;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/AcceptingTransport.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/AcceptingTransport.java
new file mode 100644
index 0000000000..bf7f2835e0
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/AcceptingTransport.java
@@ -0,0 +1,27 @@
+/*
+ *
+ * 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.server.transport;
+
+public interface AcceptingTransport
+{
+ public void start();
+ public void close();
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransport.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransport.java
new file mode 100644
index 0000000000..a26f892483
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransport.java
@@ -0,0 +1,146 @@
+/*
+ *
+ * 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.server.transport;
+
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.protocol.AmqpProtocolVersion;
+import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory;
+import org.apache.qpid.transport.NetworkTransportConfiguration;
+import org.apache.qpid.transport.network.IncomingNetworkTransport;
+
+import javax.net.ssl.SSLContext;
+import java.net.InetSocketAddress;
+import java.util.Set;
+
+import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
+
+class TCPandSSLTransport implements AcceptingTransport
+{
+ private IncomingNetworkTransport _networkTransport;
+ private Set<Transport> _transports;
+ private SSLContext _sslContext;
+ private InetSocketAddress _bindingSocketAddress;
+ private Port _port;
+ private Set<AmqpProtocolVersion> _supported;
+ private AmqpProtocolVersion _defaultSupportedProtocolReply;
+
+ TCPandSSLTransport(final Set<Transport> transports,
+ final SSLContext sslContext,
+ final Port port,
+ final Set<AmqpProtocolVersion> supported,
+ final AmqpProtocolVersion defaultSupportedProtocolReply)
+ {
+ _transports = transports;
+ _sslContext = sslContext;
+ _port = port;
+ _supported = supported;
+ _defaultSupportedProtocolReply = defaultSupportedProtocolReply;
+ }
+
+ @Override
+ public void start()
+ {
+ String bindingAddress = (String) _port.getAttribute(Port.BINDING_ADDRESS);
+ if (WILDCARD_ADDRESS.equals(bindingAddress))
+ {
+ bindingAddress = null;
+ }
+ Integer port = (Integer) _port.getAttribute(Port.PORT);
+ if ( bindingAddress == null )
+ {
+ _bindingSocketAddress = new InetSocketAddress(port);
+ }
+ else
+ {
+ _bindingSocketAddress = new InetSocketAddress(bindingAddress, port);
+ }
+
+ final NetworkTransportConfiguration settings = new ServerNetworkTransportConfiguration();
+ _networkTransport = org.apache.qpid.transport.network.Transport.getIncomingTransportInstance();
+ final MultiVersionProtocolEngineFactory protocolEngineFactory =
+ new MultiVersionProtocolEngineFactory(
+ _port.getParent(Broker.class), _transports.contains(Transport.TCP) ? _sslContext : null,
+ settings.wantClientAuth(), settings.needClientAuth(),
+ _supported,
+ _defaultSupportedProtocolReply,
+ _port,
+ _transports.contains(Transport.TCP) ? Transport.TCP : Transport.SSL);
+
+ _networkTransport.accept(settings, protocolEngineFactory, _transports.contains(Transport.TCP) ? null : _sslContext);
+ }
+
+ @Override
+ public void close()
+ {
+ _networkTransport.close();
+ }
+
+ class ServerNetworkTransportConfiguration implements NetworkTransportConfiguration
+ {
+ public ServerNetworkTransportConfiguration()
+ {
+ }
+
+ @Override
+ public boolean wantClientAuth()
+ {
+ return (Boolean)_port.getAttribute(Port.WANT_CLIENT_AUTH);
+ }
+
+ @Override
+ public boolean needClientAuth()
+ {
+ return (Boolean)_port.getAttribute(Port.NEED_CLIENT_AUTH);
+ }
+
+ @Override
+ public Boolean getTcpNoDelay()
+ {
+ return (Boolean)_port.getAttribute(Port.TCP_NO_DELAY);
+ }
+
+ @Override
+ public Integer getSendBufferSize()
+ {
+ return (Integer)_port.getAttribute(Port.SEND_BUFFER_SIZE);
+ }
+
+ @Override
+ public Integer getReceiveBufferSize()
+ {
+ return (Integer)_port.getAttribute(Port.RECEIVE_BUFFER_SIZE);
+ }
+
+ @Override
+ public InetSocketAddress getAddress()
+ {
+ return _bindingSocketAddress;
+ }
+
+ @Override
+ public String toString()
+ {
+ return _port.toString();
+ }
+ }
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransportProvider.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransportProvider.java
new file mode 100644
index 0000000000..33c7774a29
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransportProvider.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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.server.transport;
+
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.protocol.AmqpProtocolVersion;
+
+import javax.net.ssl.SSLContext;
+import java.util.Set;
+
+class TCPandSSLTransportProvider implements TransportProvider
+{
+ @Override
+ public AcceptingTransport createTransport(final Set<Transport> transports,
+ final SSLContext sslContext,
+ final Port port,
+ final Set<AmqpProtocolVersion> supported,
+ final AmqpProtocolVersion defaultSupportedProtocolReply)
+ {
+ return new TCPandSSLTransport(transports, sslContext, port, supported, defaultSupportedProtocolReply);
+ }
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransportProviderFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransportProviderFactory.java
new file mode 100644
index 0000000000..9b61d1d037
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransportProviderFactory.java
@@ -0,0 +1,55 @@
+/*
+ *
+ * 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.server.transport;
+
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.plugin.TransportProviderFactory;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Set;
+
+public class TCPandSSLTransportProviderFactory implements TransportProviderFactory
+{
+
+ private static final String TYPE = "TCPandSSL";
+
+ @Override
+ public Set<Set<Transport>> getSupportedTransports()
+ {
+ return new HashSet<Set<Transport>>(Arrays.asList(EnumSet.of(Transport.TCP),
+ EnumSet.of(Transport.SSL),
+ EnumSet.of(Transport.TCP,Transport.SSL)));
+ }
+
+ @Override
+ public TransportProvider getTransportProvider(final Set<Transport> transports)
+ {
+ return new TCPandSSLTransportProvider();
+ }
+
+ @Override
+ public String getType()
+ {
+ return TYPE;
+ }
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TransportProvider.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TransportProvider.java
new file mode 100644
index 0000000000..86b1e31727
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TransportProvider.java
@@ -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.
+ *
+ */
+package org.apache.qpid.server.transport;
+
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.protocol.AmqpProtocolVersion;
+
+import javax.net.ssl.SSLContext;
+import java.net.InetSocketAddress;
+import java.util.Set;
+
+public interface TransportProvider
+{
+ AcceptingTransport createTransport(Set<Transport> transports,
+ SSLContext sslContext,
+ Port port,
+ Set<AmqpProtocolVersion> supported,
+ AmqpProtocolVersion defaultSupportedProtocolReply);
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
index 0cd4f0b6b2..5859ce3c68 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
@@ -563,11 +563,6 @@ public abstract class AbstractVirtualHost implements VirtualHost, IConnectionReg
String alternateExchangeName)
throws AMQException
{
-
- if(_exchangeRegistry.isReservedExchangeName(name))
- {
- throw new ReservedExchangeNameException(name);
- }
synchronized (_exchangeRegistry)
{
Exchange existing;
@@ -575,6 +570,11 @@ public abstract class AbstractVirtualHost implements VirtualHost, IConnectionReg
{
throw new ExchangeExistsException(name,existing);
}
+ if(_exchangeRegistry.isReservedExchangeName(name))
+ {
+ throw new ReservedExchangeNameException(name);
+ }
+
Exchange alternateExchange;
if(alternateExchangeName != null)
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/BindingRecoverer.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/BindingRecoverer.java
index a321c285b7..de6d3d9e75 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/BindingRecoverer.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/BindingRecoverer.java
@@ -20,15 +20,12 @@
*/
package org.apache.qpid.server.virtualhost;
-import java.nio.ByteBuffer;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.exchange.ExchangeRegistry;
diff --git a/qpid/java/broker-core/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.TransportProviderFactory b/qpid/java/broker-core/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.TransportProviderFactory
new file mode 100644
index 0000000000..3838a9c39f
--- /dev/null
+++ b/qpid/java/broker-core/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.TransportProviderFactory
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+org.apache.qpid.server.transport.TCPandSSLTransportProviderFactory \ No newline at end of file
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java
index dc9ddf7b32..f60f173de9 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java
@@ -26,7 +26,6 @@ import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.queue.AMQPriorityQueue;
import org.apache.qpid.server.queue.AMQQueue;
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/DefaultExchangeFactoryTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/DefaultExchangeFactoryTest.java
index 86ae3e6e9c..16d3e44bb5 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/DefaultExchangeFactoryTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/DefaultExchangeFactoryTest.java
@@ -26,7 +26,6 @@ import java.util.List;
import java.util.UUID;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.test.utils.QpidTestCase;
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/FanoutExchangeTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/FanoutExchangeTest.java
index 7335d43b2e..98ff2421bc 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/FanoutExchangeTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/FanoutExchangeTest.java
@@ -37,8 +37,6 @@ import org.apache.qpid.AMQException;
import org.apache.qpid.AMQInternalException;
import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.common.AMQPFilterTypes;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.message.AMQMessageHeader;
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/HeadersExchangeTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/HeadersExchangeTest.java
index 0f1ab65244..757624d090 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/HeadersExchangeTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/HeadersExchangeTest.java
@@ -32,7 +32,6 @@ import junit.framework.TestCase;
import org.apache.qpid.AMQInternalException;
import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.common.AMQPFilterTypes;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.message.AMQMessageHeader;
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java
index a84f5e1ecb..344ddd9366 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java
@@ -24,14 +24,12 @@ import java.util.List;
import junit.framework.Assert;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.message.MessageReference;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.model.UUIDGenerator;
import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.queue.AMQQueueFactory;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java
index e52ead451e..d9ecfc91b1 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java
@@ -20,7 +20,6 @@
*/
package org.apache.qpid.server.logging.subjects;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.MockAMQQueue;
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/InboundMessageAdapterTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/InboundMessageAdapterTest.java
index 584e26d88f..2c7fa3a8d0 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/InboundMessageAdapterTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/InboundMessageAdapterTest.java
@@ -23,7 +23,6 @@ package org.apache.qpid.server.queue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.message.AMQMessageHeader;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.test.utils.QpidTestCase;
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java
index 2a0c12ff3e..d7ef240ef4 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java
@@ -21,7 +21,6 @@
package org.apache.qpid.server.queue;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.configuration.QueueConfiguration;
import org.apache.qpid.server.exchange.Exchange;
@@ -35,7 +34,6 @@ import org.apache.qpid.server.virtualhost.VirtualHost;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
index 3a41bb9c72..4058eac99d 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
@@ -34,8 +34,6 @@ import org.apache.qpid.AMQException;
import org.apache.qpid.AMQInternalException;
import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.exchange.ExchangeDefaults;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.server.exchange.DirectExchange;
import org.apache.qpid.server.message.AMQMessageHeader;
import org.apache.qpid.server.message.MessageReference;
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/TestMessageMetaData.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/TestMessageMetaData.java
index d99adb91fe..a52b9f8d14 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/TestMessageMetaData.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/TestMessageMetaData.java
@@ -1,3 +1,23 @@
+/*
+ *
+ * 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.server.store;
import java.io.DataOutputStream;
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java
index 77f09dc567..508f33fd35 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java
@@ -22,7 +22,6 @@
package org.apache.qpid.server.subscription;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.logging.LogSubject;
diff --git a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
index cc93c540df..52f55f7e2d 100644
--- a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
+++ b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
@@ -25,7 +25,6 @@ import java.security.Principal;
import javax.security.auth.Subject;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.security.Result;
import org.apache.qpid.server.security.access.ObjectProperties;
import org.apache.qpid.server.security.access.ObjectType;
diff --git a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/MessageMetaData_0_10.java b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/MessageMetaData_0_10.java
index 092ea7c3c9..2ca680869f 100755
--- a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/MessageMetaData_0_10.java
+++ b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/MessageMetaData_0_10.java
@@ -20,7 +20,6 @@
*/
package org.apache.qpid.server.protocol.v0_10;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.message.AMQMessageHeader;
import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.plugin.MessageMetaDataType;
diff --git a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/MessageTransferMessage.java b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/MessageTransferMessage.java
index e5914d1d4e..34cf6998ab 100644
--- a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/MessageTransferMessage.java
+++ b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/MessageTransferMessage.java
@@ -20,7 +20,6 @@
*/
package org.apache.qpid.server.protocol.v0_10;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.message.AMQMessageHeader;
import org.apache.qpid.server.message.AbstractServerMessageImpl;
import org.apache.qpid.server.message.InboundMessage;
diff --git a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ProtocolEngine_0_10.java b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ProtocolEngine_0_10.java
index 9e41a5234c..b8fcdbfe6d 100755
--- a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ProtocolEngine_0_10.java
+++ b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ProtocolEngine_0_10.java
@@ -60,15 +60,8 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol
if(network != null)
{
- setNetworkConnection(network);
+ setNetworkConnection(network, network.getSender());
}
-
-
- }
-
- public void setNetworkConnection(NetworkConnection network)
- {
- setNetworkConnection(network, network.getSender());
}
public void setNetworkConnection(NetworkConnection network, Sender<ByteBuffer> sender)
@@ -77,7 +70,6 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol
_connection.setNetworkConnection(network);
_connection.setSender(new Disassembler(wrapSender(sender), MAX_FRAME_SIZE));
- _connection.setPeerPrincipal(_network.getPeerPrincipal());
// FIXME Two log messages to maintain compatibility with earlier protocol versions
_connection.getLogActor().message(ConnectionMessages.OPEN(null, null, null, null, false, false, false, false));
_connection.getLogActor().message(ConnectionMessages.OPEN(null, "0-10", null, null, false, true, false, false));
diff --git a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java
index 72d6a0832d..b4d591a72f 100644
--- a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java
+++ b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java
@@ -73,7 +73,6 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
private Port _port;
private AtomicLong _lastIoTime = new AtomicLong();
private boolean _blocking;
- private Principal _peerPrincipal;
private NetworkConnection _networkConnection;
private Transport _transport;
private volatile boolean _stopped;
@@ -529,12 +528,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
public Principal getPeerPrincipal()
{
- return _peerPrincipal;
- }
-
- public void setPeerPrincipal(Principal peerPrincipal)
- {
- _peerPrincipal = peerPrincipal;
+ return _networkConnection.getPeerPrincipal();
}
@Override
diff --git a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerSessionDelegate.java b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerSessionDelegate.java
index 395aed29ce..041e1d3645 100644
--- a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerSessionDelegate.java
+++ b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerSessionDelegate.java
@@ -212,10 +212,21 @@ public class ServerSessionDelegate extends SessionDelegate
{
ServerSession s = (ServerSession) session;
queue.setExclusiveOwningSession(s);
+
+ ((ServerSession) session).addSessionCloseTask(new ServerSession.Task()
+ {
+ public void doTask(ServerSession session)
+ {
+ if(queue.getExclusiveOwningSession() == session)
+ {
+ queue.setExclusiveOwningSession(null);
+ }
+ }
+ });
+
if(queue.getAuthorizationHolder() == null)
{
queue.setAuthorizationHolder(s);
- queue.setExclusiveOwningSession(s);
((ServerSession) session).addSessionCloseTask(new ServerSession.Task()
{
public void doTask(ServerSession session)
@@ -223,7 +234,6 @@ public class ServerSessionDelegate extends SessionDelegate
if(queue.getAuthorizationHolder() == session)
{
queue.setAuthorizationHolder(null);
- queue.setExclusiveOwningSession(null);
}
}
});
diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java
index 4cacae134e..f04475eb33 100644
--- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java
+++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java
@@ -1271,11 +1271,11 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
}
else if (throwable instanceof IOException)
{
- _logger.error("IOException caught in" + this + ", session closed implictly: " + throwable);
+ _logger.info("IOException caught in " + this + ", connection closed implicitly: " + throwable);
}
else
{
- _logger.error("Exception caught in" + this + ", closing session explictly: " + throwable, throwable);
+ _logger.error("Exception caught in " + this + ", closing connection explicitly: " + throwable, throwable);
MethodRegistry methodRegistry = MethodRegistry.getMethodRegistry(getProtocolVersion());
diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/handler/ExchangeBoundHandler.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/handler/ExchangeBoundHandler.java
index 0535236f94..4ebddb0f68 100644
--- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/handler/ExchangeBoundHandler.java
+++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/handler/ExchangeBoundHandler.java
@@ -29,7 +29,6 @@ import org.apache.qpid.server.protocol.v0_8.AMQChannel;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.protocol.v0_8.AMQProtocolSession;
import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.protocol.v0_8.state.AMQStateManager;
import org.apache.qpid.server.protocol.v0_8.state.StateAwareMethodListener;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -80,13 +79,9 @@ public class ExchangeBoundHandler implements StateAwareMethodListener<ExchangeBo
channel.sync();
- AMQShortString exchangeName = body.getExchange();
+ AMQShortString exchangeName = body.getExchange() == null ? AMQShortString.EMPTY_STRING : body.getExchange();
AMQShortString queueName = body.getQueue();
AMQShortString routingKey = body.getRoutingKey();
- if (exchangeName == null)
- {
- throw new AMQException("Exchange exchange must not be null");
- }
Exchange exchange = virtualHost.getExchange(exchangeName.toString());
ExchangeBoundOkBody response;
if (exchange == null)
@@ -94,7 +89,7 @@ public class ExchangeBoundHandler implements StateAwareMethodListener<ExchangeBo
response = methodRegistry.createExchangeBoundOkBody(EXCHANGE_NOT_FOUND,
- new AMQShortString("Exchange " + exchangeName + " not found"));
+ new AMQShortString("Exchange '" + exchangeName + "' not found"));
}
else if (routingKey == null)
{
@@ -119,7 +114,7 @@ public class ExchangeBoundHandler implements StateAwareMethodListener<ExchangeBo
{
response = methodRegistry.createExchangeBoundOkBody(QUEUE_NOT_FOUND, // replyCode
- new AMQShortString("Queue " + queueName + " not found")); // replyText
+ new AMQShortString("Queue '" + queueName + "' not found")); // replyText
}
else
{
@@ -133,7 +128,7 @@ public class ExchangeBoundHandler implements StateAwareMethodListener<ExchangeBo
{
response = methodRegistry.createExchangeBoundOkBody(QUEUE_NOT_BOUND, // replyCode
- new AMQShortString("Queue " + queueName + " not bound to exchange " + exchangeName)); // replyText
+ new AMQShortString("Queue '" + queueName + "' not bound to exchange '" + exchangeName + "'")); // replyText
}
}
}
@@ -145,7 +140,7 @@ public class ExchangeBoundHandler implements StateAwareMethodListener<ExchangeBo
{
response = methodRegistry.createExchangeBoundOkBody(QUEUE_NOT_FOUND, // replyCode
- new AMQShortString("Queue " + queueName + " not found")); // replyText
+ new AMQShortString("Queue '" + queueName + "' not found")); // replyText
}
else
{
@@ -159,8 +154,8 @@ public class ExchangeBoundHandler implements StateAwareMethodListener<ExchangeBo
else
{
- String message = "Queue " + queueName + " not bound with routing key " +
- body.getRoutingKey() + " to exchange " + exchangeName;
+ String message = "Queue '" + queueName + "' not bound with routing key '" +
+ body.getRoutingKey() + "' to exchange '" + exchangeName + "'";
if(message.length()>255)
{
@@ -183,8 +178,8 @@ public class ExchangeBoundHandler implements StateAwareMethodListener<ExchangeBo
{
response = methodRegistry.createExchangeBoundOkBody(NO_QUEUE_BOUND_WITH_RK, // replyCode
- new AMQShortString("No queue bound with routing key " + body.getRoutingKey() +
- " to exchange " + exchangeName)); // replyText
+ new AMQShortString("No queue bound with routing key '" + body.getRoutingKey() +
+ "' to exchange '" + exchangeName + "'")); // replyText
}
}
session.writeFrame(response.generateFrame(channelId));
diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngineTest.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngineTest.java
index f5e58cfd02..1506ecb92f 100644
--- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngineTest.java
+++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngineTest.java
@@ -1,3 +1,23 @@
+/*
+ *
+ * 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.server.protocol.v0_8;
import static org.mockito.Mockito.mock;
diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java
index 5b1e5af7bd..f1dfc52ba4 100644
--- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java
+++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java
@@ -314,11 +314,6 @@ public class InternalTestProtocolSession extends AMQProtocolEngine implements Pr
}
@Override
- public void setPeerPrincipal(Principal principal)
- {
- }
-
- @Override
public Principal getPeerPrincipal()
{
return null;
diff --git a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java
index 68e9a88b0b..9b11c0f48d 100644
--- a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java
+++ b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java
@@ -26,7 +26,6 @@ import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.message.MessageReference;
import org.apache.qpid.server.message.ServerMessage;
diff --git a/qpid/java/broker-plugins/amqp-msg-conv-0-8-to-0-10/src/main/java/org/apache/qpid/server/protocol/converter/v0_8_v0_10/MessageConverter_0_10_to_0_8.java b/qpid/java/broker-plugins/amqp-msg-conv-0-8-to-0-10/src/main/java/org/apache/qpid/server/protocol/converter/v0_8_v0_10/MessageConverter_0_10_to_0_8.java
index e832ef7569..92bccf871f 100644
--- a/qpid/java/broker-plugins/amqp-msg-conv-0-8-to-0-10/src/main/java/org/apache/qpid/server/protocol/converter/v0_8_v0_10/MessageConverter_0_10_to_0_8.java
+++ b/qpid/java/broker-plugins/amqp-msg-conv-0-8-to-0-10/src/main/java/org/apache/qpid/server/protocol/converter/v0_8_v0_10/MessageConverter_0_10_to_0_8.java
@@ -1,3 +1,23 @@
+/*
+ *
+ * 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.server.protocol.converter.v0_8_v0_10;
import java.nio.ByteBuffer;
diff --git a/qpid/java/broker-plugins/derby-store/src/main/java/resources/virtualhost/store/derby/add.html b/qpid/java/broker-plugins/derby-store/src/main/java/resources/virtualhost/store/derby/add.html
index 2ed5b35c10..ead232d0b1 100644
--- a/qpid/java/broker-plugins/derby-store/src/main/java/resources/virtualhost/store/derby/add.html
+++ b/qpid/java/broker-plugins/derby-store/src/main/java/resources/virtualhost/store/derby/add.html
@@ -1,3 +1,19 @@
+<!--
+ ~ 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.
+ -->
<table class="tableContainer-table tableContainer-table-horiz">
<tr>
<td class="tableContainer-labelCell" style="width: 300px;"><strong>Path to store location*: </strong></td>
diff --git a/qpid/java/broker-plugins/jdbc-provider-bone/src/main/java/resources/virtualhost/store/pool/bonecp/add.html b/qpid/java/broker-plugins/jdbc-provider-bone/src/main/java/resources/virtualhost/store/pool/bonecp/add.html
index 52da8f52ae..0a83bd9f6f 100644
--- a/qpid/java/broker-plugins/jdbc-provider-bone/src/main/java/resources/virtualhost/store/pool/bonecp/add.html
+++ b/qpid/java/broker-plugins/jdbc-provider-bone/src/main/java/resources/virtualhost/store/pool/bonecp/add.html
@@ -1,3 +1,19 @@
+<!--
+ ~ 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.
+ -->
<table class="tableContainer-table tableContainer-table-horiz">
<tr>
diff --git a/qpid/java/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/store/jdbc/add.html b/qpid/java/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/store/jdbc/add.html
index 966b4fcc06..c3d6c287a2 100644
--- a/qpid/java/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/store/jdbc/add.html
+++ b/qpid/java/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/store/jdbc/add.html
@@ -1,3 +1,19 @@
+<!--
+ ~ 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.
+ -->
<table class="tableContainer-table tableContainer-table-horiz">
<tr>
<td class="tableContainer-labelCell" style="width: 300px;"><strong>JDBC Url*: </strong></td>
diff --git a/qpid/java/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/store/pool/none/add.html b/qpid/java/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/store/pool/none/add.html
index e69de29bb2..2666129a1f 100644
--- a/qpid/java/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/store/pool/none/add.html
+++ b/qpid/java/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/store/pool/none/add.html
@@ -0,0 +1,17 @@
+<!--
+ ~ 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.
+ -->
+
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
index f8a2091282..e92960a719 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
@@ -23,15 +23,13 @@ package org.apache.qpid.server.management.plugin;
import java.lang.reflect.Type;
import java.net.SocketAddress;
import java.security.GeneralSecurityException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.UUID;
+import java.util.*;
+import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
import org.apache.log4j.Logger;
import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.logging.actors.CurrentActor;
@@ -78,6 +76,7 @@ import org.apache.qpid.server.model.VirtualHost;
import org.apache.qpid.server.model.adapter.AbstractPluginAdapter;
import org.apache.qpid.server.plugin.PluginFactory;
import org.apache.qpid.server.util.MapValueConverter;
+import org.apache.qpid.transport.network.security.ssl.QpidMultipleTrustManager;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.DispatcherType;
import org.eclipse.jetty.server.Server;
@@ -183,7 +182,7 @@ public class HttpManagement extends AbstractPluginAdapter implements HttpManagem
}
catch (Exception e)
{
- throw new RuntimeException("Failed to start http management on ports " + httpPorts);
+ throw new RuntimeException("Failed to start HTTP management on ports : " + httpPorts, e);
}
CurrentActor.get().message(ManagementConsoleMessages.READY(OPERATIONAL_LOGGING_NAME));
@@ -200,7 +199,7 @@ public class HttpManagement extends AbstractPluginAdapter implements HttpManagem
}
catch (Exception e)
{
- throw new RuntimeException("Failed to stop http management on port " + getHttpPorts(getBroker().getPorts()));
+ throw new RuntimeException("Failed to stop HTTP management on ports : " + getHttpPorts(getBroker().getPorts()), e);
}
}
@@ -240,28 +239,93 @@ public class HttpManagement extends AbstractPluginAdapter implements HttpManagem
else if (transports.contains(Transport.SSL))
{
KeyStore keyStore = port.getKeyStore();
+ Collection<TrustStore> trustStores = port.getTrustStores();
if (keyStore == null)
{
throw new IllegalConfigurationException("Key store is not configured. Cannot start management on HTTPS port without keystore");
}
SslContextFactory factory = new SslContextFactory();
+ final boolean needClientAuth = Boolean.valueOf(String.valueOf(port.getAttribute(Port.NEED_CLIENT_AUTH)));
+ final boolean wantClientAuth = Boolean.valueOf(String.valueOf(port.getAttribute(Port.WANT_CLIENT_AUTH)));
+ boolean needClientCert = needClientAuth || wantClientAuth;
+ if (needClientCert && trustStores.isEmpty())
+ {
+ throw new IllegalConfigurationException("Client certificate authentication is enabled on AMQP port '"
+ + this.getName() + "' but no trust store defined");
+ }
+
try
{
SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(keyStore.getKeyManagers(), null, null);
+ KeyManager[] keyManagers = keyStore.getKeyManagers();
+
+ TrustManager[] trustManagers;
+ if(trustStores == null || trustStores.isEmpty())
+ {
+ trustManagers = null;
+ }
+ else if(trustStores.size() == 1)
+ {
+ trustManagers = trustStores.iterator().next().getTrustManagers();
+ }
+ else
+ {
+ Collection<TrustManager> trustManagerList = new ArrayList<TrustManager>();
+ final QpidMultipleTrustManager mulTrustManager = new QpidMultipleTrustManager();
+
+ for(TrustStore ts : trustStores)
+ {
+ TrustManager[] managers = ts.getTrustManagers();
+ if(managers != null)
+ {
+ for(TrustManager manager : managers)
+ {
+ if(manager instanceof X509TrustManager)
+ {
+ mulTrustManager.addTrustManager((X509TrustManager)manager);
+ }
+ else
+ {
+ trustManagerList.add(manager);
+ }
+ }
+ }
+ }
+ if(!mulTrustManager.isEmpty())
+ {
+ trustManagerList.add(mulTrustManager);
+ }
+ trustManagers = trustManagerList.toArray(new TrustManager[trustManagerList.size()]);
+ }
+ sslContext.init(keyManagers, trustManagers, null);
+
factory.setSslContext(sslContext);
+ if(needClientAuth)
+ {
+ factory.setNeedClientAuth(true);
+ }
+ else if(wantClientAuth)
+ {
+ factory.setWantClientAuth(true);
+ }
}
catch (GeneralSecurityException e)
{
throw new RuntimeException("Cannot configure port " + port.getName() + " for transport " + Transport.SSL, e);
}
connector = new SslSocketConnector(factory);
+
}
else
{
throw new IllegalArgumentException("Unexpected transport on port " + port.getName() + ":" + transports);
}
lastPort = port.getPort();
+ String bindingAddress = port.getBindingAddress();
+ if(bindingAddress != null && !bindingAddress.trim().equals("") && !bindingAddress.trim().equals("*"))
+ {
+ connector.setHost(bindingAddress.trim());
+ }
connector.setPort(port.getPort());
server.addConnector(connector);
}
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java
index 990ff1c53b..f6674b5152 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java
@@ -23,10 +23,14 @@ package org.apache.qpid.server.management.plugin;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.security.AccessControlException;
+import java.security.Principal;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
import javax.security.auth.Subject;
+import javax.security.auth.x500.X500Principal;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@@ -36,11 +40,17 @@ import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.HttpManagementActor;
import org.apache.qpid.server.management.plugin.session.LoginLogoutReporter;
+import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.security.SubjectCreator;
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManagerFactory;
+import org.apache.qpid.transport.network.security.ssl.SSLUtil;
public class HttpManagementUtil
{
@@ -164,17 +174,41 @@ public class HttpManagementUtil
session.setAttribute(ATTR_LOGIN_LOGOUT_REPORTER, new LoginLogoutReporter(logActor, subject));
}
- private static Subject tryToAuthenticate(HttpServletRequest request, HttpManagementConfiguration managementConfig)
+ public static Subject tryToAuthenticate(HttpServletRequest request, HttpManagementConfiguration managementConfig)
{
Subject subject = null;
SocketAddress localAddress = getSocketAddress(request);
- SubjectCreator subjectCreator = managementConfig.getAuthenticationProvider(localAddress).getSubjectCreator();
+ final AuthenticationProvider authenticationProvider = managementConfig.getAuthenticationProvider(localAddress);
+ SubjectCreator subjectCreator = authenticationProvider.getSubjectCreator();
String remoteUser = request.getRemoteUser();
if (remoteUser != null || subjectCreator.isAnonymousAuthenticationAllowed())
{
subject = authenticateUser(subjectCreator, remoteUser, null);
}
+ else if(subjectCreator.isExternalAuthenticationAllowed()
+ && Collections.list(request.getAttributeNames()).contains("javax.servlet.request.X509Certificate"))
+ {
+ Principal principal = null;
+ X509Certificate[] certificates =
+ (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
+ if(certificates != null && certificates.length != 0)
+ {
+ principal = certificates[0].getSubjectX500Principal();
+
+ if(!Boolean.valueOf(String.valueOf(authenticationProvider.getAttribute(ExternalAuthenticationManagerFactory.ATTRIBUTE_USE_FULL_DN))))
+ {
+ String username;
+ String dn = ((X500Principal) principal).getName(X500Principal.RFC2253);
+
+
+ username = SSLUtil.getIdFromSubjectDN(dn);
+ principal = new UsernamePrincipal(username);
+ }
+
+ subject = subjectCreator.createSubjectWithGroups(new AuthenticatedPrincipal(principal));
+ }
+ }
else
{
String header = request.getHeader("Authorization");
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java
index a08d6496bf..ee481ebdbe 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java
@@ -33,7 +33,6 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.HttpManagementActor;
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
index 2b035fed8f..9ad52007ab 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
@@ -284,6 +284,11 @@ public class SaslServlet extends AbstractServlet
@Override
protected Subject getAuthorisedSubject(HttpServletRequest request)
{
- return HttpManagementUtil.getAuthorisedSubject(request.getSession());
+ Subject subject = HttpManagementUtil.getAuthorisedSubject(request.getSession());
+ if(subject == null)
+ {
+ subject = HttpManagementUtil.tryToAuthenticate(request, HttpManagementUtil.getManagementConfiguration(getServletContext()));
+ }
+ return subject;
}
}
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addPort.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addPort.html
index 59abbadf32..c7676d27b7 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addPort.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addPort.html
@@ -42,9 +42,11 @@
data-dojo-props="name:'authenticationProvider',label:'Authentication Provider*:', searchAttr: 'name', required: true, placeHolder: 'Select Provider'">
</select>
</div>
- <div id="formAddPort:fieldsAMQP">
+ <div id="formAddPort:fieldsBindingAddress">
<input id="formAddPort.bindingAddress" type="text" name="bindingAddress" placeholder="*"
- dojoType="dijit.form.TextBox" data-dojo-props="label: 'Binding address:'"/>
+ dojoType="dijit.form.TextBox" data-dojo-props="label: 'Binding address:'"/>
+ </div>
+ <div id="formAddPort:fieldsAMQP">
<input id="formAddPort.protocolsDefault" type="checkbox" checked="checked"
dojoType="dijit.form.CheckBox" data-dojo-props="label: 'Support default protocols:'"/>
<select id="formAddPort.protocolsAMQP" name="protocols" data-dojo-type="dijit.form.MultiSelect" multiple="true"
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/footer.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/footer.html
index fa84825e80..76d1d26695 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/footer.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/footer.html
@@ -19,10 +19,10 @@
-
-->
-<div class="footer"><p>&#xA9; 2004-<span class="currentYear">2012</span> The Apache Software Foundation.
+<div class="footer"><p>&#xA9; 2004-<span class="currentYear">2014</span> The Apache Software Foundation.
<br/>
Apache Qpid, Qpid, Apache, the Apache feather logo, and the Apache Qpid project logo are trademarks of
The Apache Software Foundation.
<br/>
All other marks mentioned may be trademarks or registered trademarks of their respective owners.
-</div> \ No newline at end of file
+</div>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Connection.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Connection.js
index b0ad1c661b..2b455a90f1 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Connection.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Connection.js
@@ -84,12 +84,11 @@ define(["dojo/_base/xhr",
}
storeNodes(["name",
- "state",
- "durable",
+ "clientVersion",
+ "clientId",
"principal",
"port",
"transport",
- "lifetimePolicy",
"msgInRate",
"bytesInRate",
"bytesInRateUnits",
@@ -125,12 +124,11 @@ define(["dojo/_base/xhr",
ConnectionUpdater.prototype.updateHeader = function()
{
this.name.innerHTML = entities.encode(String(this.connectionData[ "name" ]));
- this.state.innerHTML = entities.encode(String(this.connectionData[ "state" ]));
- this.durable.innerHTML = entities.encode(String(this.connectionData[ "durable" ]));
+ this.clientId.innerHTML = entities.encode(String(this.connectionData[ "clientId" ]));
+ this.clientVersion.innerHTML = entities.encode(String(this.connectionData[ "clientVersion" ]));
this.principal.innerHTML = entities.encode(String(this.connectionData[ "principal" ]));
this.port.innerHTML = entities.encode(String(this.connectionData[ "port" ]));
this.transport.innerHTML = entities.encode(String(this.connectionData[ "transport" ]));
- this.lifetimePolicy.innerHTML = entities.encode(String(this.connectionData[ "lifetimePolicy" ]));
};
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js
index 18abfa443f..86ded8f059 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js
@@ -110,7 +110,7 @@ define(["dojo/_base/xhr",
}
var type = dijit.byId("formAddPort.type").value;
- if (type == "AMQP")
+ if (type == "AMQP" || type == "HTTP")
{
var transportWidget = registry.byId("formAddPort.transports");
var needClientAuth = dijit.byId("formAddPort.needClientAuth");
@@ -154,7 +154,7 @@ define(["dojo/_base/xhr",
{
var clientAuthPanel = dojo.byId("formAddPort:fieldsClientAuth");
var display = clientAuthPanel.style.display;
- if (transportType == "SSL" && protocolType == "AMQP")
+ if (transportType == "SSL" && (protocolType == "AMQP" || protocolType == "HTTP"))
{
clientAuthPanel.style.display = "block";
registry.byId("formAddPort.needClientAuth").set("disabled", false);
@@ -212,8 +212,11 @@ define(["dojo/_base/xhr",
});
var isAMQP = ("AMQP" == newValue);
- registry.byId("formAddPort.needClientAuth").set("enabled", isAMQP);
- registry.byId("formAddPort.wantClientAuth").set("enabled", isAMQP);
+
+ var isHTTP = ("HTTP" == newValue);
+
+ registry.byId("formAddPort.needClientAuth").set("enabled", isAMQP || isHTTP);
+ registry.byId("formAddPort.wantClientAuth").set("enabled", isAMQP || isHTTP);
registry.byId("formAddPort:fields" + newValue).domNode.style.display = "block";
var defaultsAMQPProtocols = registry.byId("formAddPort.protocolsDefault");
@@ -246,13 +249,15 @@ define(["dojo/_base/xhr",
transportWidget.set("disabled", disableTransportWidget);
registry.byId("formAddPort.authenticationProvider").set("disabled", isRMI);
registry.byId("formAddPort:fieldsAuthenticationProvider").domNode.style.display = isRMI? "none" : "block";
+ registry.byId("formAddPort:fieldsBindingAddress").domNode.style.display = newValue == "JMX" ? "none" : "block";
+
});
theForm = registry.byId("formAddPort");
var containers = ["formAddPort:fields", "formAddPort:fieldsTransportSSL", "formAddPort:fieldsAMQP",
"formAddPort:fieldsJMX", "formAddPort:fieldsHTTP", "formAddPort:transport",
- "formAddPort:fieldsClientAuthCheckboxes", "formAddPort:fieldsAuthenticationProvider"];
+ "formAddPort:fieldsClientAuthCheckboxes", "formAddPort:fieldsAuthenticationProvider", "formAddPort:fieldsBindingAddress"];
var labelWidthValue = "200";
for(var i = 0; i < containers.length; i++)
{
@@ -448,8 +453,10 @@ define(["dojo/_base/xhr",
{
var httpProtocolsWidget = registry.byId("formAddPort.protocolsHTTP");
httpProtocolsWidget.set("disabled", false);
- httpProtocolsWidget.set("value", protocols[0])
+ httpProtocolsWidget.set("value", protocols[0]);
typeWidget.set("value", "HTTP");
+ var addressWidget = registry.byId("formAddPort.bindingAddress");
+ addressWidget.set("value", port.bindingAddress)
}
registry.byId("formAddPort:fields" + typeWidget.value).domNode.style.display = "block";
typeWidget.set("disabled", true);
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showConnection.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showConnection.html
index 4611b77f6c..1032bdeaef 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showConnection.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showConnection.html
@@ -19,30 +19,28 @@
-
-->
<div class="connection">
- <span style="">Name:</span><span class="name" style="position:absolute; left:6em"></span>
+ <span style="">Name:</span><span class="name" style="position:absolute; left:8em"></span>
<br/>
- <span style="">State:</span><span class="state" style="position:absolute; left:6em"></span>
+ <span style="">User:</span><span class="principal" style="position:absolute; left:8em"></span>
<span style="position:absolute; left:26em">Pre-fetched:</span>
<br/>
- <span style="">Durable:</span><span class="durable" style="position:absolute; left:6em"></span>
+ <span style="">ClientID:</span><span class="clientId" style="position:absolute; left:8em"></span>
<span style="position:absolute; left:26em">Inbound:</span>
<span class="msgInRate" style="position:absolute; right:9.5em"></span>
<span style="position:absolute; right: 5em; width: 4em"> msg/s</span>
<span class="bytesInRate" style="position:absolute; right: 3.3em"></span>
<span class="bytesInRateUnits" style="position:absolute; right: 0em; width: 3em"></span>
<br/>
- <span style="">Lifespan:</span><span style="position:absolute; left:6em" class="lifetimePolicy"></span>
+ <span style="">Client Version:</span><span style="position:absolute; left:8em" class="clientVersion"></span>
<span style="position:absolute; left:26em">Outbound:</span>
<span class="msgOutRate" style="position:absolute; right:9.5em"></span>
<span style="position:absolute; right: 5em; width: 4em"> msg/s</span>
<span class="bytesOutRate" style="position:absolute; right: 3.3em"></span>
<span class="bytesOutRateUnits" style="position:absolute; right: 0em; width: 3em"></span>
<br/>
- <span style="">User:</span><span style="position:absolute; left:6em" class="principal"></span>
+ <span style="">Port:</span><span style="position:absolute; left:8em" class="port"></span>
<br/>
- <span style="">Port:</span><span style="position:absolute; left:6em" class="port"></span>
- <br/>
- <span style="">Transport:</span><span style="position:absolute; left:6em" class="transport"></span>
+ <span style="">Transport:</span><span style="position:absolute; left:8em" class="transport"></span>
<br/>
<br/>
<div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Sessions'">
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showMessage.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showMessage.html
index 9a6ec55686..caf26bc075 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showMessage.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showMessage.html
@@ -24,10 +24,18 @@
<td><span class="message-id"></span></td>
</tr>
<tr style="margin-bottom: 4pt">
+ <td style="width: 10em; vertical-align: top"><span style="font-weight: bold;">Size:</span></td>
+ <td><span class="message-size"></span>&nbsp;bytes</td>
+ </tr>
+ <tr style="margin-bottom: 4pt">
<td style="width: 10em; vertical-align: top"><span style="font-weight: bold;">Message Id:</span></td>
<td><span class="message-messageId"></span></td>
</tr>
<tr style="margin-bottom: 4pt">
+ <td style="width: 10em; vertical-align: top"><span style="font-weight: bold;">Correlation Id:</span></td>
+ <td><span class="message-correlationId"></span></td>
+ </tr>
+ <tr style="margin-bottom: 4pt">
<td style="width: 10em; vertical-align: top"><span style="font-weight: bold;">State:</span></td>
<td><span class="message-state"></span></td>
</tr>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/standard/add.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/standard/add.html
index 3519d0dbd6..050ea9533e 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/standard/add.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/standard/add.html
@@ -1,3 +1,19 @@
+<!--
+ ~ 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.
+ -->
<table class="tableContainer-table tableContainer-table-horiz">
<tr>
<td class="tableContainer-labelCell" style="width: 300px;"><strong>Store Type*: </strong></td>
diff --git a/qpid/java/broker-plugins/memory-store/src/main/java/resources/virtualhost/store/memory/add.html b/qpid/java/broker-plugins/memory-store/src/main/java/resources/virtualhost/store/memory/add.html
index e69de29bb2..2666129a1f 100644
--- a/qpid/java/broker-plugins/memory-store/src/main/java/resources/virtualhost/store/memory/add.html
+++ b/qpid/java/broker-plugins/memory-store/src/main/java/resources/virtualhost/store/memory/add.html
@@ -0,0 +1,17 @@
+<!--
+ ~ 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.
+ -->
+
diff --git a/qpid/java/broker-plugins/websocket/build.xml b/qpid/java/broker-plugins/websocket/build.xml
new file mode 100644
index 0000000000..fc3dd3b846
--- /dev/null
+++ b/qpid/java/broker-plugins/websocket/build.xml
@@ -0,0 +1,32 @@
+<!--
+ - 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.
+ -->
+<project name="Qpid Broker-Plugins Websocket Transport" default="build">
+ <property name="module.depends" value="common broker-core" />
+ <property name="module.test.depends" value="qpid-test-utils broker-core/tests" />
+
+ <property name="module.genpom" value="true"/>
+ <property name="module.genpom.args" value="-Sqpid-common=provided -Sqpid-broker-core=provided"/>
+
+ <property name="broker.plugin" value="true"/>
+ <property name="broker-plugins-websocket.libs" value="" />
+
+ <import file="../../module.xml" />
+
+ <target name="bundle" depends="bundle-tasks"/>
+</project>
diff --git a/qpid/java/broker-plugins/websocket/pom.xml b/qpid/java/broker-plugins/websocket/pom.xml
new file mode 100644
index 0000000000..2029bd33aa
--- /dev/null
+++ b/qpid/java/broker-plugins/websocket/pom.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>qpid-project</artifactId>
+ <groupId>org.apache.qpid</groupId>
+ <version>0.26-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>qpid-broker-plugins-websocket</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.qpid</groupId>
+ <artifactId>qpid-broker-core</artifactId>
+ <version>0.26-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-servlet_2.5_spec</artifactId>
+ <version>1.2</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ <version>7.6.10.v20130312</version>
+ <scope>compile</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.jetty.orbit</groupId>
+ <artifactId>javax.servlet</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-continuation</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-http</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-continuation</artifactId>
+ <version>7.6.10.v20130312</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-security</artifactId>
+ <version>7.6.10.v20130312</version>
+ <scope>compile</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-http</artifactId>
+ <version>7.6.10.v20130312</version>
+ <scope>compile</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-io</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-io</artifactId>
+ <version>7.6.10.v20130312</version>
+ <scope>compile</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-util</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-servlet</artifactId>
+ <version>7.6.10.v20130312</version>
+ <scope>compile</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-security</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-util</artifactId>
+ <version>7.6.10.v20130312</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-websocket</artifactId>
+ <version>7.6.10.v20130312</version>
+ <scope>compile</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-util</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-io</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-http</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+
+ <build>
+ </build>
+
+</project> \ No newline at end of file
diff --git a/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketProvider.java b/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketProvider.java
new file mode 100644
index 0000000000..fde93a27e3
--- /dev/null
+++ b/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketProvider.java
@@ -0,0 +1,315 @@
+/*
+ *
+ * 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.server.transport.websocket;
+
+import org.apache.qpid.protocol.ProtocolEngine;
+import org.apache.qpid.protocol.ProtocolEngineFactory;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.protocol.AmqpProtocolVersion;
+import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory;
+import org.apache.qpid.server.transport.AcceptingTransport;
+import org.apache.qpid.transport.Binary;
+import org.apache.qpid.transport.Sender;
+import org.apache.qpid.transport.network.NetworkConnection;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
+import org.eclipse.jetty.server.ssl.SslSocketConnector;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.websocket.WebSocket;
+import org.eclipse.jetty.websocket.WebSocketHandler;
+
+import javax.net.ssl.SSLContext;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.security.Principal;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Set;
+
+class WebSocketProvider implements AcceptingTransport
+{
+ public static final String AMQP_WEBSOCKET_SUBPROTOCOL = "AMQPWSB10";
+ private final Transport _transport;
+ private final SSLContext _sslContext;
+ private final Port _port;
+ private final Set<AmqpProtocolVersion> _supported;
+ private final AmqpProtocolVersion _defaultSupportedProtocolReply;
+ private final ProtocolEngineFactory _factory;
+ private Server _server;
+
+ WebSocketProvider(final Transport transport,
+ final SSLContext sslContext,
+ final Port port,
+ final Set<AmqpProtocolVersion> supported,
+ final AmqpProtocolVersion defaultSupportedProtocolReply)
+ {
+ _transport = transport;
+ _sslContext = sslContext;
+ _port = port;
+ _supported = supported;
+ _defaultSupportedProtocolReply = defaultSupportedProtocolReply;
+ _factory = new MultiVersionProtocolEngineFactory(
+ _port.getParent(Broker.class), null,
+ (Boolean)_port.getAttribute(Port.WANT_CLIENT_AUTH),
+ (Boolean)_port.getAttribute(Port.NEED_CLIENT_AUTH),
+ _supported,
+ _defaultSupportedProtocolReply,
+ _port,
+ _transport);
+
+ }
+
+ @Override
+ public void start()
+ {
+ _server = new Server();
+
+ Connector connector = null;
+
+
+ if (_transport == Transport.WS)
+ {
+ connector = new SelectChannelConnector();
+ }
+ else if (_transport == Transport.WSS)
+ {
+ SslContextFactory factory = new SslContextFactory();
+ factory.setSslContext(_sslContext);
+ factory.setNeedClientAuth(true);
+ connector = new SslSelectChannelConnector(factory);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Unexpected transport on port " + _port.getName() + ":" + _transport);
+ }
+ String bindingAddress = _port.getBindingAddress();
+ if(bindingAddress != null && !bindingAddress.trim().equals("") && !bindingAddress.trim().equals("*"))
+ {
+ connector.setHost(bindingAddress.trim());
+ }
+ connector.setPort(_port.getPort());
+ _server.addConnector(connector);
+
+ WebSocketHandler wshandler = new WebSocketHandler()
+ {
+ @Override
+ public WebSocket doWebSocketConnect(final HttpServletRequest request, final String protocol)
+ {
+
+ Principal principal = null;
+ if(Collections.list(request.getAttributeNames()).contains("javax.servlet.request.X509Certificate"))
+ {
+ X509Certificate[] certificates =
+ (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
+ if(certificates != null && certificates.length != 0)
+ {
+ principal = certificates[0].getSubjectDN();
+ }
+ }
+
+ SocketAddress remoteAddress = new InetSocketAddress(request.getRemoteHost(), request.getRemotePort());
+ SocketAddress localAddress = new InetSocketAddress(request.getLocalName(), request.getLocalPort());
+ return AMQP_WEBSOCKET_SUBPROTOCOL.equals(protocol) ? new AmqpWebSocket(_transport, localAddress, remoteAddress, principal) : null;
+ }
+ };
+
+ _server.setHandler(wshandler);
+ try
+ {
+ _server.start();
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ @Override
+ public void close()
+ {
+
+ }
+
+ private class AmqpWebSocket implements WebSocket,WebSocket.OnBinaryMessage
+ {
+ private final SocketAddress _localAddress;
+ private final SocketAddress _remoteAddress;
+ private final Principal _userPrincipal;
+ private Connection _connection;
+ private final Transport _transport;
+ private ProtocolEngine _engine;
+
+ private AmqpWebSocket(final Transport transport,
+ final SocketAddress localAddress,
+ final SocketAddress remoteAddress,
+ final Principal userPrincipal)
+ {
+ _transport = transport;
+ _localAddress = localAddress;
+ _remoteAddress = remoteAddress;
+ _userPrincipal = userPrincipal;
+ }
+
+ @Override
+ public void onMessage(final byte[] data, final int offset, final int length)
+ {
+ _engine.received(ByteBuffer.wrap(data, offset, length).slice());
+ }
+
+ @Override
+ public void onOpen(final Connection connection)
+ {
+ _connection = connection;
+
+ _engine = _factory.newProtocolEngine();
+
+ final ConnectionWrapper connectionWrapper =
+ new ConnectionWrapper(connection, _localAddress, _remoteAddress);
+ connectionWrapper.setPeerPrincipal(_userPrincipal);
+ _engine.setNetworkConnection(connectionWrapper, connectionWrapper.getSender());
+
+ }
+
+ @Override
+ public void onClose(final int closeCode, final String message)
+ {
+ _engine.closed();
+ }
+ }
+
+ private class ConnectionWrapper implements NetworkConnection, Sender<ByteBuffer>
+ {
+ private final WebSocket.Connection _connection;
+ private final SocketAddress _localAddress;
+ private final SocketAddress _remoteAddress;
+ private Principal _principal;
+ private int _maxWriteIdle;
+ private int _maxReadIdle;
+
+ public ConnectionWrapper(final WebSocket.Connection connection,
+ final SocketAddress localAddress,
+ final SocketAddress remoteAddress)
+ {
+ _connection = connection;
+ _localAddress = localAddress;
+ _remoteAddress = remoteAddress;
+ }
+
+ @Override
+ public Sender<ByteBuffer> getSender()
+ {
+ return this;
+ }
+
+ @Override
+ public void start()
+ {
+
+ }
+
+ @Override
+ public void setIdleTimeout(final int i)
+ {
+
+ }
+
+ @Override
+ public void send(final ByteBuffer msg)
+ {
+ try
+ {
+ _connection.sendMessage(msg.array(),msg.arrayOffset()+msg.position(),msg.remaining());
+ }
+ catch (IOException e)
+ {
+ close();
+ }
+ }
+
+ @Override
+ public void flush()
+ {
+
+ }
+
+ @Override
+ public void close()
+ {
+ _connection.close();
+ }
+
+ @Override
+ public SocketAddress getRemoteAddress()
+ {
+ return _remoteAddress;
+ }
+
+ @Override
+ public SocketAddress getLocalAddress()
+ {
+ return _localAddress;
+ }
+
+ @Override
+ public void setMaxWriteIdle(final int sec)
+ {
+ _maxWriteIdle = sec;
+ }
+
+ @Override
+ public void setMaxReadIdle(final int sec)
+ {
+ _maxReadIdle = sec;
+ }
+
+ @Override
+ public Principal getPeerPrincipal()
+ {
+ return _principal;
+ }
+
+ @Override
+ public int getMaxReadIdle()
+ {
+ return _maxReadIdle;
+ }
+
+ @Override
+ public int getMaxWriteIdle()
+ {
+ return _maxWriteIdle;
+ }
+
+ void setPeerPrincipal(final Principal peerPrincipal)
+ {
+ _principal = peerPrincipal;
+ }
+ }
+}
diff --git a/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketTransportProvider.java b/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketTransportProvider.java
new file mode 100644
index 0000000000..02d1100315
--- /dev/null
+++ b/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketTransportProvider.java
@@ -0,0 +1,51 @@
+/*
+ *
+ * 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.server.transport.websocket;
+
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.protocol.AmqpProtocolVersion;
+import org.apache.qpid.server.transport.AcceptingTransport;
+import org.apache.qpid.server.transport.TransportProvider;
+
+import javax.net.ssl.SSLContext;
+import java.util.Set;
+
+class WebSocketTransportProvider implements TransportProvider
+{
+ public WebSocketTransportProvider()
+ {
+ }
+
+ @Override
+ public AcceptingTransport createTransport(final Set<Transport> transports,
+ final SSLContext sslContext,
+ final Port port,
+ final Set<AmqpProtocolVersion> supported,
+ final AmqpProtocolVersion defaultSupportedProtocolReply)
+ {
+ return new WebSocketProvider(transports.iterator().next(),
+ sslContext,
+ port,
+ supported,
+ defaultSupportedProtocolReply);
+ }
+}
diff --git a/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketTransportProviderFactory.java b/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketTransportProviderFactory.java
new file mode 100644
index 0000000000..e7c5a786b5
--- /dev/null
+++ b/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketTransportProviderFactory.java
@@ -0,0 +1,56 @@
+/*
+ *
+ * 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.server.transport.websocket;
+
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.plugin.TransportProviderFactory;
+import org.apache.qpid.server.transport.TransportProvider;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Set;
+
+public class WebSocketTransportProviderFactory implements TransportProviderFactory
+{
+
+ private static final String TYPE = "Websocket";
+
+ @Override
+ public Set<Set<Transport>> getSupportedTransports()
+ {
+ return new HashSet<Set<Transport>>(Arrays.asList(EnumSet.of(Transport.WS),
+ EnumSet.of(Transport.WSS)));
+ }
+
+ @Override
+ public TransportProvider getTransportProvider(final Set<Transport> transports)
+ {
+ return new WebSocketTransportProvider();
+ }
+
+ @Override
+ public String getType()
+ {
+ return TYPE;
+ }
+}
diff --git a/qpid/java/broker-plugins/websocket/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.TransportProviderFactory b/qpid/java/broker-plugins/websocket/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.TransportProviderFactory
new file mode 100644
index 0000000000..55b88cc7be
--- /dev/null
+++ b/qpid/java/broker-plugins/websocket/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.TransportProviderFactory
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+org.apache.qpid.server.transport.websocket.WebSocketTransportProviderFactory \ No newline at end of file
diff --git a/qpid/java/build.deps b/qpid/java/build.deps
index 67a67783c9..58dea7009e 100644
--- a/qpid/java/build.deps
+++ b/qpid/java/build.deps
@@ -74,6 +74,7 @@ amqp-1-0-common.libs=
amqp-1-0-client.libs=
amqp-1-0-client-example.libs=${commons-cli}
amqp-1-0-client-jms.libs=${geronimo-jms}
+amqp-1-0-client-websocket.libs = ${jetty} ${jetty-continuation} ${jetty-security} ${jetty-http} ${jetty-io} ${jetty-servlet} ${jetty-util} ${servlet-api} ${jetty-websocket}
tools.libs=${commons-configuration.libs} ${log4j}
broker-core.libs=${commons-cli} ${commons-logging} ${log4j} ${slf4j-log4j} \
${xalan} ${derby-db} ${commons-configuration.libs} \
@@ -82,7 +83,7 @@ broker-core.libs=${commons-cli} ${commons-logging} ${log4j} ${slf4j-log4j} \
#Borrow the broker-core libs, hack for release binary generation
broker.libs=${broker-core.libs}
-broker-plugins-management-http.libs=${jetty} ${jetty-continuation} ${jetty-security} ${jetty-http} ${jetty-io} ${jetty-servlet} ${jetty-util} ${servlet-api} ${jackson-core} ${jackson-mapper} ${dojo}
+broker-plugins-management-http.libs=${dojo}
broker-plugins.libs=${log4j} ${commons-configuration.libs}
test.libs=${slf4j-log4j} ${log4j} ${junit} ${slf4j-api} ${mockito-all}
diff --git a/qpid/java/build.xml b/qpid/java/build.xml
index e761677f6d..219029b908 100644
--- a/qpid/java/build.xml
+++ b/qpid/java/build.xml
@@ -34,7 +34,7 @@
<findSubProjects name="broker-plugins" dir="broker-plugins" excludes="${broker-plugins-exclude}"/>
<findSubProjects name="client-plugins" dir="client-plugins"/>
- <property name="modules.core" value="qpid-test-utils common management/common amqp-1-0-common broker-core broker client amqp-1-0-client amqp-1-0-client-jms tools"/>
+ <property name="modules.core" value="qpid-test-utils common management/common amqp-1-0-common broker-core broker client amqp-1-0-client amqp-1-0-client-jms amqp-1-0-client-websocket tools"/>
<property name="modules.examples" value="client/example management/example amqp-1-0-client/example amqp-1-0-client-jms/example"/>
<property name="modules.tests" value="systests perftests"/>
<property name="modules.plugin" value="${broker-plugins} ${client-plugins}"/>
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
index 018a1ec851..8224c77ba9 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
@@ -109,7 +109,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
/** System property to enable failure if strict AMQP compliance is violated. */
public static final String STRICT_AMQP_FATAL = "STRICT_AMQP_FATAL";
- /** Strickt AMQP failure default. */
+ /** Strict AMQP failure default. */
public static final String STRICT_AMQP_FATAL_DEFAULT = "true";
/** System property to enable immediate message prefetching. */
@@ -124,6 +124,9 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
private final boolean _declareExchanges =
Boolean.parseBoolean(System.getProperty(ClientProperties.QPID_DECLARE_EXCHANGES_PROP_NAME, "true"));
+ private final boolean _bindQueues =
+ Boolean.parseBoolean(System.getProperty(ClientProperties.QPID_BIND_QUEUES_PROP_NAME, "true"));
+
private final boolean _useAMQPEncodedMapMessage;
private final boolean _useAMQPEncodedStreamMessage;
@@ -2870,10 +2873,13 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
declareQueue(amqd, consumer.isNoLocal(), nowait);
}
- if(!isBound(amqd.getExchangeName(), amqd.getAMQQueueName(), amqd.getRoutingKey()))
+ if (_bindQueues)
{
- bindQueue(amqd.getAMQQueueName(), amqd.getRoutingKey(),
- amqd instanceof AMQTopic ? consumer.getArguments() : null, amqd.getExchangeName(), amqd, nowait);
+ if(!isBound(amqd.getExchangeName(), amqd.getAMQQueueName(), amqd.getRoutingKey()))
+ {
+ bindQueue(amqd.getAMQQueueName(), amqd.getRoutingKey(),
+ amqd instanceof AMQTopic ? consumer.getArguments() : null, amqd.getExchangeName(), amqd, nowait);
+ }
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java
index f733e6bbca..f735895c81 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java
@@ -116,7 +116,7 @@ public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<UnprocessedMe
{
return getMessageFactory().createMessage(messageFrame.getDeliveryTag(),
- messageFrame.isRedelivered(), messageFrame.getExchange(),
+ messageFrame.isRedelivered(), messageFrame.getExchange() == null ? AMQShortString.EMPTY_STRING : messageFrame.getExchange(),
messageFrame.getRoutingKey(), messageFrame.getContentHeader(), messageFrame.getBodies(),
_queueDestinationCache, _topicDestinationCache);
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractAMQMessageDelegate.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractAMQMessageDelegate.java
index ad19b0e620..784c33cf02 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractAMQMessageDelegate.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractAMQMessageDelegate.java
@@ -60,7 +60,10 @@ public abstract class AbstractAMQMessageDelegate implements AMQMessageDelegate
_exchangeTypeToDestinationType.put(ExchangeDefaults.FANOUT_EXCHANGE_CLASS, AMQDestination.TOPIC_TYPE);
_exchangeTypeToDestinationType.put(ExchangeDefaults.HEADERS_EXCHANGE_CLASS, AMQDestination.QUEUE_TYPE);
- _exchangeMap.put("", new ExchangeInfo("","",AMQDestination.QUEUE_TYPE));
+ _exchangeMap.put(ExchangeDefaults.DEFAULT_EXCHANGE_NAME,
+ new ExchangeInfo(ExchangeDefaults.DEFAULT_EXCHANGE_NAME,
+ ExchangeDefaults.DIRECT_EXCHANGE_CLASS,
+ AMQDestination.QUEUE_TYPE));
_exchangeMap.put(ExchangeDefaults.DIRECT_EXCHANGE_NAME,
new ExchangeInfo(ExchangeDefaults.DIRECT_EXCHANGE_NAME,
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/transport/TestNetworkConnection.java b/qpid/java/client/src/test/java/org/apache/qpid/client/transport/TestNetworkConnection.java
index 1ec217e468..c9af1de6a7 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/client/transport/TestNetworkConnection.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/client/transport/TestNetworkConnection.java
@@ -75,11 +75,6 @@ public class TestNetworkConnection implements NetworkConnection
}
@Override
- public void setPeerPrincipal(Principal principal)
- {
- }
-
- @Override
public Principal getPeerPrincipal()
{
return null;
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java b/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java
index b43b9d450b..0e7d061ba7 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java
@@ -230,6 +230,12 @@ public class ClientProperties
* producer/consumer creation when using BindingURLs.
*/
public static final String QPID_DECLARE_EXCHANGES_PROP_NAME = "qpid.declare_exchanges";
+ /**
+ * System property to control whether the client will bind queues during
+ * consumer creation when using BindingURLs.
+ */
+ public static final String QPID_BIND_QUEUES_PROP_NAME = "qpid.bind_queues";
+
public static final String VERIFY_QUEUE_ON_SEND = "qpid.verify_queue_on_send";
public static final String QPID_MAX_CACHED_ADDR_OPTION_STRINGS = "qpid.max_cached_address_option_strings";
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java
index 050d194c47..1b8bbebdf5 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java
@@ -47,8 +47,6 @@ public interface NetworkConnection
void setMaxReadIdle(int sec);
- void setPeerPrincipal(Principal principal);
-
Principal getPeerPrincipal();
int getMaxReadIdle();
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java
index f5c09ac2cc..4a4bd3ddc0 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java
@@ -24,11 +24,14 @@ import java.net.Socket;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.security.Principal;
+
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSocket;
+
import org.apache.qpid.transport.Receiver;
import org.apache.qpid.transport.Sender;
import org.apache.qpid.transport.network.Ticker;
import org.apache.qpid.transport.network.NetworkConnection;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -39,15 +42,11 @@ public class IoNetworkConnection implements NetworkConnection
private final long _timeout;
private final IoSender _ioSender;
private final IoReceiver _ioReceiver;
- private Principal _principal;
private int _maxReadIdle;
private int _maxWriteIdle;
-
- public IoNetworkConnection(Socket socket, Receiver<ByteBuffer> delegate,
- int sendBufferSize, int receiveBufferSize, long timeout)
- {
- this(socket,delegate,sendBufferSize,receiveBufferSize,timeout,null);
- }
+ private Principal _principal;
+ private boolean _principalChecked;
+ private final Object _lock = new Object();
public IoNetworkConnection(Socket socket, Receiver<ByteBuffer> delegate,
int sendBufferSize, int receiveBufferSize, long timeout, Ticker ticker)
@@ -108,15 +107,29 @@ public class IoNetworkConnection implements NetworkConnection
}
@Override
- public void setPeerPrincipal(Principal principal)
- {
- _principal = principal;
- }
-
- @Override
public Principal getPeerPrincipal()
{
- return _principal;
+ synchronized (_lock)
+ {
+ if(!_principalChecked)
+ {
+ if(_socket instanceof SSLSocket)
+ {
+ try
+ {
+ _principal = ((SSLSocket) _socket).getSession().getPeerPrincipal();
+ }
+ catch(SSLPeerUnverifiedException e)
+ {
+ _principal = null;
+ }
+ }
+
+ _principalChecked = true;
+ }
+
+ return _principal;
+ }
}
@Override
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java
index 18a8bf2779..4ccb88bbf8 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java
@@ -146,7 +146,7 @@ public class IoNetworkTransport implements OutgoingNetworkTransport, IncomingNet
}
catch (IOException e)
{
- throw new TransportException("Unable to start server socket", e);
+ throw new TransportException("Failed to start AMQP on port : " + config, e);
}
}
@@ -245,19 +245,6 @@ public class IoNetworkTransport implements OutgoingNetworkTransport, IncomingNet
ticker.setConnection(connection);
- if(_sslContext != null && socket instanceof SSLSocket)
- {
- try
- {
- Principal peerPrincipal = ((SSLSocket) socket).getSession().getPeerPrincipal();
- connection.setPeerPrincipal(peerPrincipal);
- }
- catch(SSLPeerUnverifiedException e)
- {
- // ignore
- }
- }
-
engine.setNetworkConnection(connection, connection.getSender());
connection.start();
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IdleTimeoutTickerTest.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IdleTimeoutTickerTest.java
index 5cdd7a8597..a445cff0a7 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IdleTimeoutTickerTest.java
+++ b/qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IdleTimeoutTickerTest.java
@@ -233,11 +233,6 @@ public class IdleTimeoutTickerTest extends TestCase implements TransportActivity
}
@Override
- public void setPeerPrincipal(Principal principal)
- {
- }
-
- @Override
public Principal getPeerPrincipal()
{
return null;
diff --git a/qpid/java/ivy.nexus.xml b/qpid/java/ivy.nexus.xml
index d492169ff3..ee0ec27d48 100644
--- a/qpid/java/ivy.nexus.xml
+++ b/qpid/java/ivy.nexus.xml
@@ -135,6 +135,12 @@
<artifact name="qpid-amqp-1-0-client-jms" type="jar.asc" ext="jar.asc"/>
<artifact name="qpid-amqp-1-0-client-jms" type="source" ext="jar" e:classifier="sources"/>
<artifact name="qpid-amqp-1-0-client-jms" type="source.asc" ext="jar.asc" e:classifier="sources"/>
+ <artifact name="qpid-amqp-1-0-client-websocket" type="pom" ext="pom"/>
+ <artifact name="qpid-amqp-1-0-client-websocket" type="pom.asc" ext="pom.asc"/>
+ <artifact name="qpid-amqp-1-0-client-websocket" type="jar" ext="jar"/>
+ <artifact name="qpid-amqp-1-0-client-websocket" type="jar.asc" ext="jar.asc"/>
+ <artifact name="qpid-amqp-1-0-client-websocket" type="source" ext="jar" e:classifier="sources"/>
+ <artifact name="qpid-amqp-1-0-client-websocket" type="source.asc" ext="jar.asc" e:classifier="sources"/>
<artifact name="qpid-management-common" type="pom" ext="pom"/>
<artifact name="qpid-management-common" type="pom.asc" ext="pom.asc"/>
<artifact name="qpid-management-common" type="jar" ext="jar"/>
diff --git a/qpid/java/jca/README-GERONIMO.txt b/qpid/java/jca/README-GERONIMO.txt
index 3b72a7e094..504d33eab8 100644
--- a/qpid/java/jca/README-GERONIMO.txt
+++ b/qpid/java/jca/README-GERONIMO.txt
@@ -1,3 +1,21 @@
+#
+# 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.
+#
Qpid JCA Resource Adapter
Apache Geronimo 2.x Installation and Configuration Instructions
diff --git a/qpid/java/jca/README-JBOSS-EAP6.txt b/qpid/java/jca/README-JBOSS-EAP6.txt
index 219bfb6468..cd5f42d9aa 100644
--- a/qpid/java/jca/README-JBOSS-EAP6.txt
+++ b/qpid/java/jca/README-JBOSS-EAP6.txt
@@ -1,3 +1,21 @@
+#
+# 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.
+#
Qpid JCA Resource Adapter
JBoss EAP 6.x Installation and Configuration Instructions
diff --git a/qpid/java/jca/README-JBOSS.txt b/qpid/java/jca/README-JBOSS.txt
index 717565b938..80d6573b33 100644
--- a/qpid/java/jca/README-JBOSS.txt
+++ b/qpid/java/jca/README-JBOSS.txt
@@ -1,3 +1,21 @@
+#
+# 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.
+#
Qpid JCA Resource Adapter
JBoss EAP 5.x Installation and Configuration Instructions
diff --git a/qpid/java/jca/README.txt b/qpid/java/jca/README.txt
index d4c14112a4..86f548ce39 100644
--- a/qpid/java/jca/README.txt
+++ b/qpid/java/jca/README.txt
@@ -1,3 +1,21 @@
+#
+# 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.
+#
Qpid JCA Resource Adapter Installation/Configuration Instructions
Overview
diff --git a/qpid/java/jca/example/README-EXAMPLE.txt b/qpid/java/jca/example/README-EXAMPLE.txt
index fd0af585ef..7ff331116c 100644
--- a/qpid/java/jca/example/README-EXAMPLE.txt
+++ b/qpid/java/jca/example/README-EXAMPLE.txt
@@ -1,3 +1,21 @@
+#
+# 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.
+#
Qpid JCA Example
Overview
diff --git a/qpid/java/jca/example/README-GERONIMO.txt b/qpid/java/jca/example/README-GERONIMO.txt
index d58d034c79..51cf2c4e9c 100644
--- a/qpid/java/jca/example/README-GERONIMO.txt
+++ b/qpid/java/jca/example/README-GERONIMO.txt
@@ -1,3 +1,21 @@
+#
+# 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.
+#
Qpid JCA Example - Apache Geronimo 2.x
Overview
diff --git a/qpid/java/jca/example/README-GLASSFISH.txt b/qpid/java/jca/example/README-GLASSFISH.txt
index 1b73ba68fd..ccbc257c04 100644
--- a/qpid/java/jca/example/README-GLASSFISH.txt
+++ b/qpid/java/jca/example/README-GLASSFISH.txt
@@ -1,3 +1,21 @@
+#
+# 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.
+#
Qpid JCA Example - Glassfish 3.x
Overview
diff --git a/qpid/java/jca/example/README-JBOSS.txt b/qpid/java/jca/example/README-JBOSS.txt
index e23b3ba308..ffc750a078 100644
--- a/qpid/java/jca/example/README-JBOSS.txt
+++ b/qpid/java/jca/example/README-JBOSS.txt
@@ -1,3 +1,21 @@
+#
+# 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.
+#
Qpid JCA Example - JBoss EAP 5.x, JBoss 5.x, 6.x
Overview
diff --git a/qpid/java/jca/example/README-JBOSS7.txt b/qpid/java/jca/example/README-JBOSS7.txt
index 5234a0b293..ae12078cd0 100644
--- a/qpid/java/jca/example/README-JBOSS7.txt
+++ b/qpid/java/jca/example/README-JBOSS7.txt
@@ -1,3 +1,21 @@
+#
+# 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.
+#
Qpid JCA Example - JBoss AS 7
Overview
diff --git a/qpid/java/jca/example/conf/glassfish-ejb-jar.xml b/qpid/java/jca/example/conf/glassfish-ejb-jar.xml
index e3ea140472..3416e2b4ae 100644
--- a/qpid/java/jca/example/conf/glassfish-ejb-jar.xml
+++ b/qpid/java/jca/example/conf/glassfish-ejb-jar.xml
@@ -1,4 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - 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.
+ -
+ -->
<!DOCTYPE glassfish-ejb-jar PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 EJB 3.1//EN" "http://glassfish.org/dtds/glassfish-ejb-jar_3_1-1.dtd">
<glassfish-ejb-jar>
<enterprise-beans>
diff --git a/qpid/java/jca/example/conf/glassfish-resources.xml b/qpid/java/jca/example/conf/glassfish-resources.xml
index 9eab4302d5..ce1fc5b764 100644
--- a/qpid/java/jca/example/conf/glassfish-resources.xml
+++ b/qpid/java/jca/example/conf/glassfish-resources.xml
@@ -1,4 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - 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.
+ -
+ -->
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
diff --git a/qpid/java/jca/example/conf/glassfish-web.xml b/qpid/java/jca/example/conf/glassfish-web.xml
index 950ee73d51..3aa49c01b1 100644
--- a/qpid/java/jca/example/conf/glassfish-web.xml
+++ b/qpid/java/jca/example/conf/glassfish-web.xml
@@ -1,4 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - 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.
+ -
+ -->
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app>
diff --git a/qpid/java/module.xml b/qpid/java/module.xml
index 28c31f967d..6d3f08a386 100644
--- a/qpid/java/module.xml
+++ b/qpid/java/module.xml
@@ -584,8 +584,8 @@
<copylist todir="${build.lib}" dir="${project.root}" files="${module.libs}"/>
</target>
-
- <target name="libs-release" description="copy dependencies into module release">
+
+ <target name="libs-release-basic" description="copy dependencies into module release">
<!-- Copy the module dependencies -->
<echo message="${module.libs}"/>
<copylist todir="${module.release}/lib" dir="${project.root}" files="${module.libs}"/>
@@ -594,10 +594,18 @@
<!-- Copy the jar for this module -->
<copy todir="${module.release}/lib" failonerror="true">
<fileset file="${module.jar}"/>
+ </copy>
+ </target>
+
+ <target name="libs-release-module-depends" description="copy dependencies into module release" unless="release.exclude.module.deps">
+ <copy todir="${module.release}/lib" failonerror="true">
<fileset dir="${build.lib}" includes="${module.depends.jars}"/>
</copy>
</target>
+ <target name="libs-release" description="copy dependencies into module release" depends="libs-release-basic,libs-release-module-depends">
+ </target>
+
<target name="resources" description="copy resources into build tree">
<copy todir="${build}" failonerror="false" flatten="true">
<fileset dir="${basedir}${file.separator}.." includes="${resources}"/>
diff --git a/qpid/java/pom.xml b/qpid/java/pom.xml
index 7ea1db66aa..1b313b3514 100644
--- a/qpid/java/pom.xml
+++ b/qpid/java/pom.xml
@@ -29,22 +29,24 @@
<packaging>pom</packaging>
<!-- ###### TODO ######
-
+ - Fix the jca/rar pom module name, it should be qpid-ra not qpid-rar.
+ - Add the Excludes files, log4j config, etc test resources to a module (qpid-test-utils?) which can be
+ used (extracted?) by the others to prevent them having to reference outside their directly for the files.
+ - Fix what the systests/perftests do to copy the test-profiles dir to the necessary location.
+ - Fix the log4j configuration property to work with all the modules, resolve the currently generated log4j exceptions during test runs.
- Add project details such as Website, Mailing List, SCM.
- - Test deploying the modules to a local Nexus instance (overriding the repo properties).
- - Dont deploy modules we aren't already doing so.
- - Decide on name for this parent module.
- Fix the version numbers in all the modules.
- - Align the XML in the pom files consistently, fix whitepsace errors.
- - Complete setting properties for the dependency version numbers.
- - Use dependancy management sections to control the version numbers.
- - Add LICENCE, NOTICE, README files to the binary assemblies.
- - Add the test profiles, log4j config etc to a module which can be extracted by the others.
- - Then fix log4j configuration property to work with all modules.
- - Then fix what the systests/perftests do to copy the test-profiles dir to the encessary location.
+ - Decide on a final name for this parent module, qpid-project isnt necessarily appropriate given it doesnt encompass the whole project.
+ - Test deploying the modules to a local Nexus instance (by overriding the repo properties locally).
+ - Ensure we dont deploy modules we aren't already doing so, it will make changing them later less of a pain for everyone.
- Figure out dependency setup for optional bdbstore tests.
- - Add the other test profiles
+ - Add the other test profiles, e.g. derby and other protocols.
- Generate HTML reports of the test results
+ - Decide on how to handle the surefire report target re-running the tests (there is a report-only task that doesnt, provided as a workaround)
+ - Add LICENCE, NOTICE, README files to the binary assemblies.
+ - Complete setting properties for all the dependency version numbers from the modules.
+ - Use dependancy management sections to control the version numbers?
+ - Align the XML in the pom files consistently, fix whitepsace errors.
=== Once the Ant build is removed ===
- Move all the resources to be in the /src/foo/resources folders.
@@ -55,6 +57,7 @@
- Fix the tests not to be dependant on the working dir being the java dir.
- Fix the tests not to be dependant on the test config/output dirs being children of qpid.home.
- Remove the QBTC output file mechanics, rely on Surefire to do it?
+ - JUnit test profiles instead of Exludes files?
-->
<properties>
@@ -134,6 +137,7 @@
<modules>
<module>amqp-1-0-client</module>
<module>amqp-1-0-client-jms</module>
+ <module>amqp-1-0-client-websocket</module>
<module>amqp-1-0-common</module>
<module>broker</module>
<module>broker-core</module>
@@ -150,6 +154,7 @@
<module>broker-plugins/management-http</module>
<module>broker-plugins/management-jmx</module>
<module>broker-plugins/memory-store</module>
+ <module>broker-plugins/websocket</module>
<module>common</module>
<module>client</module>
<module>management/common</module>
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java
index c999be634b..099e011054 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java
@@ -254,11 +254,6 @@ public class MultiVersionProtocolEngineFactoryTest extends QpidTestCase
}
@Override
- public void setPeerPrincipal(Principal principal)
- {
- }
-
- @Override
public Principal getPeerPrincipal()
{
return null;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MessageGroupQueueTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MessageGroupQueueTest.java
index d5cee17fa8..cb8ced4ddb 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MessageGroupQueueTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MessageGroupQueueTest.java
@@ -20,22 +20,28 @@
*/
package org.apache.qpid.server.queue;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQDestination;
-import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
-import java.util.HashMap;
-import java.util.Map;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQDestination;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
public class MessageGroupQueueTest extends QpidBrokerTestCase
{
@@ -469,7 +475,6 @@ public class MessageGroupQueueTest extends QpidBrokerTestCase
}
-
private Message createMessage(int msg, String group) throws JMSException
{
Message send = producerSession.createTextMessage("Message: " + msg);
@@ -478,4 +483,122 @@ public class MessageGroupQueueTest extends QpidBrokerTestCase
return send;
}
+
+ /**
+ * Tests that when a number of new messages for a given groupid are arriving while the delivery group
+ * state is also in the process of being emptied (due to acking a message while using prefetch=1), that only
+ * 1 of a number of existing consumers is ever receiving messages for the shared group at a time.
+ */
+ public void testSingleSharedGroupWithMultipleConsumers() throws Exception
+ {
+ final Map<String,Object> arguments = new HashMap<String, Object>();
+ arguments.put(QueueArgumentsConverter.QPID_GROUP_HEADER_KEY,"group");
+ arguments.put(QueueArgumentsConverter.QPID_SHARED_MSG_GROUP,"1");
+
+ ((AMQSession) producerSession).createQueue(new AMQShortString(QUEUE), true, false, false, arguments);
+ queue = (Queue) producerSession.createQueue("direct://amq.direct/"+QUEUE+"/"+QUEUE+"?durable='false'&autodelete='true'");
+
+ ((AMQSession) producerSession).declareAndBind((AMQDestination)queue);
+ producer = producerSession.createProducer(queue);
+
+
+ consumerConnection.close();
+ Map<String, String> options = new HashMap<String, String>();
+ options.put(ConnectionURL.OPTIONS_MAXPREFETCH, "1");
+ consumerConnection = getConnectionWithOptions(options);
+
+ int numMessages = 100;
+ SharedGroupTestMessageListener groupingTestMessageListener = new SharedGroupTestMessageListener(numMessages);
+
+ Session cs1 = ((AMQConnection)consumerConnection).createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Session cs2 = ((AMQConnection)consumerConnection).createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Session cs3 = ((AMQConnection)consumerConnection).createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Session cs4 = ((AMQConnection)consumerConnection).createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer consumer1 = cs1.createConsumer(queue);
+ consumer1.setMessageListener(groupingTestMessageListener);
+ MessageConsumer consumer2 = cs2.createConsumer(queue);
+ consumer2.setMessageListener(groupingTestMessageListener);
+ MessageConsumer consumer3 = cs3.createConsumer(queue);
+ consumer3.setMessageListener(groupingTestMessageListener);
+ MessageConsumer consumer4 = cs4.createConsumer(queue);
+ consumer4.setMessageListener(groupingTestMessageListener);
+ consumerConnection.start();
+
+ for(int i = 1; i <= numMessages; i++)
+ {
+ producer.send(createMessage(i, "GROUP"));
+ }
+ producerSession.commit();
+ producer.close();
+ producerSession.close();
+ producerConnection.close();
+
+ assertTrue("Mesages not all recieved in the allowed timeframe", groupingTestMessageListener.waitForLatch(30));
+ assertEquals("Unexpected concurrent processing of messages for the group", 0, groupingTestMessageListener.getConcurrentProcessingCases());
+ assertNull("Unexpecte throwable in message listeners", groupingTestMessageListener.getThrowable());
+ }
+
+ public static class SharedGroupTestMessageListener implements MessageListener
+ {
+ private final CountDownLatch _count;
+ private final AtomicInteger _activeListeners = new AtomicInteger();
+ private final AtomicInteger _concurrentProcessingCases = new AtomicInteger();
+ private Throwable _throwable;
+
+ public SharedGroupTestMessageListener(int numMessages)
+ {
+ _count = new CountDownLatch(numMessages);
+ }
+
+ public void onMessage(Message message)
+ {
+ try
+ {
+ int currentActiveListeners = _activeListeners.incrementAndGet();
+
+ if (currentActiveListeners > 1)
+ {
+ _concurrentProcessingCases.incrementAndGet();
+
+ System.err.println("Concurrent processing when handling message: " + message.getIntProperty("msg"));
+ }
+
+ try
+ {
+ Thread.sleep(25);
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+
+ _activeListeners.decrementAndGet();
+ }
+ catch (Throwable t)
+ {
+ _throwable = t;
+ t.printStackTrace();
+ }
+ finally
+ {
+ _count.countDown();
+ }
+ }
+
+ public boolean waitForLatch(int seconds) throws Exception
+ {
+ return _count.await(seconds, TimeUnit.SECONDS);
+ }
+
+ public int getConcurrentProcessingCases()
+ {
+ return _concurrentProcessingCases.get();
+ }
+
+ public Throwable getThrowable()
+ {
+ return _throwable;
+ }
+ }
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ExchangeManagementTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ExchangeManagementTest.java
index 594239b2ee..8c0a11b7cc 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ExchangeManagementTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ExchangeManagementTest.java
@@ -1,3 +1,23 @@
+/*
+ *
+ * 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.systest.management.jmx;
import java.util.Collections;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java
index 1294c30612..cd9f6e721b 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java
@@ -41,6 +41,7 @@ import org.apache.qpid.server.model.Protocol;
import org.apache.qpid.server.model.Queue;
import org.apache.qpid.server.model.State;
import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
public class Asserts
{
@@ -126,7 +127,7 @@ public class Asserts
Queue.DISCARDS_TTL_MESSAGES, Queue.STATE_CHANGED);
}
- public static void assertAttributesPresent(Map<String, Object> data, String[] attributes)
+ public static void assertAttributesPresent(Map<String, Object> data, String... attributes)
{
for (String name : attributes)
{
@@ -164,6 +165,8 @@ public class Asserts
Connection.INCOMING, Connection.REMOTE_PROCESS_NAME, Connection.REMOTE_PROCESS_PID,
Connection.LOCAL_ADDRESS, Connection.PROPERTIES);
+ assertEquals("Unexpected value for connection attribute " + Connection.PORT,
+ TestBrokerConfiguration.ENTRY_NAME_AMQP_PORT, connectionData.get(Connection.PORT));
assertEquals("Unexpected value of connection attribute " + Connection.SESSION_COUNT_LIMIT,
(int) connection.getMaximumChannelCount(), connectionData.get(Connection.SESSION_COUNT_LIMIT));
assertEquals("Unexpected value of connection attribute " + Connection.CLIENT_ID, "clientid",
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestHttpsClientCertAuthTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestHttpsClientCertAuthTest.java
new file mode 100644
index 0000000000..e92b38b4e0
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestHttpsClientCertAuthTest.java
@@ -0,0 +1,89 @@
+/*
+ *
+ * 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.systest.rest;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManagerFactory;
+import org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManagerFactory;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE_PASSWORD;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE_PASSWORD;
+
+public class BrokerRestHttpsClientCertAuthTest extends QpidRestTestCase
+{
+
+ @Override
+ public void setUp() throws Exception
+ {
+ setSystemProperty("javax.net.debug", "ssl");
+ super.setUp();
+ setSystemProperty("javax.net.ssl.trustStore", TRUSTSTORE);
+ setSystemProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE_PASSWORD);
+ setSystemProperty("javax.net.ssl.keystore", KEYSTORE);
+ setSystemProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASSWORD);
+
+ }
+
+ @Override
+ protected void customizeConfiguration() throws ConfigurationException, IOException
+ {
+ super.customizeConfiguration();
+ getRestTestHelper().setUseSslAuth(true);
+ Map<String, Object> newAttributes = new HashMap<String, Object>();
+ newAttributes.put(Port.PROTOCOLS, Collections.singleton(Protocol.HTTP));
+ newAttributes.put(Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+ newAttributes.put(Port.KEY_STORE, TestBrokerConfiguration.ENTRY_NAME_SSL_KEYSTORE);
+ newAttributes.put(Port.TRUST_STORES, Collections.singleton(TestBrokerConfiguration.ENTRY_NAME_SSL_TRUSTSTORE));
+ newAttributes.put(Port.NEED_CLIENT_AUTH,"true");
+
+
+ Map<String, Object> externalProviderAttributes = new HashMap<String, Object>();
+ externalProviderAttributes.put(AuthenticationProvider.TYPE, ExternalAuthenticationManagerFactory.PROVIDER_TYPE);
+ externalProviderAttributes.put(AuthenticationProvider.NAME, EXTERNAL_AUTHENTICATION_PROVIDER);
+ getBrokerConfiguration().addAuthenticationProviderConfiguration(externalProviderAttributes);
+
+ // set password authentication provider on http port for the tests
+ getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT, Port.AUTHENTICATION_PROVIDER,
+ EXTERNAL_AUTHENTICATION_PROVIDER);
+
+ getBrokerConfiguration().setObjectAttributes(TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT, newAttributes);
+ }
+
+ public void testGetWithHttps() throws Exception
+ {
+ Map<String, Object> saslData = getRestTestHelper().getJsonAsMap("/rest/sasl");
+
+ Asserts.assertAttributesPresent(saslData, "user");
+ }
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/PreferencesRestTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/PreferencesRestTest.java
index bf2044aa74..46acd9e77b 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/PreferencesRestTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/PreferencesRestTest.java
@@ -1,3 +1,23 @@
+/*
+ *
+ * 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.systest.rest;
import java.io.File;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java
index 57398ea929..ce501adeb6 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java
@@ -35,6 +35,8 @@ import org.apache.qpid.test.utils.QpidBrokerTestCase;
public class QpidRestTestCase extends QpidBrokerTestCase
{
public static final String ANONYMOUS_AUTHENTICATION_PROVIDER = "testAnonymous";
+ public static final String EXTERNAL_AUTHENTICATION_PROVIDER = "testExternal";
+
public static final String TEST1_VIRTUALHOST = "test";
public static final String TEST2_VIRTUALHOST = "test2";
public static final String TEST3_VIRTUALHOST = "test3";
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java
index 7d99b30049..810b70a2ba 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java
@@ -18,6 +18,8 @@
*/
package org.apache.qpid.systest.rest;
+import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE_PASSWORD;
import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE;
import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE_PASSWORD;
@@ -41,6 +43,7 @@ import java.util.List;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
@@ -65,16 +68,19 @@ import org.codehaus.jackson.type.TypeReference;
public class RestTestHelper
{
private static final Logger LOGGER = Logger.getLogger(RestTestHelper.class);
+ private static final String CERT_ALIAS_APP1 = "app1";
private int _httpPort;
private boolean _useSsl;
+
private String _username;
private String _password;
private File _passwdFile;
+ private boolean _useSslAuth;
public RestTestHelper(int httpPort)
{
@@ -110,7 +116,30 @@ public class RestTestHelper
{
URL url = getManagementURL(path);
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
- if(_useSsl)
+
+ if(_useSslAuth)
+ {
+ try
+ {
+ // We have to use a SSLSocketFactory from a new SSLContext so that we don't re-use
+ // the JVM's defaults that may have been initialised in previous tests.
+
+ SSLContext sslContext = SSLContextFactory.buildClientContext(
+ TRUSTSTORE, TRUSTSTORE_PASSWORD,
+ KeyStore.getDefaultType(),
+ TrustManagerFactory.getDefaultAlgorithm(),
+ KEYSTORE, KEYSTORE_PASSWORD, KeyStore.getDefaultType(), KeyManagerFactory.getDefaultAlgorithm(), CERT_ALIAS_APP1);
+
+ SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
+
+ ((HttpsURLConnection) httpCon).setSSLSocketFactory(sslSocketFactory);
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ else if(_useSsl)
{
try
{
@@ -475,4 +504,10 @@ public class RestTestHelper
connection.connect();
return readConnectionInputStream(connection);
}
+
+ public void setUseSslAuth(final boolean useSslAuth)
+ {
+ _useSslAuth = useSslAuth;
+ _useSsl = true;
+ }
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java
index 1c05f17e25..61f4a1a8e2 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java
@@ -55,6 +55,8 @@ public class SaslRestTest extends QpidRestTestCase
public void startBrokerNow() throws Exception
{
super.startBroker();
+
+ getRestTestHelper().setUsernameAndPassword(null,null);
}
public void testGetMechanismsWithBrokerPlainPasswordPrincipalDatabase() throws Exception
@@ -71,7 +73,7 @@ public class SaslRestTest extends QpidRestTestCase
{
assertTrue("Mechanism " + mechanism + " is not found", mechanisms.contains(mechanism));
}
- assertNull("Unexpected user was returned", saslData.get("user"));
+ assertNull("Unexpected user was returned: " + saslData.get("user"), saslData.get("user"));
}
public void testGetMechanismsWithBrokerBase64MD5FilePrincipalDatabase() throws Exception
@@ -89,7 +91,8 @@ public class SaslRestTest extends QpidRestTestCase
{
assertTrue("Mechanism " + mechanism + " is not found", mechanisms.contains(mechanism));
}
- assertNull("Unexpected user was returned", saslData.get("user"));
+
+ assertNull("Unexpected user was returned: " + saslData.get("user"), saslData.get("user"));
}
public void testPlainSaslAuthenticationForValidCredentials() throws Exception
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/JMSDestinationTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/JMSDestinationTest.java
index 1ee5b997f2..760884e654 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/JMSDestinationTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/JMSDestinationTest.java
@@ -20,18 +20,17 @@
*/
package org.apache.qpid.test.client.message;
-import org.apache.qpid.client.AMQAnyDestination;
import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.client.AMQTopic;
import org.apache.qpid.client.CustomJMSXProperty;
import org.apache.qpid.configuration.ClientProperties;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.management.common.mbeans.ManagedQueue;
import org.apache.qpid.test.utils.JMXTestUtils;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
import javax.jms.Connection;
import javax.jms.Destination;
+import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
@@ -41,7 +40,7 @@ import javax.jms.Session;
import javax.jms.Topic;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.TabularData;
-import java.nio.BufferOverflowException;
+
import java.util.Iterator;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -88,15 +87,15 @@ public class JMSDestinationTest extends QpidBrokerTestCase
_connection.start();
- Message message = consumer.receive(10000);
+ Message receivedMessage = consumer.receive(10000);
- assertNotNull("Message should not be null", message);
+ assertNotNull("Message should not be null", receivedMessage);
- Destination destination = message.getJMSDestination();
+ Destination receivedDestination = receivedMessage.getJMSDestination();
- assertNotNull("JMSDestination should not be null", destination);
+ assertNotNull("JMSDestination should not be null", receivedDestination);
- assertEquals("Incorrect Destination type", queue.getClass(), destination.getClass());
+ assertEquals("Incorrect Destination type", queue.getClass(), receivedDestination.getClass());
}
/**
@@ -115,15 +114,14 @@ public class JMSDestinationTest extends QpidBrokerTestCase
_connection.start();
- Message message = consumer.receive(10000);
-
- assertNotNull("Message should not be null", message);
+ Message receivedMessage = consumer.receive(10000);
- Destination destination = message.getJMSDestination();
+ assertNotNull("Message should not be null", receivedMessage);
- assertNotNull("JMSDestination should not be null", destination);
+ Destination receivedDestination = receivedMessage.getJMSDestination();
- assertEquals("Incorrect Destination type", topic.getClass(), destination.getClass());
+ assertNotNull("JMSDestination should not be null", receivedDestination);
+ assertEquals("Incorrect Destination type", topic.getClass(), receivedDestination.getClass());
}
/**
@@ -191,11 +189,11 @@ public class JMSDestinationTest extends QpidBrokerTestCase
assertNotNull("Message should not be null", message);
- Destination destination = message.getJMSDestination();
+ Destination receivedDestination = message.getJMSDestination();
- assertNotNull("JMSDestination should not be null", destination);
+ assertNotNull("JMSDestination should not be null", receivedDestination);
- assertEquals("Incorrect Destination type", queue.getClass(), destination.getClass());
+ assertEquals("Incorrect Destination type", queue.getClass(), receivedDestination.getClass());
}
finally
@@ -238,11 +236,11 @@ public class JMSDestinationTest extends QpidBrokerTestCase
assertNotNull("Message should not be null", _message);
- Destination destination = _message.getJMSDestination();
+ Destination receivedDestination = _message.getJMSDestination();
- assertNotNull("JMSDestination should not be null", destination);
+ assertNotNull("JMSDestination should not be null", receivedDestination);
- assertEquals("Incorrect Destination type", queue.getClass(), destination.getClass());
+ assertEquals("Incorrect Destination type", queue.getClass(), receivedDestination.getClass());
}
/**
@@ -305,17 +303,7 @@ public class JMSDestinationTest extends QpidBrokerTestCase
// b) we can actually send without a BufferOverFlow.
MessageProducer producer = session08.createProducer(queue);
-
- try
- {
- producer.send(message);
- }
- catch (BufferOverflowException bofe)
- {
- // Print the stack trace so we can validate where the execption occured.
- bofe.printStackTrace();
- fail("BufferOverflowException thrown during send");
- }
+ producer.send(message);
message = consumer.receive(1000);
@@ -327,45 +315,45 @@ public class JMSDestinationTest extends QpidBrokerTestCase
}
- /**
- * Send a message to a custom exchange and then verify
- * the message received has the proper destination set
- *
- * @throws Exception
- */
- public void testGetDestinationWithCustomExchange() throws Exception
+ public void testQueueWithBindingUrlUsingCustomExchange() throws Exception
{
-
- AMQDestination dest = new AMQAnyDestination(new AMQShortString("my-exchange"),
- new AMQShortString("direct"),
- new AMQShortString("test"),
- false,
- false,
- new AMQShortString("test"),
- false,
- new AMQShortString[]{new AMQShortString("test")});
-
- // to force the creation of my-exchange.
- sendMessage(_session, dest, 1);
-
- MessageProducer prod = _session.createProducer(dest);
+ String exchangeName = "exch_" + getTestQueueName();
+ String queueName = "queue_" + getTestQueueName();
+ String address = String.format("direct://%s/%s/%s?routingkey='%s'", exchangeName, queueName, queueName, queueName);
+ sendReceive(address);
+ }
+
+ public void testQueueWithBindingUrlUsingAmqDirectExchange() throws Exception
+ {
+ String queueName = getTestQueueName();
+ String address = String.format("direct://amq.direct/%s/%s?routingkey='%s'", queueName, queueName, queueName);
+ sendReceive(address);
+ }
+
+ public void testQueueWithBindingUrlUsingDefaultExchange() throws Exception
+ {
+ String queueName = getTestQueueName();
+ String address = String.format("direct:///%s/%s?routingkey='%s'", queueName, queueName, queueName);
+ sendReceive(address);
+ }
+
+ private void sendReceive(String address) throws JMSException, Exception
+ {
+ Destination dest = _session.createQueue(address);
MessageConsumer consumer = _session.createConsumer(dest);
-
+
_connection.start();
sendMessage(_session, dest, 1);
-
- Message message = consumer.receive(10000);
- assertNotNull("Message should not be null", message);
+ Message receivedMessage = consumer.receive(10000);
- Destination destination = message.getJMSDestination();
+ assertNotNull("Message should not be null", receivedMessage);
- assertNotNull("JMSDestination should not be null", destination);
+ Destination receivedDestination = receivedMessage.getJMSDestination();
- assertEquals("Incorrect Destination name", "my-exchange", dest.getExchangeName().asString());
- assertEquals("Incorrect Destination type", "direct", dest.getExchangeClass().asString());
- assertEquals("Incorrect Routing Key", "test", dest.getRoutingKey().asString());
+ assertNotNull("JMSDestination should not be null", receivedDestination);
+ assertEquals("JMSDestination should match that sent", address, receivedDestination.toString());
}
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java
index 734e3f2268..77df6c58d9 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java
@@ -31,6 +31,7 @@ import org.apache.qpid.test.utils.QpidBrokerTestCase;
import org.apache.qpid.url.BindingURL;
import javax.jms.Connection;
+import javax.jms.InvalidDestinationException;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.Session;
@@ -158,6 +159,28 @@ public class DynamicQueueExchangeCreateTest extends QpidBrokerTestCase
assertFalse("exchange should not exist", _jmxUtils.doesManagedObjectExist(exchangeObjectName2));
}
+ public void testQueueNotBoundDuringConsumerCreation() throws Exception
+ {
+ setSystemProperty(ClientProperties.QPID_BIND_QUEUES_PROP_NAME, "false");
+ setSystemProperty(ClientProperties.VERIFY_QUEUE_ON_SEND, "true");
+
+ Connection connection = getConnection();
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ Queue queue = session.createQueue(getTestQueueName());
+ session.createConsumer(queue);
+
+ try
+ {
+ session.createProducer(queue).send(session.createMessage());
+ fail("JMSException should be thrown as the queue does not exist");
+ }
+ catch (InvalidDestinationException ide)
+ {
+ //PASS
+ }
+ }
private void checkExceptionErrorCode(JMSException original, AMQConstant code)
{
Exception linked = original.getLinkedException();
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java
index e893a58282..3ffa73b9b7 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java
@@ -154,11 +154,6 @@ public class AMQProtocolSessionTest extends QpidBrokerTestCase
}
@Override
- public void setPeerPrincipal(Principal principal)
- {
- }
-
- @Override
public Principal getPeerPrincipal()
{
return null;