summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Godfrey <rgodfrey@apache.org>2012-03-01 15:42:44 +0000
committerRobert Godfrey <rgodfrey@apache.org>2012-03-01 15:42:44 +0000
commite78f6a9e59098ac104892a79b74c9895272b292e (patch)
tree56d1765b5470746a864b7ab9f26460e477f48e8f
parent252f863d8ffc90d958daec6040a886f9ff44861c (diff)
downloadqpid-python-e78f6a9e59098ac104892a79b74c9895272b292e.tar.gz
NO-JIRA: [AMQP 1-0 Sandbox] merging from trunk
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/rg-amqp-1-0-sandbox@1295627 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/java/bdbstore/build.xml2
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java697
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StringMapBinding.java61
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/UUIDTupleBinding.java50
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/QueueEntryTB.java2
-rw-r--r--qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreTest.java107
-rw-r--r--qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBUpgradeTest.java32
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java9
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java17
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java9
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java67
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java35
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java9
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java14
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java17
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java202
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java65
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/ExtractResendAndRequeue.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java69
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMap.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java8
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java19
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java107
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java62
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java10
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherDFAState.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java137
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java199
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/flow/AbstractFlowCreditManager.java13
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java1
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseHandler.java1
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelFlowHandler.java1
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseMethodHandler.java1
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java1
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java13
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java14
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java11
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java13
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java33
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessage.java27
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/message/AbstractServerMessageImpl.java29
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/message/EnqueableMessage.java5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/message/InboundMessage.java2
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageContentSource.java1
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java2
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_0_10.java105
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java35
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferMessage.java56
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/message/ServerMessage.java14
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/output/HeaderPropertiesConverter.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_8/ProtocolOutputConverterImpl.java840
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9/ProtocolOutputConverterImpl.java837
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9_1/ProtocolOutputConverterImpl.java837
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java63
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java11
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java32
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLink_1_0.java13
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/TxnCoordinatorLink_1_0.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java10
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/BaseQueue.java1
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java2
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java30
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/OutOfOrderQueue.java10
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java36
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java17
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryList.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java17
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java241
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SortedQueueEntryList.java11
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/queue/SubFlushRunner.java23
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java13
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java159
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java68
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java17
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java603
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java10
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java30
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java69
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/store/StorableMessageMetaData.java2
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/store/StoredMemoryMessage.java83
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/store/StoredMessage.java4
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/store/TransactionLog.java65
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/store/TransactionLogRecoveryHandler.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java150
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java270
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/MessageGroupManager.java (renamed from qpid/java/client/src/main/java/org/apache/qpid/filter/Expression.java)40
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java140
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java13
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java253
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java59
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java61
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java40
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java11
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java6
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java91
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java80
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java41
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java5
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java13
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java60
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/CurrentActorTest.java48
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java18
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java133
-rwxr-xr-xqpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockStoredMessage.java13
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryListTestBase.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java4
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java4
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SortedQueueEntryListTest.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java8
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/store/SkeletonMessageStore.java88
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestMemoryMessageStore.java6
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestableMemoryMessageStore.java16
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/txn/AutoCommitTransactionTest.java12
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/txn/LocalTransactionTest.java12
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java16
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java41
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java11
-rw-r--r--qpid/java/broker/src/xsl/qmf.xsl16
-rw-r--r--qpid/java/build.deps2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java30
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java71
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java77
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java16
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java10
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java21
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/filter/JMSSelectorFilter.java209
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/filter/MessageFilter.java (renamed from qpid/java/client/src/main/java/org/apache/qpid/filter/MessageFilter.java)2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java5
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java4
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_8.java82
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java15
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java52
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactory.java5
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java17
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java229
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/filter/ArithmeticExpression.java268
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/filter/BinaryExpression.java103
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/filter/ComparisonExpression.java589
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/filter/ConstantExpression.java204
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/filter/JMSSelectorFilter.java70
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/filter/LogicExpression.java108
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java300
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/filter/UnaryExpression.java321
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/nclient/util/MessagePartListenerAdapter.java16
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/AMQSession_0_10Test.java8
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/BasicMessageConsumer_0_8_Test.java15
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/filter/JMSSelectorFilterTest.java108
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java11
-rw-r--r--qpid/java/common.xml26
-rw-r--r--qpid/java/common/Composite.tpl5
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/codec/AMQDecoder.java53
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/codec/MarkableDataInput.java21
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQBody.java3
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlock.java3
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlockDecoder.java5
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQFrame.java17
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBody.java5
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyFactory.java4
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyImpl.java62
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyInstanceFactory.java5
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java147
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQType.java102
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQTypedValue.java230
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java204
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/BodyFactory.java5
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/ByteArrayDataInput.java174
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/CompositeAMQDataBlock.java4
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java65
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/ContentBodyFactory.java4
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java7
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBodyFactory.java4
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderProperties.java7
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java3
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java108
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/ExtendedDataInput.java14
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java128
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java3
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBody.java4
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBodyFactory.java5
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java13
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/SmallCompositeAMQDataBlock.java4
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/VersionSpecificRegistry.java3
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/pool/ReadWriteJobQueue.java432
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/pool/ReadWriteRunnable.java26
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/pool/ReferenceCountingExecutorService.java24
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java21
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/Header.java103
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/Range.java257
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/RangeSet.java140
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/RangeSetFactory.java (renamed from qpid/java/client/src/main/java/org/apache/qpid/filter/BooleanExpression.java)31
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/RangeSetImpl.java178
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/Session.java101
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java31
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractDecoder.java30
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/codec/BBEncoder.java10
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/Assembler.java35
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/Disassembler.java53
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/util/ByteBufferInputStream.java (renamed from qpid/java/broker/src/main/java/org/apache/qpid/server/util/ByteBufferInputStream.java)18
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java40
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/transport/RangeSetTest.java40
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/util/ByteBufferInputStreamTest.java111
-rw-r--r--qpid/java/common/templates/method/version/MethodBodyClass.vm11
-rw-r--r--qpid/java/common/templates/model/MethodRegistryClass.vm4
-rw-r--r--qpid/java/common/templates/model/version/MethodRegistryClass.vm4
-rw-r--r--qpid/java/jca/example/qpid-jca-example-properties.xml12
-rw-r--r--qpid/java/jca/src/main/java/org/apache/qpid/ra/QpidRAManagedConnection.java45
-rw-r--r--qpid/java/jca/src/main/java/org/apache/qpid/ra/QpidRAMessage.java2
-rw-r--r--qpid/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionImpl.java9
-rw-r--r--qpid/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidActivation.java17
-rw-r--r--qpid/java/lib/cobertura/README.txt9
-rw-r--r--qpid/java/lib/poms/je-4.0.117.xml22
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/client/prefetch/PrefetchBehaviourTest.java39
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MessageGroupQueueTest.java481
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/queue/ProducerFlowControlTest.java23
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java67
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/ObjectMessageTest.java17
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/client/queue/QueuePolicyTest.java19
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java79
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactedTest.java66
-rwxr-xr-xqpid/java/test-profiles/CPPExcludes6
-rwxr-xr-xqpid/java/test-profiles/Java010Excludes3
236 files changed, 8861 insertions, 6582 deletions
diff --git a/qpid/java/bdbstore/build.xml b/qpid/java/bdbstore/build.xml
index 9513e7cc5b..af7c108aa9 100644
--- a/qpid/java/bdbstore/build.xml
+++ b/qpid/java/bdbstore/build.xml
@@ -24,7 +24,7 @@
<import file="../module.xml" />
<property name="bdb.lib.dir" value="${project.root}/lib/bdbstore" />
- <property name="bdb.version" value="4.0.117" />
+ <property name="bdb.version" value="5.0.34" />
<property name="bdb.download.url" value="http://download.oracle.com/maven/com/sleepycat/je/${bdb.version}/je-${bdb.version}.jar" />
<property name="bdb.jar.file" value="${bdb.lib.dir}/je-${bdb.version}.jar" />
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 f900159808..2e2d2f0b11 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
@@ -22,27 +22,37 @@ package org.apache.qpid.server.store.berkeleydb;
import java.io.File;
import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Queue;
+import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
+import com.sleepycat.bind.tuple.LongBinding;
+import com.sleepycat.bind.tuple.StringBinding;
+import com.sleepycat.je.*;
import org.apache.commons.configuration.Configuration;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQStoreException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.federation.Bridge;
+import org.apache.qpid.server.federation.BrokerLink;
import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.messages.ConfigStoreMessages;
import org.apache.qpid.server.logging.messages.MessageStoreMessages;
import org.apache.qpid.server.logging.messages.TransactionLogMessages;
+import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.store.ConfigurationRecoveryHandler;
import org.apache.qpid.server.store.DurableConfigurationStore;
@@ -70,17 +80,6 @@ import org.apache.qpid.server.store.berkeleydb.tuples.QueueTupleBindingFactory;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.tuple.ByteBinding;
import com.sleepycat.bind.tuple.TupleBinding;
-import com.sleepycat.je.CheckpointConfig;
-import com.sleepycat.je.Cursor;
-import com.sleepycat.je.Database;
-import com.sleepycat.je.DatabaseConfig;
-import com.sleepycat.je.DatabaseEntry;
-import com.sleepycat.je.DatabaseException;
-import com.sleepycat.je.Environment;
-import com.sleepycat.je.EnvironmentConfig;
-import com.sleepycat.je.LockMode;
-import com.sleepycat.je.OperationStatus;
-import com.sleepycat.je.TransactionConfig;
/**
* BDBMessageStore implements a persistent {@link MessageStore} using the BDB high performance log.
@@ -91,7 +90,7 @@ import com.sleepycat.je.TransactionConfig;
* dequeue messages to queues. <tr><td> Generate message identifiers. </table>
*/
@SuppressWarnings({"unchecked"})
-public class BDBMessageStore implements MessageStore
+public class BDBMessageStore implements MessageStore, DurableConfigurationStore
{
private static final Logger _log = Logger.getLogger(BDBMessageStore.class);
@@ -107,19 +106,24 @@ public class BDBMessageStore implements MessageStore
private String DELIVERYDB_NAME = "deliveryDb";
private String EXCHANGEDB_NAME = "exchangeDb";
private String QUEUEDB_NAME = "queueDb";
+ private String BRIDGEDB_NAME = "bridges";
+ private String LINKDB_NAME = "links";
+
private Database _messageMetaDataDb;
private Database _messageContentDb;
private Database _queueBindingsDb;
private Database _deliveryDb;
private Database _exchangeDb;
private Database _queueDb;
+ private Database _bridgeDb;
+ private Database _linkDb;
/* =======
* Schema:
* =======
- *
+ *
* Queue:
- * name(AMQShortString) - name(AMQShortString), owner(AMQShortString),
+ * name(AMQShortString) - name(AMQShortString), owner(AMQShortString),
* arguments(FieldTable encoded as binary), exclusive (boolean)
*
* Exchange:
@@ -171,7 +175,7 @@ public class BDBMessageStore implements MessageStore
private boolean _configured;
-
+
public BDBMessageStore()
{
this(DATABASE_FORMAT_VERSION);
@@ -197,27 +201,28 @@ public class BDBMessageStore implements MessageStore
EXCHANGEDB_NAME += "_v" + version;
QUEUEBINDINGSDB_NAME += "_v" + version;
+
+ LINKDB_NAME += "_v" + version;
+
+ BRIDGEDB_NAME += "_v" + version;
}
}
-
- public void configureConfigStore(String name,
- ConfigurationRecoveryHandler recoveryHandler,
+
+ public void configureConfigStore(String name,
+ ConfigurationRecoveryHandler recoveryHandler,
Configuration storeConfiguration,
LogSubject logSubject) throws Exception
{
- _logSubject = logSubject;
- CurrentActor.get().message(_logSubject, ConfigStoreMessages.CREATED(this.getClass().getName()));
+ CurrentActor.get().message(logSubject, ConfigStoreMessages.CREATED(this.getClass().getName()));
- if(_configured)
+ if(!_configured)
{
- throw new Exception("ConfigStore already configured");
+ _logSubject = logSubject;
+ configure(name,storeConfiguration);
+ _configured = true;
+ stateTransition(State.CONFIGURING, State.CONFIGURED);
}
- configure(name,storeConfiguration);
-
- _configured = true;
- stateTransition(State.CONFIGURING, State.CONFIGURED);
-
recover(recoveryHandler);
stateTransition(State.RECOVERING, State.STARTED);
}
@@ -227,11 +232,14 @@ public class BDBMessageStore implements MessageStore
Configuration storeConfiguration,
LogSubject logSubject) throws Exception
{
- CurrentActor.get().message(_logSubject, MessageStoreMessages.CREATED(this.getClass().getName()));
+ CurrentActor.get().message(logSubject, MessageStoreMessages.CREATED(this.getClass().getName()));
if(!_configured)
{
- throw new Exception("ConfigStore not configured");
+ _logSubject = logSubject;
+ configure(name,storeConfiguration);
+ _configured = true;
+ stateTransition(State.CONFIGURING, State.CONFIGURED);
}
recoverMessages(recoveryHandler);
@@ -240,24 +248,28 @@ public class BDBMessageStore implements MessageStore
public void configureTransactionLog(String name, TransactionLogRecoveryHandler recoveryHandler,
Configuration storeConfiguration, LogSubject logSubject) throws Exception
{
- CurrentActor.get().message(_logSubject, TransactionLogMessages.CREATED(this.getClass().getName()));
+ CurrentActor.get().message(logSubject, TransactionLogMessages.CREATED(this.getClass().getName()));
+
if(!_configured)
{
- throw new Exception("ConfigStore not configured");
+ _logSubject = logSubject;
+ configure(name,storeConfiguration);
+ _configured = true;
+ stateTransition(State.CONFIGURING, State.CONFIGURED);
}
recoverQueueEntries(recoveryHandler);
-
+
}
- public org.apache.qpid.server.store.TransactionLog.Transaction newTransaction()
+ public org.apache.qpid.server.store.MessageStore.Transaction newTransaction()
{
return new BDBTransaction();
}
-
+
/**
* Called after instantiation in order to configure the message store.
*
@@ -268,8 +280,8 @@ public class BDBMessageStore implements MessageStore
*/
public boolean configure(String name, Configuration storeConfig) throws Exception
{
- File environmentPath = new File(storeConfig.getString(ENVIRONMENT_PATH_PROPERTY,
- System.getProperty("QPID_WORK") + "/bdbstore/" + name));
+ File environmentPath = new File(storeConfig.getString(ENVIRONMENT_PATH_PROPERTY,
+ System.getProperty("QPID_WORK") + "/bdbstore/" + name));
if (!environmentPath.exists())
{
if (!environmentPath.mkdirs())
@@ -288,7 +300,7 @@ public class BDBMessageStore implements MessageStore
/**
* @param environmentPath location for the store to be created in/recovered from
- * @param readonly if true then don't allow modifications to an existing store, and don't create a new store if none exists
+ * @param readonly if true then don't allow modifications to an existing store, and don't create a new store if none exists
* @return whether or not a new store environment was created
* @throws AMQStoreException
* @throws DatabaseException
@@ -301,12 +313,12 @@ public class BDBMessageStore implements MessageStore
_log.info("Configuring BDB message store");
createTupleBindingFactories(_version);
-
+
setDatabaseNames(_version);
return setupStore(environmentPath, readonly);
}
-
+
private void createTupleBindingFactories(int version)
{
_bindingTupleBindingFactory = new BindingTupleBindingFactory(version);
@@ -406,7 +418,7 @@ public class BDBMessageStore implements MessageStore
envConfig.setTransactional(true);
envConfig.setConfigParam("je.lock.nLockTables", "7");
- // Restore 500,000 default timeout.
+ // Restore 500,000 default timeout.
//envConfig.setLockTimeout(15000);
// Added to help diagnosis of Deadlock issue
@@ -416,10 +428,10 @@ public class BDBMessageStore implements MessageStore
envConfig.setConfigParam("je.txn.deadlockStackTrace", "true");
envConfig.setConfigParam("je.txn.dumpLocks", "true");
}
-
+
// Set transaction mode
_transactionConfig.setReadCommitted(true);
-
+
//This prevents background threads running which will potentially update the store.
envConfig.setReadOnly(readonly);
try
@@ -458,15 +470,26 @@ public class BDBMessageStore implements MessageStore
//This is required if we are wanting read only access.
dbConfig.setReadOnly(readonly);
- _messageMetaDataDb = _environment.openDatabase(null, MESSAGEMETADATADB_NAME, dbConfig);
- _queueDb = _environment.openDatabase(null, QUEUEDB_NAME, dbConfig);
- _exchangeDb = _environment.openDatabase(null, EXCHANGEDB_NAME, dbConfig);
- _queueBindingsDb = _environment.openDatabase(null, QUEUEBINDINGSDB_NAME, dbConfig);
- _messageContentDb = _environment.openDatabase(null, MESSAGECONTENTDB_NAME, dbConfig);
- _deliveryDb = _environment.openDatabase(null, DELIVERYDB_NAME, dbConfig);
+ _messageMetaDataDb = openDatabase(MESSAGEMETADATADB_NAME, dbConfig);
+ _queueDb = openDatabase(QUEUEDB_NAME, dbConfig);
+ _exchangeDb = openDatabase(EXCHANGEDB_NAME, dbConfig);
+ _queueBindingsDb = openDatabase(QUEUEBINDINGSDB_NAME, dbConfig);
+ _messageContentDb = openDatabase(MESSAGECONTENTDB_NAME, dbConfig);
+ _deliveryDb = openDatabase(DELIVERYDB_NAME, dbConfig);
+ _linkDb = openDatabase(LINKDB_NAME, dbConfig);
+ _bridgeDb = openDatabase(BRIDGEDB_NAME, dbConfig);
+
}
+ private Database openDatabase(final String dbName, final DatabaseConfig dbConfig)
+ {
+ // if opening read-only and the database doesn't exist, then you can't create it
+ return dbConfig.getReadOnly() && !_environment.getDatabaseNames().contains(dbName)
+ ? null
+ : _environment.openDatabase(null, dbName, dbConfig);
+ }
+
/**
* Called to close and cleanup any resources used by the message store.
*
@@ -520,10 +543,22 @@ public class BDBMessageStore implements MessageStore
_deliveryDb.close();
}
+ if (_bridgeDb != null)
+ {
+ _log.info("Close bridge database");
+ _bridgeDb.close();
+ }
+
+ if (_linkDb != null)
+ {
+ _log.info("Close link database");
+ _linkDb.close();
+ }
+
closeEnvironment();
_state = State.CLOSED;
-
+
CurrentActor.get().message(_logSubject,MessageStoreMessages.CLOSED());
}
@@ -542,7 +577,7 @@ public class BDBMessageStore implements MessageStore
}
}
-
+
public void recover(ConfigurationRecoveryHandler recoveryHandler) throws AMQStoreException
{
stateTransition(State.CONFIGURED, State.RECOVERING);
@@ -556,11 +591,12 @@ public class BDBMessageStore implements MessageStore
ExchangeRecoveryHandler erh = qrh.completeQueueRecovery();
loadExchanges(erh);
-
+
BindingRecoveryHandler brh = erh.completeExchangeRecovery();
recoverBindings(brh);
-
- brh.completeBindingRecovery();
+
+ ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler lrh = brh.completeBindingRecovery();
+ recoverBrokerLinks(lrh);
}
catch (DatabaseException e)
{
@@ -582,13 +618,13 @@ public class BDBMessageStore implements MessageStore
while (cursor.getNext(key, value, LockMode.RMW) == OperationStatus.SUCCESS)
{
QueueRecord queueRecord = (QueueRecord) binding.entryToObject(value);
-
- String queueName = queueRecord.getNameShortString() == null ? null :
+
+ String queueName = queueRecord.getNameShortString() == null ? null :
queueRecord.getNameShortString().asString();
- String owner = queueRecord.getOwner() == null ? null :
+ String owner = queueRecord.getOwner() == null ? null :
queueRecord.getOwner().asString();
boolean exclusive = queueRecord.isExclusive();
-
+
FieldTable arguments = queueRecord.getArguments();
qrh.queue(queueName, owner, exclusive, arguments);
@@ -603,8 +639,8 @@ public class BDBMessageStore implements MessageStore
}
}
}
-
-
+
+
private void loadExchanges(ExchangeRecoveryHandler erh) throws DatabaseException
{
Cursor cursor = null;
@@ -615,17 +651,17 @@ public class BDBMessageStore implements MessageStore
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry value = new DatabaseEntry();
TupleBinding binding = new ExchangeTB();
-
+
while (cursor.getNext(key, value, LockMode.RMW) == OperationStatus.SUCCESS)
{
ExchangeRecord exchangeRec = (ExchangeRecord) binding.entryToObject(value);
- String exchangeName = exchangeRec.getNameShortString() == null ? null :
+ String exchangeName = exchangeRec.getNameShortString() == null ? null :
exchangeRec.getNameShortString().asString();
- String type = exchangeRec.getType() == null ? null :
+ String type = exchangeRec.getType() == null ? null :
exchangeRec.getType().asString();
boolean autoDelete = exchangeRec.isAutoDelete();
-
+
erh.exchange(exchangeName, type, autoDelete);
}
}
@@ -638,7 +674,7 @@ public class BDBMessageStore implements MessageStore
}
}
-
+
private void recoverBindings(BindingRecoveryHandler brh) throws DatabaseException
{
Cursor cursor = null;
@@ -648,22 +684,22 @@ public class BDBMessageStore implements MessageStore
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry value = new DatabaseEntry();
TupleBinding binding = _bindingTupleBindingFactory.getInstance();
-
+
while (cursor.getNext(key, value, LockMode.RMW) == OperationStatus.SUCCESS)
{
//yes, this is retrieving all the useful information from the key only.
//For table compatibility it shall currently be left as is
BindingKey bindingRecord = (BindingKey) binding.entryToObject(key);
-
+
String exchangeName = bindingRecord.getExchangeName() == null ? null :
bindingRecord.getExchangeName().asString();
String queueName = bindingRecord.getQueueName() == null ? null :
bindingRecord.getQueueName().asString();
String routingKey = bindingRecord.getRoutingKey() == null ? null :
bindingRecord.getRoutingKey().asString();
- ByteBuffer argumentsBB = (bindingRecord.getArguments() == null ? null :
+ ByteBuffer argumentsBB = (bindingRecord.getArguments() == null ? null :
java.nio.ByteBuffer.wrap(bindingRecord.getArguments().getDataAsBytes()));
-
+
brh.binding(exchangeName, queueName, routingKey, argumentsBB);
}
}
@@ -677,6 +713,74 @@ public class BDBMessageStore implements MessageStore
}
+
+ private void recoverBrokerLinks(final ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler lrh)
+ {
+ Cursor cursor = null;
+
+ try
+ {
+ cursor = _linkDb.openCursor(null, null);
+ DatabaseEntry key = new DatabaseEntry();
+ DatabaseEntry value = new DatabaseEntry();
+
+ while (cursor.getNext(key, value, LockMode.RMW) == OperationStatus.SUCCESS)
+ {
+ UUID id = UUIDTupleBinding.getInstance().entryToObject(key);
+ long createTime = LongBinding.entryToLong(value);
+ Map<String,String> arguments = StringMapBinding.getInstance().entryToObject(value);
+
+ ConfigurationRecoveryHandler.BridgeRecoveryHandler brh = lrh.brokerLink(id, createTime, arguments);
+
+ recoverBridges(brh, id);
+ }
+ }
+ finally
+ {
+ if (cursor != null)
+ {
+ cursor.close();
+ }
+ }
+
+ }
+
+ private void recoverBridges(final ConfigurationRecoveryHandler.BridgeRecoveryHandler brh, final UUID linkId)
+ {
+ Cursor cursor = null;
+
+ try
+ {
+ cursor = _bridgeDb.openCursor(null, null);
+ DatabaseEntry key = new DatabaseEntry();
+ DatabaseEntry value = new DatabaseEntry();
+
+ while (cursor.getNext(key, value, LockMode.RMW) == OperationStatus.SUCCESS)
+ {
+ UUID id = UUIDTupleBinding.getInstance().entryToObject(key);
+
+ UUID parentId = UUIDTupleBinding.getInstance().entryToObject(value);
+ if(parentId.equals(linkId))
+ {
+
+ long createTime = LongBinding.entryToLong(value);
+ Map<String,String> arguments = StringMapBinding.getInstance().entryToObject(value);
+ brh.bridge(id,createTime,arguments);
+ }
+ }
+ brh.completeBridgeRecoveryForLink();
+ }
+ finally
+ {
+ if (cursor != null)
+ {
+ cursor.close();
+ }
+ }
+
+ }
+
+
private void recoverMessages(MessageStoreRecoveryHandler msrh) throws DatabaseException
{
StoredMessageRecoveryHandler mrh = msrh.begin();
@@ -686,8 +790,6 @@ public class BDBMessageStore implements MessageStore
{
cursor = _messageMetaDataDb.openCursor(null, null);
DatabaseEntry key = new DatabaseEntry();
- EntryBinding keyBinding = TupleBinding.getPrimitiveBinding(Long.class);;
-
DatabaseEntry value = new DatabaseEntry();
EntryBinding valueBinding = _metaDataTupleBindingFactory.getInstance();
@@ -695,12 +797,12 @@ public class BDBMessageStore implements MessageStore
while (cursor.getNext(key, value, LockMode.RMW) == OperationStatus.SUCCESS)
{
- long messageId = (Long) keyBinding.entryToObject(key);
+ long messageId = LongBinding.entryToLong(key);
StorableMessageMetaData metaData = (StorableMessageMetaData) valueBinding.entryToObject(value);
StoredBDBMessage message = new StoredBDBMessage(messageId, metaData, false);
mrh.message(message);
-
+
maxId = Math.max(maxId, messageId);
}
@@ -719,14 +821,14 @@ public class BDBMessageStore implements MessageStore
}
}
}
-
- private void recoverQueueEntries(TransactionLogRecoveryHandler recoveryHandler)
+
+ private void recoverQueueEntries(TransactionLogRecoveryHandler recoveryHandler)
throws DatabaseException
{
QueueEntryRecoveryHandler qerh = recoveryHandler.begin(this);
ArrayList<QueueEntryKey> entries = new ArrayList<QueueEntryKey>();
-
+
Cursor cursor = null;
try
{
@@ -751,12 +853,12 @@ public class BDBMessageStore implements MessageStore
{
cursor = null;
}
-
+
for(QueueEntryKey entry : entries)
{
AMQShortString queueName = entry.getQueueName();
long messageId = entry.getMessageId();
-
+
qerh.queueEntry(queueName.asString(),messageId);
}
}
@@ -781,36 +883,39 @@ public class BDBMessageStore implements MessageStore
*
* @param messageId Identifies the message to remove.
*
- * @throws AMQInternalException If the operation fails for any reason.
+ * @throws AMQStoreException If the operation fails for any reason.
*/
- public void removeMessage(Long messageId) throws AMQStoreException
+ public void removeMessage(long messageId) throws AMQStoreException
{
+ removeMessage(messageId, true);
+ }
+ public void removeMessage(long messageId, boolean sync) throws AMQStoreException
+ {
+
// _log.debug("public void removeMessage(Long messageId = " + messageId): called");
com.sleepycat.je.Transaction tx = null;
-
+
Cursor cursor = null;
try
{
tx = _environment.beginTransaction(null, null);
-
+
//remove the message meta data from the store
DatabaseEntry key = new DatabaseEntry();
- EntryBinding metaKeyBindingTuple = TupleBinding.getPrimitiveBinding(Long.class);
- metaKeyBindingTuple.objectToEntry(messageId, key);
+ LongBinding.longToEntry(messageId, key);
if (_log.isDebugEnabled())
{
_log.debug("Removing message id " + messageId);
}
-
+
OperationStatus status = _messageMetaDataDb.delete(tx, key);
if (status == OperationStatus.NOTFOUND)
{
- tx.abort();
-
- throw new AMQStoreException("Message metadata not found for message id " + messageId);
+ _log.info("Message not found (attempt to remove failed - probably application initiated rollback) " +
+ messageId);
}
if (_log.isDebugEnabled())
@@ -826,7 +931,7 @@ public class BDBMessageStore implements MessageStore
TupleBinding<MessageContentKey> contentKeyTupleBinding = new MessageContentKeyTB_5();
contentKeyTupleBinding.objectToEntry(mck, contentKeyEntry);
- //Use a partial record for the value to prevent retrieving the
+ //Use a partial record for the value to prevent retrieving the
//data itself as we only need the key to identify what to remove.
DatabaseEntry value = new DatabaseEntry();
value.setPartial(0, 0, true);
@@ -837,7 +942,7 @@ public class BDBMessageStore implements MessageStore
while (status == OperationStatus.SUCCESS)
{
mck = (MessageContentKey_5) contentKeyTupleBinding.entryToObject(contentKeyEntry);
-
+
if(mck.getMessageId() != messageId)
{
//we have exhausted all chunks for this message id, break
@@ -846,34 +951,34 @@ public class BDBMessageStore implements MessageStore
else
{
status = cursor.delete();
-
+
if(status == OperationStatus.NOTFOUND)
{
cursor.close();
cursor = null;
-
+
tx.abort();
throw new AMQStoreException("Content chunk offset" + mck.getOffset() + " not found for message " + messageId);
}
-
+
if (_log.isDebugEnabled())
{
_log.debug("Deleted content chunk offset " + mck.getOffset() + " for message " + messageId);
}
}
-
+
status = cursor.getNext(contentKeyEntry, value, LockMode.RMW);
}
cursor.close();
cursor = null;
-
- commit(tx, true);
+
+ commit(tx, sync);
}
catch (DatabaseException e)
{
e.printStackTrace();
-
+
if (tx != null)
{
try
@@ -883,7 +988,7 @@ public class BDBMessageStore implements MessageStore
cursor.close();
cursor = null;
}
-
+
tx.abort();
}
catch (DatabaseException e1)
@@ -917,7 +1022,7 @@ public class BDBMessageStore implements MessageStore
{
if (_state != State.RECOVERING)
{
- ExchangeRecord exchangeRec = new ExchangeRecord(exchange.getNameShortString(),
+ ExchangeRecord exchangeRec = new ExchangeRecord(exchange.getNameShortString(),
exchange.getTypeShortString(), exchange.isAutoDelete());
DatabaseEntry key = new DatabaseEntry();
@@ -974,20 +1079,20 @@ public class BDBMessageStore implements MessageStore
if (_state != State.RECOVERING)
{
- BindingKey bindingRecord = new BindingKey(exchange.getNameShortString(),
+ BindingKey bindingRecord = new BindingKey(exchange.getNameShortString(),
queue.getNameShortString(), routingKey, args);
DatabaseEntry key = new DatabaseEntry();
EntryBinding keyBinding = _bindingTupleBindingFactory.getInstance();
-
+
keyBinding.objectToEntry(bindingRecord, key);
- //yes, this is writing out 0 as a value and putting all the
+ //yes, this is writing out 0 as a value and putting all the
//useful info into the key, don't ask me why. For table
//compatibility it shall currently be left as is
DatabaseEntry value = new DatabaseEntry();
ByteBinding.byteToEntry((byte) 0, value);
-
+
try
{
_queueBindingsDb.put(null, key, value);
@@ -1043,16 +1148,16 @@ public class BDBMessageStore implements MessageStore
{
_log.debug("public void createQueue(AMQQueue queue(" + queue.getName() + ") = " + queue + "): called");
}
-
- QueueRecord queueRecord= new QueueRecord(queue.getNameShortString(),
+
+ QueueRecord queueRecord= new QueueRecord(queue.getNameShortString(),
queue.getOwner(), queue.isExclusive(), arguments);
-
+
createQueue(queueRecord);
}
/**
- * Makes the specified queue persistent.
- *
+ * Makes the specified queue persistent.
+ *
* Only intended for direct use during store upgrades.
*
* @param queueRecord Details of the queue to store.
@@ -1086,7 +1191,7 @@ public class BDBMessageStore implements MessageStore
/**
* Updates the specified queue in the persistent store, IF it is already present. If the queue
* is not present in the store, it will not be added.
- *
+ *
* NOTE: Currently only updates the exclusivity.
*
* @param queue The queue to update the entry for.
@@ -1112,13 +1217,13 @@ public class BDBMessageStore implements MessageStore
OperationStatus status = _queueDb.get(null, key, value, LockMode.DEFAULT);
if(status == OperationStatus.SUCCESS)
{
- //read the existing record and apply the new exclusivity setting
+ //read the existing record and apply the new exclusivity setting
QueueRecord queueRecord = (QueueRecord) queueBinding.entryToObject(value);
queueRecord.setExclusive(queue.isExclusive());
-
+
//write the updated entry to the store
queueBinding.objectToEntry(queueRecord, newValue);
-
+
_queueDb.put(null, key, newValue);
}
else if(status != OperationStatus.NOTFOUND)
@@ -1147,7 +1252,7 @@ public class BDBMessageStore implements MessageStore
{
_log.debug("public void removeQueue(AMQShortString name = " + name + "): called");
}
-
+
DatabaseEntry key = new DatabaseEntry();
EntryBinding keyBinding = new AMQShortStringTB();
keyBinding.objectToEntry(name, key);
@@ -1165,6 +1270,90 @@ public class BDBMessageStore implements MessageStore
}
}
+ public void createBrokerLink(final BrokerLink link) throws AMQStoreException
+ {
+ if (_state != State.RECOVERING)
+ {
+ DatabaseEntry key = new DatabaseEntry();
+ UUIDTupleBinding.getInstance().objectToEntry(link.getId(), key);
+
+ DatabaseEntry value = new DatabaseEntry();
+ LongBinding.longToEntry(link.getCreateTime(),value);
+ StringMapBinding.getInstance().objectToEntry(link.getArguments(), value);
+
+ try
+ {
+ _linkDb.put(null, key, value);
+ }
+ catch (DatabaseException e)
+ {
+ throw new AMQStoreException("Error writing Link " + link
+ + " to database: " + e.getMessage(), e);
+ }
+ }
+ }
+
+ public void deleteBrokerLink(final BrokerLink link) throws AMQStoreException
+ {
+ DatabaseEntry key = new DatabaseEntry();
+ UUIDTupleBinding.getInstance().objectToEntry(link.getId(), key);
+ try
+ {
+ OperationStatus status = _linkDb.delete(null, key);
+ if (status == OperationStatus.NOTFOUND)
+ {
+ throw new AMQStoreException("Link " + link + " not found");
+ }
+ }
+ catch (DatabaseException e)
+ {
+ throw new AMQStoreException("Error deleting the Link " + link + " from database: " + e.getMessage(), e);
+ }
+ }
+
+ public void createBridge(final Bridge bridge) throws AMQStoreException
+ {
+ if (_state != State.RECOVERING)
+ {
+ DatabaseEntry key = new DatabaseEntry();
+ UUIDTupleBinding.getInstance().objectToEntry(bridge.getId(), key);
+
+ DatabaseEntry value = new DatabaseEntry();
+ UUIDTupleBinding.getInstance().objectToEntry(bridge.getLink().getId(),value);
+ LongBinding.longToEntry(bridge.getCreateTime(),value);
+ StringMapBinding.getInstance().objectToEntry(bridge.getArguments(), value);
+
+ try
+ {
+ _bridgeDb.put(null, key, value);
+ }
+ catch (DatabaseException e)
+ {
+ throw new AMQStoreException("Error writing Bridge " + bridge
+ + " to database: " + e.getMessage(), e);
+ }
+
+ }
+ }
+
+ public void deleteBridge(final Bridge bridge) throws AMQStoreException
+ {
+ DatabaseEntry key = new DatabaseEntry();
+ UUIDTupleBinding.getInstance().objectToEntry(bridge.getId(), key);
+ try
+ {
+ OperationStatus status = _bridgeDb.delete(null, key);
+ if (status == OperationStatus.NOTFOUND)
+ {
+ throw new AMQStoreException("Bridge " + bridge + " not found");
+ }
+ }
+ catch (DatabaseException e)
+ {
+ throw new AMQStoreException("Error deleting the Bridge " + bridge + " from database: " + e.getMessage(), e);
+ }
+ }
+
/**
* Places a message onto a specified queue, in a given transaction.
*
@@ -1174,12 +1363,13 @@ public class BDBMessageStore implements MessageStore
*
* @throws AMQStoreException If the operation fails for any reason.
*/
- public void enqueueMessage(final com.sleepycat.je.Transaction tx, final TransactionLogResource queue, Long messageId) throws AMQStoreException
+ public void enqueueMessage(final com.sleepycat.je.Transaction tx, final TransactionLogResource queue,
+ long messageId) throws AMQStoreException
{
// _log.debug("public void enqueueMessage(Transaction tx = " + tx + ", AMQShortString name = " + name + ", Long messageId): called");
- AMQShortString name = new AMQShortString(queue.getResourceName());
-
+ AMQShortString name = AMQShortString.valueOf(queue.getResourceName());
+
DatabaseEntry key = new DatabaseEntry();
EntryBinding keyBinding = new QueueEntryTB();
QueueEntryKey dd = new QueueEntryKey(name, messageId);
@@ -1212,7 +1402,8 @@ public class BDBMessageStore implements MessageStore
*
* @throws AMQStoreException If the operation fails for any reason, or if the specified message does not exist.
*/
- public void dequeueMessage(final com.sleepycat.je.Transaction tx, final TransactionLogResource queue, Long messageId) throws AMQStoreException
+ public void dequeueMessage(final com.sleepycat.je.Transaction tx, final TransactionLogResource queue,
+ long messageId) throws AMQStoreException
{
AMQShortString name = new AMQShortString(queue.getResourceName());
@@ -1226,7 +1417,7 @@ public class BDBMessageStore implements MessageStore
{
_log.debug("Dequeue message id " + messageId);
}
-
+
try
{
@@ -1234,7 +1425,7 @@ public class BDBMessageStore implements MessageStore
if (status == OperationStatus.NOTFOUND)
{
throw new AMQStoreException("Unable to find message with id " + messageId + " on queue " + name);
- }
+ }
else if (status != OperationStatus.SUCCESS)
{
throw new AMQStoreException("Unable to remove message with id " + messageId + " on queue " + name);
@@ -1269,12 +1460,12 @@ public class BDBMessageStore implements MessageStore
//{
// _log.debug("public void commitTranImpl() called with (Transaction=" + tx + ", syncCommit= "+ syncCommit + ")");
//}
-
+
if (tx == null)
{
throw new AMQStoreException("Fatal internal error: transactional is null at commitTran");
}
-
+
StoreFuture result;
try
{
@@ -1289,7 +1480,7 @@ public class BDBMessageStore implements MessageStore
{
throw new AMQStoreException("Error commit tx: " + e.getMessage(), e);
}
-
+
return result;
}
@@ -1383,7 +1574,7 @@ public class BDBMessageStore implements MessageStore
*
* @return A fresh message id.
*/
- public Long getNewMessageId()
+ public long getNewMessageId()
{
return _messageId.incrementAndGet();
}
@@ -1398,7 +1589,7 @@ public class BDBMessageStore implements MessageStore
*
* @throws AMQStoreException If the operation fails for any reason, or if the specified message does not exist.
*/
- protected void addContent(final com.sleepycat.je.Transaction tx, Long messageId, int offset,
+ protected void addContent(final com.sleepycat.je.Transaction tx, long messageId, int offset,
ByteBuffer contentBody) throws AMQStoreException
{
DatabaseEntry key = new DatabaseEntry();
@@ -1436,7 +1627,8 @@ public class BDBMessageStore implements MessageStore
*
* @throws AMQStoreException If the operation fails for any reason, or if the specified message does not exist.
*/
- private void storeMetaData(final com.sleepycat.je.Transaction tx, Long messageId, StorableMessageMetaData messageMetaData)
+ private void storeMetaData(final com.sleepycat.je.Transaction tx, long messageId,
+ StorableMessageMetaData messageMetaData)
throws AMQStoreException
{
if (_log.isDebugEnabled())
@@ -1446,10 +1638,9 @@ public class BDBMessageStore implements MessageStore
}
DatabaseEntry key = new DatabaseEntry();
- EntryBinding keyBinding = TupleBinding.getPrimitiveBinding(Long.class);
- keyBinding.objectToEntry(messageId, key);
+ LongBinding.longToEntry(messageId, key);
DatabaseEntry value = new DatabaseEntry();
-
+
TupleBinding messageBinding = _metaDataTupleBindingFactory.getInstance();
messageBinding.objectToEntry(messageMetaData, value);
try
@@ -1475,7 +1666,7 @@ public class BDBMessageStore implements MessageStore
*
* @throws AMQStoreException If the operation fails for any reason, or if the specified message does not exist.
*/
- public StorableMessageMetaData getMessageMetaData(Long messageId) throws AMQStoreException
+ public StorableMessageMetaData getMessageMetaData(long messageId) throws AMQStoreException
{
if (_log.isDebugEnabled())
{
@@ -1484,8 +1675,7 @@ public class BDBMessageStore implements MessageStore
}
DatabaseEntry key = new DatabaseEntry();
- EntryBinding keyBinding = TupleBinding.getPrimitiveBinding(Long.class);
- keyBinding.objectToEntry(messageId, key);
+ LongBinding.longToEntry(messageId, key);
DatabaseEntry value = new DatabaseEntry();
TupleBinding messageBinding = _metaDataTupleBindingFactory.getInstance();
@@ -1519,17 +1709,17 @@ public class BDBMessageStore implements MessageStore
*
* @throws AMQStoreException If the operation fails for any reason, or if the specified message does not exist.
*/
- public int getContent(Long messageId, int offset, ByteBuffer dst) throws AMQStoreException
- {
+ public int getContent(long messageId, int offset, ByteBuffer dst) throws AMQStoreException
+ {
DatabaseEntry contentKeyEntry = new DatabaseEntry();
-
- //Start from 0 offset and search for the starting chunk.
+
+ //Start from 0 offset and search for the starting chunk.
MessageContentKey_5 mck = new MessageContentKey_5(messageId, 0);
TupleBinding<MessageContentKey> contentKeyTupleBinding = new MessageContentKeyTB_5();
contentKeyTupleBinding.objectToEntry(mck, contentKeyEntry);
DatabaseEntry value = new DatabaseEntry();
TupleBinding<ByteBuffer> contentTupleBinding = new ContentTB();
-
+
if (_log.isDebugEnabled())
{
_log.debug("Message Id: " + messageId + " Getting content body from offset: " + offset);
@@ -1537,32 +1727,32 @@ public class BDBMessageStore implements MessageStore
int written = 0;
int seenSoFar = 0;
-
+
Cursor cursor = null;
try
{
cursor = _messageContentDb.openCursor(null, null);
-
+
OperationStatus status = cursor.getSearchKeyRange(contentKeyEntry, value, LockMode.READ_UNCOMMITTED);
while (status == OperationStatus.SUCCESS)
{
mck = (MessageContentKey_5) contentKeyTupleBinding.entryToObject(contentKeyEntry);
long id = mck.getMessageId();
-
+
if(id != messageId)
{
//we have exhausted all chunks for this message id, break
break;
}
-
+
int offsetInMessage = mck.getOffset();
ByteBuffer buf = (ByteBuffer) contentTupleBinding.entryToObject(value);
-
+
final int size = (int) buf.limit();
-
+
seenSoFar += size;
-
+
if(seenSoFar >= offset)
{
byte[] dataAsBytes = buf.array();
@@ -1581,7 +1771,7 @@ public class BDBMessageStore implements MessageStore
break;
}
}
-
+
status = cursor.getNext(contentKeyEntry, value, LockMode.RMW);
}
@@ -1636,7 +1826,7 @@ public class BDBMessageStore implements MessageStore
{
return _bindingTupleBindingFactory;
}
-
+
protected MessageMetaDataTupleBindingFactory getMetaDataTupleBindingFactory()
{
return _metaDataTupleBindingFactory;
@@ -1743,7 +1933,7 @@ public class BDBMessageStore implements MessageStore
BDBCommitFuture commitFuture = new BDBCommitFuture(_commitThread, tx, syncCommit);
commitFuture.commit();
-
+
return commitFuture;
}
@@ -1778,7 +1968,6 @@ public class BDBMessageStore implements MessageStore
{
_log.debug("public synchronized void complete(): called (Transaction = " + _tx + ")");
}
-
_complete = true;
notifyAll();
@@ -1799,36 +1988,22 @@ public class BDBMessageStore implements MessageStore
{
//_log.debug("public void commit(): called");
- _commitThread.addJob(this);
-
+ _commitThread.addJob(this, _syncCommit);
+
if(!_syncCommit)
{
_log.debug("CommitAsync was requested, returning immediately.");
return;
}
-
- synchronized (BDBCommitFuture.this)
- {
- while (!_complete)
- {
- try
- {
- wait(250);
- }
- catch (InterruptedException e)
- {
- // _log.error("Unexpected thread interruption: " + e, e);
- throw new RuntimeException(e);
- }
- }
- // _log.debug("Commit completed, _databaseException = " + _databaseException);
+ waitForCompletion();
+ // _log.debug("Commit completed, _databaseException = " + _databaseException);
- if (_databaseException != null)
- {
- throw _databaseException;
- }
+ if (_databaseException != null)
+ {
+ throw _databaseException;
}
+
}
public synchronized boolean isComplete()
@@ -1836,10 +2011,11 @@ public class BDBMessageStore implements MessageStore
return _complete;
}
- public void waitForCompletion()
+ public synchronized void waitForCompletion()
{
while (!isComplete())
{
+ _commitThread.explicitNotify();
try
{
wait(250);
@@ -1866,7 +2042,7 @@ public class BDBMessageStore implements MessageStore
// private final Logger _log = Logger.getLogger(CommitThread.class);
private final AtomicBoolean _stopped = new AtomicBoolean(false);
- private final AtomicReference<Queue<BDBCommitFuture>> _jobQueue = new AtomicReference<Queue<BDBCommitFuture>>(new ConcurrentLinkedQueue<BDBCommitFuture>());
+ private final Queue<BDBCommitFuture> _jobQueue = new ConcurrentLinkedQueue<BDBCommitFuture>();
private final CheckpointConfig _config = new CheckpointConfig();
private final Object _lock = new Object();
@@ -1877,6 +2053,14 @@ public class BDBMessageStore implements MessageStore
}
+ public void explicitNotify()
+ {
+ synchronized (_lock)
+ {
+ _lock.notify();
+ }
+ }
+
public void run()
{
while (!_stopped.get())
@@ -1887,7 +2071,7 @@ public class BDBMessageStore implements MessageStore
{
try
{
- // RHM-7 Periodically wake up and check, just in case we
+ // RHM-7 Periodically wake up and check, just in case we
// missed a notification. Don't want to lock the broker hard.
_lock.wait(250);
}
@@ -1905,24 +2089,24 @@ public class BDBMessageStore implements MessageStore
{
// _log.debug("private void processJobs(): called");
- // we replace the old queue atomically with a new one and this avoids any need to
- // copy elements out of the queue
- Queue<BDBCommitFuture> jobs = _jobQueue.getAndSet(new ConcurrentLinkedQueue<BDBCommitFuture>());
+ int size = _jobQueue.size();
try
{
- // _environment.checkpoint(_config);
- _environment.sync();
+ _environment.flushLog(true);
- for (BDBCommitFuture commit : jobs)
+ for(int i = 0; i < size; i++)
{
+ BDBCommitFuture commit = _jobQueue.poll();
commit.complete();
}
+
}
catch (DatabaseException e)
{
- for (BDBCommitFuture commit : jobs)
+ for(int i = 0; i < size; i++)
{
+ BDBCommitFuture commit = _jobQueue.poll();
commit.abort(e);
}
}
@@ -1931,15 +2115,19 @@ public class BDBMessageStore implements MessageStore
private boolean hasJobs()
{
- return !_jobQueue.get().isEmpty();
+ return !_jobQueue.isEmpty();
}
- public void addJob(BDBCommitFuture commit)
+ public void addJob(BDBCommitFuture commit, final boolean sync)
{
- synchronized (_lock)
+
+ _jobQueue.add(commit);
+ if(sync)
{
- _jobQueue.get().add(commit);
- _lock.notifyAll();
+ synchronized (_lock)
+ {
+ _lock.notifyAll();
+ }
}
}
@@ -1952,14 +2140,17 @@ public class BDBMessageStore implements MessageStore
}
}
}
-
-
+
+
private class StoredBDBMessage implements StoredMessage
{
private final long _messageId;
private volatile SoftReference<StorableMessageMetaData> _metaDataRef;
- private com.sleepycat.je.Transaction _txn;
+
+ private StorableMessageMetaData _metaData;
+ private volatile SoftReference<byte[]> _dataRef;
+ private byte[] _data;
StoredBDBMessage(long messageId, StorableMessageMetaData metaData)
{
@@ -1973,22 +2164,15 @@ public class BDBMessageStore implements MessageStore
try
{
_messageId = messageId;
+ _metaData = metaData;
_metaDataRef = new SoftReference<StorableMessageMetaData>(metaData);
- if(persist)
- {
- _txn = _environment.beginTransaction(null, null);
- storeMetaData(_txn, messageId, metaData);
- }
+
}
catch (DatabaseException e)
{
throw new RuntimeException(e);
}
- catch (AMQStoreException e)
- {
- throw new RuntimeException(e);
- }
}
@@ -2018,58 +2202,114 @@ public class BDBMessageStore implements MessageStore
public void addContent(int offsetInMessage, java.nio.ByteBuffer src)
{
- try
+ src = src.slice();
+
+ if(_data == null)
{
- BDBMessageStore.this.addContent(_txn, _messageId, offsetInMessage, src);
+ _data = new byte[src.remaining()];
+ _dataRef = new SoftReference<byte[]>(_data);
+ src.duplicate().get(_data);
}
- catch (AMQStoreException e)
+ else
{
- throw new RuntimeException(e);
+ byte[] oldData = _data;
+ _data = new byte[oldData.length + src.remaining()];
+ _dataRef = new SoftReference<byte[]>(_data);
+
+ System.arraycopy(oldData,0,_data,0,oldData.length);
+ src.duplicate().get(_data, oldData.length, src.remaining());
}
+
}
public int getContent(int offsetInMessage, java.nio.ByteBuffer dst)
{
- try
+ byte[] data = _dataRef == null ? null : _dataRef.get();
+ if(data != null)
{
- return BDBMessageStore.this.getContent(_messageId, offsetInMessage, dst);
+ int length = Math.min(dst.remaining(), data.length - offsetInMessage);
+ dst.put(data, offsetInMessage, length);
+ return length;
}
- catch (AMQStoreException e)
+ else
{
- throw new RuntimeException(e);
+ try
+ {
+ return BDBMessageStore.this.getContent(_messageId, offsetInMessage, dst);
+ }
+ catch (AMQStoreException e)
+ {
+ throw new RuntimeException(e);
+ }
}
}
- public StoreFuture flushToStore()
+ public ByteBuffer getContent(int offsetInMessage, int size)
{
- try
+ byte[] data = _dataRef == null ? null : _dataRef.get();
+ if(data != null)
{
- if(_txn != null)
- {
- //if(_log.isDebugEnabled())
- //{
- // _log.debug("Flushing message " + _messageId + " to store");
- //}
- BDBMessageStore.this.commitTranImpl(_txn, true);
- }
+ return ByteBuffer.wrap(data,offsetInMessage,size);
}
- catch (AMQStoreException e)
+ else
{
- throw new RuntimeException(e);
+ ByteBuffer buf = ByteBuffer.allocate(size);
+ getContent(offsetInMessage, buf);
+ buf.position(0);
+ return buf;
}
- finally
+ }
+
+ synchronized void store(com.sleepycat.je.Transaction txn)
+ {
+
+ if(_metaData != null)
{
- _txn = null;
+ try
+ {
+ _dataRef = new SoftReference<byte[]>(_data);
+ BDBMessageStore.this.storeMetaData(txn, _messageId, _metaData);
+ BDBMessageStore.this.addContent(txn, _messageId, 0,
+ _data == null ? ByteBuffer.allocate(0) : ByteBuffer.wrap(_data));
+ }
+ catch(DatabaseException e)
+ {
+ throw new RuntimeException(e);
+ }
+ catch (AMQStoreException e)
+ {
+ throw new RuntimeException(e);
+ }
+ catch (RuntimeException e)
+ {
+ e.printStackTrace();
+ throw e;
+ }
+ finally
+ {
+ _metaData = null;
+ _data = null;
+ }
+ }
+ }
+
+ public synchronized StoreFuture flushToStore()
+ {
+ if(_metaData != null)
+ {
+ com.sleepycat.je.Transaction txn = _environment.beginTransaction(null, null);
+ store(txn);
+ BDBMessageStore.this.commit(txn,true);
+
}
return IMMEDIATE_FUTURE;
}
public void remove()
{
- flushToStore();
try
{
- BDBMessageStore.this.removeMessage(_messageId);
+ BDBMessageStore.this.removeMessage(_messageId, false);
}
catch (AMQStoreException e)
{
@@ -2094,12 +2334,27 @@ public class BDBMessageStore implements MessageStore
}
}
- public void enqueueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException
+ public void enqueueMessage(TransactionLogResource queue, EnqueableMessage message) throws AMQStoreException
+ {
+ if(message.getStoredMessage() instanceof StoredBDBMessage)
+ {
+ ((StoredBDBMessage)message.getStoredMessage()).store(_txn);
+ }
+
+ BDBMessageStore.this.enqueueMessage(_txn, queue, message.getMessageNumber());
+ }
+
+ public void dequeueMessage(TransactionLogResource queue, EnqueableMessage message) throws AMQStoreException
+ {
+ BDBMessageStore.this.dequeueMessage(_txn, queue, message.getMessageNumber());
+ }
+
+ public void enqueueMessage(TransactionLogResource queue, long messageId) throws AMQStoreException
{
BDBMessageStore.this.enqueueMessage(_txn, queue, messageId);
}
- public void dequeueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException
+ public void dequeueMessage(TransactionLogResource queue, long messageId) throws AMQStoreException
{
BDBMessageStore.this.dequeueMessage(_txn, queue, messageId);
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StringMapBinding.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StringMapBinding.java
new file mode 100644
index 0000000000..f8fd39e127
--- /dev/null
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StringMapBinding.java
@@ -0,0 +1,61 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.store.berkeleydb;
+
+import com.sleepycat.bind.tuple.TupleBinding;
+import com.sleepycat.bind.tuple.TupleInput;
+import com.sleepycat.bind.tuple.TupleOutput;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class StringMapBinding extends TupleBinding<Map<String,String>>
+{
+
+ private static final StringMapBinding INSTANCE = new StringMapBinding();
+
+ public Map<String, String> entryToObject(final TupleInput tupleInput)
+ {
+ int entries = tupleInput.readInt();
+ Map<String,String> map = new HashMap<String,String>(entries);
+ for(int i = 0; i < entries; i++)
+ {
+ map.put(tupleInput.readString(), tupleInput.readString());
+ }
+ return map;
+ }
+
+
+ public void objectToEntry(final Map<String, String> stringStringMap, final TupleOutput tupleOutput)
+ {
+ tupleOutput.writeInt(stringStringMap.size());
+ for(Map.Entry<String,String> entry : stringStringMap.entrySet())
+ {
+ tupleOutput.writeString(entry.getKey());
+ tupleOutput.writeString(entry.getValue());
+ }
+ }
+
+ public static StringMapBinding getInstance()
+ {
+ return INSTANCE;
+ }
+}
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/UUIDTupleBinding.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/UUIDTupleBinding.java
new file mode 100644
index 0000000000..c1a5d473f0
--- /dev/null
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/UUIDTupleBinding.java
@@ -0,0 +1,50 @@
+/*
+ *
+ * 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.berkeleydb;
+
+import com.sleepycat.bind.tuple.TupleBinding;
+import com.sleepycat.bind.tuple.TupleInput;
+import com.sleepycat.bind.tuple.TupleOutput;
+
+import java.util.UUID;
+
+public class UUIDTupleBinding extends TupleBinding<UUID>
+{
+ private static final UUIDTupleBinding INSTANCE = new UUIDTupleBinding();
+
+ public UUID entryToObject(final TupleInput tupleInput)
+ {
+ return new UUID(tupleInput.readLong(), tupleInput.readLong());
+ }
+
+ public void objectToEntry(final UUID uuid, final TupleOutput tupleOutput)
+ {
+ tupleOutput.writeLong(uuid.getMostSignificantBits());
+ tupleOutput.writeLong(uuid.getLeastSignificantBits());
+ }
+
+ public static UUIDTupleBinding getInstance()
+ {
+ return INSTANCE;
+ }
+
+
+}
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/QueueEntryTB.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/QueueEntryTB.java
index 975e558874..68f1e7ce6f 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/QueueEntryTB.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/QueueEntryTB.java
@@ -33,7 +33,7 @@ public class QueueEntryTB extends TupleBinding<QueueEntryKey>
public QueueEntryKey entryToObject(TupleInput tupleInput)
{
AMQShortString queueName = AMQShortStringEncoding.readShortString(tupleInput);
- Long messageId = tupleInput.readLong();
+ long messageId = tupleInput.readLong();
return new QueueEntryKey(queueName, messageId);
}
diff --git a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreTest.java b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreTest.java
index ef31b78cfe..6c890daaca 100644
--- a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreTest.java
+++ b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreTest.java
@@ -32,13 +32,11 @@ import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.framing.MethodRegistry;
import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
-import org.apache.qpid.server.message.MessageMetaData;
-import org.apache.qpid.server.message.MessageMetaData_0_10;
+import org.apache.qpid.server.message.*;
import org.apache.qpid.server.store.MessageMetaDataType;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.StorableMessageMetaData;
import org.apache.qpid.server.store.StoredMessage;
-import org.apache.qpid.server.store.TransactionLog;
import org.apache.qpid.server.store.TransactionLogResource;
import org.apache.qpid.transport.DeliveryProperties;
import org.apache.qpid.transport.Header;
@@ -100,7 +98,7 @@ public class BDBMessageStoreTest extends org.apache.qpid.server.store.MessageSto
*/
MessageProperties msgProps_0_10 = createMessageProperties_0_10(bodySize);
DeliveryProperties delProps_0_10 = createDeliveryProperties_0_10();
- Header header_0_10 = new Header(msgProps_0_10, delProps_0_10);
+ Header header_0_10 = new Header(delProps_0_10, msgProps_0_10);
MessageTransfer xfr_0_10 = new MessageTransfer("destination", MessageAcceptMode.EXPLICIT,
MessageAcquireMode.PRE_ACQUIRED, header_0_10, completeContentBody_0_10);
@@ -162,7 +160,7 @@ public class BDBMessageStoreTest extends org.apache.qpid.server.store.MessageSto
assertEquals("Message arrival time has changed", origArrivalTime_0_10, returnedMMD_0_10.getArrivalTime());
- DeliveryProperties returnedDelProps_0_10 = returnedMMD_0_10.getHeader().get(DeliveryProperties.class);
+ DeliveryProperties returnedDelProps_0_10 = returnedMMD_0_10.getHeader().getDeliveryProperties();
assertNotNull("DeliveryProperties were not returned", returnedDelProps_0_10);
assertEquals("Immediate flag has changed", delProps_0_10.getImmediate(), returnedDelProps_0_10.getImmediate());
assertEquals("Routing key has changed", delProps_0_10.getRoutingKey(), returnedDelProps_0_10.getRoutingKey());
@@ -170,7 +168,7 @@ public class BDBMessageStoreTest extends org.apache.qpid.server.store.MessageSto
assertEquals("Message expiration has changed", delProps_0_10.getExpiration(), returnedDelProps_0_10.getExpiration());
assertEquals("Message delivery priority has changed", delProps_0_10.getPriority(), returnedDelProps_0_10.getPriority());
- MessageProperties returnedMsgProps = returnedMMD_0_10.getHeader().get(MessageProperties.class);
+ MessageProperties returnedMsgProps = returnedMMD_0_10.getHeader().getMessageProperties();
assertNotNull("MessageProperties were not returned", returnedMsgProps);
assertTrue("Message correlationID has changed", Arrays.equals(msgProps_0_10.getCorrelationId(), returnedMsgProps.getCorrelationId()));
assertEquals("Message content length has changed", msgProps_0_10.getContentLength(), returnedMsgProps.getContentLength());
@@ -352,7 +350,7 @@ public class BDBMessageStoreTest extends org.apache.qpid.server.store.MessageSto
*/
public void testTranCommit() throws Exception
{
- TransactionLog log = getVirtualHost().getTransactionLog();
+ MessageStore log = getVirtualHost().getMessageStore();
BDBMessageStore bdbStore = assertBDBStore(log);
@@ -366,10 +364,10 @@ public class BDBMessageStoreTest extends org.apache.qpid.server.store.MessageSto
}
};
- TransactionLog.Transaction txn = log.newTransaction();
+ MessageStore.Transaction txn = log.newTransaction();
- txn.enqueueMessage(mockQueue, 1L);
- txn.enqueueMessage(mockQueue, 5L);
+ txn.enqueueMessage(mockQueue, new MockMessage(1L));
+ txn.enqueueMessage(mockQueue, new MockMessage(5L));
txn.commitTran();
List<Long> enqueuedIds = bdbStore.getEnqueuedMessages(mockQueueName);
@@ -390,7 +388,7 @@ public class BDBMessageStoreTest extends org.apache.qpid.server.store.MessageSto
*/
public void testTranRollbackBeforeCommit() throws Exception
{
- TransactionLog log = getVirtualHost().getTransactionLog();
+ MessageStore log = getVirtualHost().getMessageStore();
BDBMessageStore bdbStore = assertBDBStore(log);
@@ -404,14 +402,14 @@ public class BDBMessageStoreTest extends org.apache.qpid.server.store.MessageSto
}
};
- TransactionLog.Transaction txn = log.newTransaction();
+ MessageStore.Transaction txn = log.newTransaction();
- txn.enqueueMessage(mockQueue, 21L);
+ txn.enqueueMessage(mockQueue, new MockMessage(21L));
txn.abortTran();
txn = log.newTransaction();
- txn.enqueueMessage(mockQueue, 22L);
- txn.enqueueMessage(mockQueue, 23L);
+ txn.enqueueMessage(mockQueue, new MockMessage(22L));
+ txn.enqueueMessage(mockQueue, new MockMessage(23L));
txn.commitTran();
List<Long> enqueuedIds = bdbStore.getEnqueuedMessages(mockQueueName);
@@ -431,7 +429,7 @@ public class BDBMessageStoreTest extends org.apache.qpid.server.store.MessageSto
*/
public void testTranRollbackAfterCommit() throws Exception
{
- TransactionLog log = getVirtualHost().getTransactionLog();
+ MessageStore log = getVirtualHost().getMessageStore();
BDBMessageStore bdbStore = assertBDBStore(log);
@@ -445,17 +443,17 @@ public class BDBMessageStoreTest extends org.apache.qpid.server.store.MessageSto
}
};
- TransactionLog.Transaction txn = log.newTransaction();
+ MessageStore.Transaction txn = log.newTransaction();
- txn.enqueueMessage(mockQueue, 30L);
+ txn.enqueueMessage(mockQueue, new MockMessage(30L));
txn.commitTran();
txn = log.newTransaction();
- txn.enqueueMessage(mockQueue, 31L);
+ txn.enqueueMessage(mockQueue, new MockMessage(31L));
txn.abortTran();
txn = log.newTransaction();
- txn.enqueueMessage(mockQueue, 32L);
+ txn.enqueueMessage(mockQueue, new MockMessage(32L));
txn.commitTran();
List<Long> enqueuedIds = bdbStore.getEnqueuedMessages(mockQueueName);
@@ -467,4 +465,73 @@ public class BDBMessageStoreTest extends org.apache.qpid.server.store.MessageSto
assertEquals("Second Message is incorrect", 32L, val.longValue());
}
+ private static class MockMessage implements ServerMessage, EnqueableMessage
+ {
+ private long _messageId;
+
+ public MockMessage(long messageId)
+ {
+ _messageId = messageId;
+ }
+
+ public String getRoutingKey()
+ {
+ return null;
+ }
+
+ public AMQMessageHeader getMessageHeader()
+ {
+ return null;
+ }
+
+ public StoredMessage getStoredMessage()
+ {
+ return null;
+ }
+
+ public boolean isPersistent()
+ {
+ return true;
+ }
+
+ public long getSize()
+ {
+ return 0;
+ }
+
+ public boolean isImmediate()
+ {
+ return false;
+ }
+
+ public long getExpiration()
+ {
+ return 0;
+ }
+
+ public MessageReference newReference()
+ {
+ return null;
+ }
+
+ public long getMessageNumber()
+ {
+ return _messageId;
+ }
+
+ public long getArrivalTime()
+ {
+ return 0;
+ }
+
+ public int getContent(ByteBuffer buf, int offset)
+ {
+ return 0;
+ }
+
+ public ByteBuffer getContent(int offset, int length)
+ {
+ return null;
+ }
+ }
}
diff --git a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBUpgradeTest.java b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBUpgradeTest.java
index 8e55e79e01..6d7cca59cf 100644
--- a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBUpgradeTest.java
+++ b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBUpgradeTest.java
@@ -52,7 +52,9 @@ import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl;
import org.apache.qpid.management.common.mbeans.ManagedQueue;
import org.apache.qpid.server.message.MessageMetaData;
-import org.apache.qpid.server.store.TransactionLog;
+import org.apache.qpid.server.message.EnqueableMessage;
+import org.apache.qpid.server.store.MessageStore;
+import org.apache.qpid.server.store.StoredMessage;
import org.apache.qpid.server.store.TransactionLogResource;
import org.apache.qpid.server.store.berkeleydb.keys.MessageContentKey_4;
import org.apache.qpid.server.store.berkeleydb.tuples.MessageContentKeyTupleBindingFactory;
@@ -415,7 +417,7 @@ public class BDBUpgradeTest extends QpidBrokerTestCase
ContentHeaderBody contentHeaderBody = new ContentHeaderBody(classForBasic, 1, props, bodySize);
// add content entry to database
- long messageId = store.getNewMessageId();
+ final long messageId = store.getNewMessageId();
TupleBinding<MessageContentKey> contentKeyTB = new MessageContentKeyTupleBindingFactory(storeVersion).getInstance();
MessageContentKey contentKey = null;
if (storeVersion == VERSION_4)
@@ -451,9 +453,29 @@ public class BDBUpgradeTest extends QpidBrokerTestCase
return queueName.asString();
}
};
- TransactionLog log = (TransactionLog) store;
- TransactionLog.Transaction txn = log.newTransaction();
- txn.enqueueMessage(mockQueue, messageId);
+
+ EnqueableMessage mockMessage = new EnqueableMessage()
+ {
+
+ public long getMessageNumber()
+ {
+ return messageId;
+ }
+
+ public boolean isPersistent()
+ {
+ return true;
+ }
+
+ public StoredMessage getStoredMessage()
+ {
+ return null;
+ }
+ };
+
+ MessageStore log = (MessageStore) store;
+ MessageStore.Transaction txn = log.newTransaction();
+ txn.enqueueMessage(mockQueue, mockMessage);
txn.commitTran();
}
finally
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java
index 593c1616fb..b898e85aa2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java
@@ -111,6 +111,11 @@ public class ManagementExchange implements Exchange, QMFService.Listener
}
+ public void enqueue(ServerMessage message, boolean sync, PostEnqueueAction action) throws AMQException
+ {
+ enqueue(message);
+ }
+
public void enqueue(ServerMessage message, PostEnqueueAction action) throws AMQException
{
enqueue(message);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java
index b98daf7cb1..709b59588d 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java
@@ -21,6 +21,7 @@
package org.apache.qpid.qmf;
+import org.apache.log4j.Logger;
import org.apache.qpid.transport.codec.BBDecoder;
import org.apache.qpid.transport.codec.BBEncoder;
import org.apache.qpid.server.message.ServerMessage;
@@ -32,10 +33,14 @@ import org.apache.qpid.AMQException;
import org.apache.qpid.management.common.mbeans.ManagedConnection;
import java.util.ArrayList;
+import java.util.List;
public class QMFBrokerRequestCommand extends QMFCommand
{
+ private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf");
+
+
public QMFBrokerRequestCommand(QMFCommandHeader header, BBDecoder buf)
{
super(header);
@@ -46,6 +51,8 @@ public class QMFBrokerRequestCommand extends QMFCommand
String exchangeName = message.getMessageHeader().getReplyToExchange();
String queueName = message.getMessageHeader().getReplyToRoutingKey();
+ _qmfLogger.debug("Execute: " + this);
+
QMFCommand[] commands = new QMFCommand[2];
commands[0] = new QMFBrokerResponseCommand(this, virtualHost);
commands[1] = new QMFCommandCompletionCommand(this);
@@ -57,7 +64,7 @@ public class QMFBrokerRequestCommand extends QMFCommand
QMFMessage responseMessage = new QMFMessage(queueName, cmd);
- ArrayList<? extends BaseQueue> queues = exchange.route(responseMessage);
+ List<? extends BaseQueue> queues = exchange.route(responseMessage);
for(BaseQueue q : queues)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java
index 26a27cfa19..64edc2f294 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java
@@ -21,6 +21,7 @@
package org.apache.qpid.qmf;
+import org.apache.log4j.Logger;
import org.apache.qpid.transport.codec.BBDecoder;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.message.ServerMessage;
@@ -31,9 +32,13 @@ import org.apache.qpid.AMQException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
public class QMFClassQueryCommand extends QMFCommand
{
+ private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf");
+
+
private final String _package;
public QMFClassQueryCommand(QMFCommandHeader header, BBDecoder decoder)
@@ -47,6 +52,8 @@ public class QMFClassQueryCommand extends QMFCommand
String exchangeName = message.getMessageHeader().getReplyToExchange();
String routingKey = message.getMessageHeader().getReplyToRoutingKey();
+ _qmfLogger.debug("Execute: " + this);
+
IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry();
QMFService service = appRegistry.getQMFService();
@@ -71,7 +78,7 @@ public class QMFClassQueryCommand extends QMFCommand
Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName);
- ArrayList<? extends BaseQueue> queues = exchange.route(responseMessage);
+ List<? extends BaseQueue> queues = exchange.route(responseMessage);
for(BaseQueue q : queues)
{
@@ -87,4 +94,12 @@ public class QMFClassQueryCommand extends QMFCommand
}
}
+
+ @Override
+ public String toString()
+ {
+ return "QMFClassQueryCommand{" +
+ "package='" + _package + '\'' +
+ '}';
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java
index f163e434d1..9a25201d4c 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java
@@ -53,4 +53,13 @@ public class QMFCommandCompletionCommand extends QMFCommand
encoder.writeInt32(_status.ordinal());
encoder.writeStr8(_text);
}
+
+ @Override
+ public String toString()
+ {
+ return "QMFCommandCompletionCommand{" +
+ "status=" + _status +
+ ",text='" + _text + '\'' +
+ '}';
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java
index 8e8cb55a0d..c11e1a9b27 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java
@@ -21,6 +21,7 @@
package org.apache.qpid.qmf;
+import org.apache.log4j.Logger;
import org.apache.qpid.transport.codec.BBDecoder;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.message.ServerMessage;
@@ -33,28 +34,22 @@ import java.util.*;
public class QMFGetQueryCommand extends QMFCommand
{
- private Map<String, Object> _map;
+ private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf");
+
+ private String _className;
+ private String _packageName;
+ private UUID _objectId;
public QMFGetQueryCommand(QMFCommandHeader header, BBDecoder decoder)
{
super(header);
- _map = decoder.readMap();
- }
-
- public void process(VirtualHost virtualHost, ServerMessage message)
- {
- String exchangeName = message.getMessageHeader().getReplyToExchange();
- String routingKey = message.getMessageHeader().getReplyToRoutingKey();
-
- IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry();
- QMFService service = appRegistry.getQMFService();
-
- String className = (String) _map.get("_class");
- String packageName = (String) _map.get("_package");
+ Map<String, Object> _map = decoder.readMap();
+ _className = (String) _map.get("_class");
+ _packageName = (String) _map.get("_package");
byte[] objectIdBytes = (byte[]) _map.get("_objectId");
- UUID objectId;
+
if(objectIdBytes != null)
{
long msb = 0;
@@ -68,21 +63,34 @@ public class QMFGetQueryCommand extends QMFCommand
{
lsb = (lsb << 8) | (objectIdBytes[i] & 0xff);
}
- objectId = new UUID(msb, lsb);
+ _objectId = new UUID(msb, lsb);
}
else
{
- objectId = null;
+ _objectId = null;
}
+
+ }
+
+ public void process(VirtualHost virtualHost, ServerMessage message)
+ {
+ String exchangeName = message.getMessageHeader().getReplyToExchange();
+ String routingKey = message.getMessageHeader().getReplyToRoutingKey();
+
+ IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry();
+ QMFService service = appRegistry.getQMFService();
+
+ _qmfLogger.debug("Execute: " + this);
+
List<QMFCommand> commands = new ArrayList<QMFCommand>();
final long sampleTime = System.currentTimeMillis() * 1000000l;
Collection<QMFPackage> packages;
- if(packageName != null && packageName.length() != 0)
+ if(_packageName != null && _packageName.length() != 0)
{
- QMFPackage qmfPackage = service.getPackage(packageName);
+ QMFPackage qmfPackage = service.getPackage(_packageName);
if(qmfPackage == null)
{
packages = Collections.EMPTY_LIST;
@@ -102,9 +110,9 @@ public class QMFGetQueryCommand extends QMFCommand
Collection<QMFClass> qmfClasses;
- if(className != null && className.length() != 0)
+ if(_className != null && _className.length() != 0)
{
- QMFClass qmfClass = qmfPackage.getQMFClass(className);
+ QMFClass qmfClass = qmfPackage.getQMFClass(_className);
if(qmfClass == null)
{
qmfClasses = Collections.EMPTY_LIST;
@@ -124,9 +132,9 @@ public class QMFGetQueryCommand extends QMFCommand
{
Collection<QMFObject> objects;
- if(objectId != null)
+ if(_objectId != null)
{
- QMFObject obj = service.getObjectById(qmfClass, objectId);
+ QMFObject obj = service.getObjectById(qmfClass, _objectId);
if(obj == null)
{
objects = Collections.EMPTY_LIST;
@@ -158,12 +166,12 @@ public class QMFGetQueryCommand extends QMFCommand
for(QMFCommand cmd : commands)
{
-
+ _qmfLogger.debug("Respond: " + cmd);
QMFMessage responseMessage = new QMFMessage(routingKey, cmd);
Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName);
- ArrayList<? extends BaseQueue> queues = exchange.route(responseMessage);
+ List<? extends BaseQueue> queues = exchange.route(responseMessage);
for(BaseQueue q : queues)
{
@@ -179,4 +187,13 @@ public class QMFGetQueryCommand extends QMFCommand
}
}
+ @Override
+ public String toString()
+ {
+ return "QMFGetQueryCommand{" +
+ "packageName='" + _packageName + '\'' +
+ ", className='" + _className + '\'' +
+ ", objectId=" + _objectId +
+ '}';
+ }
} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java
index 3f6290dedb..3248a5aae0 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java
@@ -21,14 +21,17 @@
package org.apache.qpid.qmf;
+import org.apache.commons.lang.NotImplementedException;
+import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.configuration.SessionConfig;
import org.apache.qpid.server.message.*;
+import org.apache.qpid.server.store.StoredMessage;
import org.apache.qpid.transport.codec.BBEncoder;
import java.nio.ByteBuffer;
import java.util.Set;
-public class QMFMessage implements ServerMessage<QMFMessage>, InboundMessage, AMQMessageHeader
+public class QMFMessage implements ServerMessage, InboundMessage, AMQMessageHeader
{
private ByteBuffer _content;
@@ -59,11 +62,21 @@ public class QMFMessage implements ServerMessage<QMFMessage>, InboundMessage, AM
return _routingKey;
}
+ public AMQShortString getRoutingKeyShortString()
+ {
+ return AMQShortString.valueOf(_routingKey);
+ }
+
public AMQMessageHeader getMessageHeader()
{
return this;
}
+ public StoredMessage getStoredMessage()
+ {
+ throw new NotImplementedException();
+ }
+
public boolean isPersistent()
{
return false;
@@ -159,9 +172,9 @@ public class QMFMessage implements ServerMessage<QMFMessage>, InboundMessage, AM
return new QMFMessageReference(this);
}
- public Long getMessageNumber()
+ public long getMessageNumber()
{
- return null;
+ return 0l;
}
public long getArrivalTime()
@@ -172,9 +185,9 @@ public class QMFMessage implements ServerMessage<QMFMessage>, InboundMessage, AM
public int getContent(ByteBuffer buf, int offset)
{
ByteBuffer src = _content.duplicate();
- _content.position(offset);
- _content = _content.slice();
- int len = _content.remaining();
+ src.position(offset);
+ src = src.slice();
+ int len = src.remaining();
if(len > buf.remaining())
{
len = buf.remaining();
@@ -185,6 +198,16 @@ public class QMFMessage implements ServerMessage<QMFMessage>, InboundMessage, AM
return len;
}
+
+ public ByteBuffer getContent(int offset, int size)
+ {
+ ByteBuffer src = _content.duplicate();
+ src.position(offset);
+ src = src.slice();
+ src.limit(size);
+ return src;
+ }
+
private static class QMFMessageReference extends MessageReference<QMFMessage>
{
public QMFMessageReference(QMFMessage message)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java
index cf27e4b970..4001a2a321 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.qmf;
+import org.apache.log4j.Logger;
import org.apache.qpid.transport.codec.BBDecoder;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.message.ServerMessage;
@@ -27,11 +28,14 @@ import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.AMQException;
+import java.util.List;
import java.util.UUID;
import java.util.ArrayList;
public class QMFMethodRequestCommand extends QMFCommand
{
+ private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf");
+
private QMFMethodInvocation _methodInstance;
private QMFObject _object;
@@ -58,6 +62,9 @@ public class QMFMethodRequestCommand extends QMFCommand
String queueName = message.getMessageHeader().getReplyToRoutingKey();
QMFCommand[] commands = new QMFCommand[2];
+
+ _qmfLogger.debug("Execute: " + _methodInstance + " on " + _object);
+
commands[0] = _methodInstance.execute(_object, this);
commands[1] = new QMFCommandCompletionCommand(this);
@@ -68,7 +75,7 @@ public class QMFMethodRequestCommand extends QMFCommand
QMFMessage responseMessage = new QMFMessage(queueName, cmd);
- ArrayList<? extends BaseQueue> queues = exchange.route(responseMessage);
+ List<? extends BaseQueue> queues = exchange.route(responseMessage);
for(BaseQueue q : queues)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java
index d126717fc8..631bd3c7cc 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java
@@ -73,4 +73,9 @@ public abstract class QMFObject<C extends QMFClass, D extends QMFObject.Delegate
abstract public QMFCommand asInstrumentInfoCmd(long sampleTime);
abstract public QMFCommand asGetQueryResponseCmd(final QMFGetQueryCommand queryCommand, long sampleTime);
+ @Override
+ public String toString()
+ {
+ return _delegate.toString();
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java
index 6defd088de..9cacbafcc1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java
@@ -21,6 +21,7 @@
package org.apache.qpid.qmf;
+import org.apache.log4j.Logger;
import org.apache.qpid.transport.codec.BBDecoder;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.message.ServerMessage;
@@ -31,9 +32,13 @@ import org.apache.qpid.AMQException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
public class QMFPackageQueryCommand extends QMFCommand
{
+
+ private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf");
+
public QMFPackageQueryCommand(QMFCommandHeader header, BBDecoder decoder)
{
super(header);
@@ -52,6 +57,8 @@ public class QMFPackageQueryCommand extends QMFCommand
QMFCommand[] commands = new QMFCommand[ supportedSchemas.size() + 1 ];
+ _qmfLogger.debug("Exectuting " + this);
+
int i = 0;
for(QMFPackage p : supportedSchemas)
{
@@ -67,7 +74,7 @@ public class QMFPackageQueryCommand extends QMFCommand
Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName);
- ArrayList<? extends BaseQueue> queues = exchange.route(responseMessage);
+ List<? extends BaseQueue> queues = exchange.route(responseMessage);
for(BaseQueue q : queues)
@@ -83,4 +90,9 @@ public class QMFPackageQueryCommand extends QMFCommand
}
}
}
+
+ public String toString()
+ {
+ return "QMFPackageQueryCommand";
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java
index 3141676f10..a1260ed9e6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java
@@ -21,6 +21,7 @@
package org.apache.qpid.qmf;
+import org.apache.log4j.Logger;
import org.apache.qpid.transport.codec.BBDecoder;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.message.ServerMessage;
@@ -31,9 +32,12 @@ import org.apache.qpid.AMQException;
import java.util.Collection;
import java.util.ArrayList;
+import java.util.List;
public class QMFSchemaRequestCommand extends QMFCommand
{
+ private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf");
+
private final String _packageName;
private final String _className;
private final byte[] _hash;
@@ -48,6 +52,8 @@ public class QMFSchemaRequestCommand extends QMFCommand
public void process(VirtualHost virtualHost, ServerMessage message)
{
+ _qmfLogger.debug("Execute: " + this);
+
String exchangeName = message.getMessageHeader().getReplyToExchange();
String routingKey = message.getMessageHeader().getReplyToRoutingKey();
@@ -70,7 +76,7 @@ public class QMFSchemaRequestCommand extends QMFCommand
QMFMessage responseMessage = new QMFMessage(routingKey, cmd);
- ArrayList<? extends BaseQueue> queues = exchange.route(responseMessage);
+ List<? extends BaseQueue> queues = exchange.route(responseMessage);
for(BaseQueue q : queues)
{
@@ -85,4 +91,13 @@ public class QMFSchemaRequestCommand extends QMFCommand
}
}
}
+
+ @Override
+ public String toString()
+ {
+ return "QMFSchemaRequestCommand{" +
+ " packageName='" + _packageName + '\'' +
+ ", className='" + _className + '\'' +
+ '}';
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
index 6abef6fd6b..27345f0a88 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
@@ -410,7 +410,10 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
ConcurrentHashMap<UUID, QMFObject> map = _managedObjectsById.get(qmfclass);
if(map != null)
{
- return map.get(id);
+
+ UUID key = new UUID(id.getMostSignificantBits() & (0xFFFl << 48), id.getLeastSignificantBits());
+ return map.get(key);
+
}
else
{
@@ -604,6 +607,11 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
{
return _obj.getCreateTime();
}
+
+ public String toString()
+ {
+ return _obj.toString();
+ }
}
private class BrokerDelegate implements BrokerSchema.BrokerDelegate
@@ -762,6 +770,11 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
{
return _obj.getCreateTime();
}
+
+ public String toString()
+ {
+ return _obj.toString();
+ }
}
private class VhostDelegate implements BrokerSchema.VhostDelegate
@@ -797,6 +810,11 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
{
return _obj.getCreateTime();
}
+
+ public String toString()
+ {
+ return _obj.toString();
+ }
}
private class ExchangeDelegate implements BrokerSchema.ExchangeDelegate
@@ -923,6 +941,11 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
{
return _obj.getCreateTime();
}
+
+ public String toString()
+ {
+ return _obj.toString();
+ }
}
private class QueueDelegate implements BrokerSchema.QueueDelegate
@@ -1163,6 +1186,11 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
{
return _obj.getCreateTime();
}
+
+ public String toString()
+ {
+ return _obj.toString();
+ }
}
private class BindingDelegate implements BrokerSchema.BindingDelegate
@@ -1214,6 +1242,11 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
{
return _obj.getCreateTime();
}
+
+ public String toString()
+ {
+ return _obj.toString();
+ }
}
private class ConnectionDelegate implements BrokerSchema.ConnectionDelegate
@@ -1352,6 +1385,12 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
// TODO
return 0;
}
+
+
+ public String toString()
+ {
+ return _obj.toString();
+ }
}
private class SessionDelegate implements BrokerSchema.SessionDelegate
@@ -1476,6 +1515,11 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
{
return _obj.getCreateTime();
}
+
+ public String toString()
+ {
+ return _obj.toString();
+ }
}
private class SubscriptionDelegate implements BrokerSchema.SubscriptionDelegate
@@ -1542,93 +1586,103 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
{
return _obj.getCreateTime();
}
- }
- private class BridgeDelegate implements BrokerSchema.BridgeDelegate
+ public String toString()
{
- private final BridgeConfig _obj;
+ return _obj.toString();
+ }
+ }
- private BridgeDelegate(final BridgeConfig obj)
- {
- _obj = obj;
- }
+ private class BridgeDelegate implements BrokerSchema.BridgeDelegate
+ {
+ private final BridgeConfig _obj;
- public BrokerSchema.LinkObject getLinkRef()
- {
- return (BrokerSchema.LinkObject) adapt(_obj.getLink());
- }
+ private BridgeDelegate(final BridgeConfig obj)
+ {
+ _obj = obj;
+ }
- public Integer getChannelId()
- {
- return _obj.getChannelId();
- }
+ public BrokerSchema.LinkObject getLinkRef()
+ {
+ return (BrokerSchema.LinkObject) adapt(_obj.getLink());
+ }
- public Boolean getDurable()
- {
- return _obj.isDurable();
- }
+ public Integer getChannelId()
+ {
+ return _obj.getChannelId();
+ }
- public String getSrc()
- {
- return _obj.getSource();
- }
+ public Boolean getDurable()
+ {
+ return _obj.isDurable();
+ }
- public String getDest()
- {
- return _obj.getDestination();
- }
+ public String getSrc()
+ {
+ return _obj.getSource();
+ }
- public String getKey()
- {
- return _obj.getKey();
- }
+ public String getDest()
+ {
+ return _obj.getDestination();
+ }
- public Boolean getSrcIsQueue()
- {
- return _obj.isQueueBridge();
- }
+ public String getKey()
+ {
+ return _obj.getKey();
+ }
- public Boolean getSrcIsLocal()
- {
- return _obj.isLocalSource();
- }
+ public Boolean getSrcIsQueue()
+ {
+ return _obj.isQueueBridge();
+ }
- public String getTag()
- {
- return _obj.getTag();
- }
+ public Boolean getSrcIsLocal()
+ {
+ return _obj.isLocalSource();
+ }
- public String getExcludes()
- {
- return _obj.getExcludes();
- }
+ public String getTag()
+ {
+ return _obj.getTag();
+ }
- public Boolean getDynamic()
- {
- return _obj.isDynamic();
- }
+ public String getExcludes()
+ {
+ return _obj.getExcludes();
+ }
- public Integer getSync()
- {
- return _obj.getAckBatching();
- }
+ public Boolean getDynamic()
+ {
+ return _obj.isDynamic();
+ }
- public BrokerSchema.BridgeClass.CloseMethodResponseCommand close(final BrokerSchema.BridgeClass.CloseMethodResponseCommandFactory factory)
- {
- return null;
- }
+ public Integer getSync()
+ {
+ return _obj.getAckBatching();
+ }
- public UUID getId()
- {
- return _obj.getId();
- }
+ public BrokerSchema.BridgeClass.CloseMethodResponseCommand close(final BrokerSchema.BridgeClass.CloseMethodResponseCommandFactory factory)
+ {
+ return null;
+ }
- public long getCreateTime()
- {
- return _obj.getCreateTime();
- }
+ public UUID getId()
+ {
+ return _obj.getId();
}
+ public long getCreateTime()
+ {
+ return _obj.getCreateTime();
+ }
+
+ public String toString()
+ {
+ return _obj.toString();
+ }
+ }
+
private class LinkDelegate implements BrokerSchema.LinkDelegate
{
private final LinkConfig _obj;
@@ -1665,14 +1719,12 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
public String getState()
{
- // TODO
- return "";
+ return _obj.getState();
}
public String getLastError()
{
- // TODO
- return "";
+ return _obj.getLastError();
}
public BrokerSchema.LinkClass.CloseMethodResponseCommand close(final BrokerSchema.LinkClass.CloseMethodResponseCommandFactory factory)
@@ -1706,6 +1758,12 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
{
return _obj.getCreateTime();
}
+
+ @Override
+ public String toString()
+ {
+ return _obj.toString();
+ }
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
index 30d620401f..873c846258 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
@@ -96,7 +96,7 @@ import java.util.concurrent.atomic.AtomicLong;
public class AMQChannel implements SessionConfig, AMQSessionModel
{
- public static final int DEFAULT_PREFETCH = 5000;
+ public static final int DEFAULT_PREFETCH = 4096;
private static final Logger _logger = Logger.getLogger(AMQChannel.class);
@@ -167,6 +167,8 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
private final UUID _id;
private long _createTime = System.currentTimeMillis();
+ private final ClientDeliveryMethod _clientDeliveryMethod;
+
public AMQChannel(AMQProtocolSession session, int channelId, MessageStore messageStore)
throws AMQException
{
@@ -184,6 +186,8 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
// by default the session is non-transactional
_transaction = new AutoCommitTransaction(_messageStore);
+
+ _clientDeliveryMethod = session.createDeliveryMethod(_channelId);
}
public ConfigStore getConfigStore()
@@ -206,6 +210,11 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
return !(_transaction instanceof AutoCommitTransaction);
}
+ public void receivedComplete()
+ {
+ }
+
+
public boolean inTransaction()
{
return isTransactional() && _txnUpdateTime.get() > 0 && _transaction.getTransactionStartTime() > 0;
@@ -285,7 +294,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
_currentMessage.setExpiration();
- MessageMetaData mmd = _currentMessage.headersReceived();
+ MessageMetaData mmd = _currentMessage.headersReceived(getProtocolSession().getLastReceivedTime());
final StoredMessage<MessageMetaData> handle = _messageStore.addMessage(mmd);
_currentMessage.setStoredMessage(handle);
@@ -317,8 +326,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
{
try
{
- _currentMessage.getStoredMessage().flushToStore();
- final ArrayList<? extends BaseQueue> destinationQueues = _currentMessage.getDestinationQueues();
+ final List<? extends BaseQueue> destinationQueues = _currentMessage.getDestinationQueues();
if(!checkMessageUserId(_currentMessage.getContentHeader()))
{
@@ -340,11 +348,13 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
}
else
{
- _transaction.enqueue(destinationQueues, _currentMessage, new MessageDeliveryAction(_currentMessage, destinationQueues, isTransactional()));
+ _transaction.enqueue(destinationQueues, _currentMessage, new MessageDeliveryAction(_currentMessage, destinationQueues), getProtocolSession().getLastReceivedTime());
incrementOutstandingTxnsIfNecessary();
updateTransactionalActivity();
}
}
+ _currentMessage.getStoredMessage().flushToStore();
+
}
finally
{
@@ -858,10 +868,8 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
private Collection<QueueEntry> getAckedMessages(long deliveryTag, boolean multiple)
{
- Map<Long, QueueEntry> ackedMessageMap = new LinkedHashMap<Long,QueueEntry>();
- _unacknowledgedMessageMap.collect(deliveryTag, multiple, ackedMessageMap);
- _unacknowledgedMessageMap.remove(ackedMessageMap);
- return ackedMessageMap.values();
+ return _unacknowledgedMessageMap.acknowledge(deliveryTag, multiple);
+
}
/**
@@ -950,12 +958,17 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
public void commit() throws AMQException
{
+ commit(null);
+ }
+ public void commit(Runnable immediateAction) throws AMQException
+ {
+
if (!isTransactional())
{
throw new AMQException("Fatal error: commit called on non-transactional channel");
}
- _transaction.commit();
+ _transaction.commit(immediateAction);
_txnCommits.incrementAndGet();
_txnStarts.incrementAndGet();
@@ -1034,7 +1047,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
{
if (isTransactional())
{
- _txnUpdateTime.set(System.currentTimeMillis());
+ _txnUpdateTime.set(getProtocolSession().getLastReceivedTime());
}
}
@@ -1080,21 +1093,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
return _messageStore;
}
- private final ClientDeliveryMethod _clientDeliveryMethod = new ClientDeliveryMethod()
- {
-
- public void deliverToClient(final Subscription sub, final QueueEntry entry, final long deliveryTag)
- throws AMQException
- {
- _session.registerMessageDelivered(entry.getMessage().getSize());
- getProtocolSession().getProtocolOutputConverter().writeDeliver(entry, getChannelId(),
- deliveryTag,
- ((SubscriptionImpl)sub).getConsumerTag());
- entry.incrementDeliveryCount();
- }
-
- };
-
public ClientDeliveryMethod getClientDeliveryMethod()
{
return _clientDeliveryMethod;
@@ -1160,11 +1158,10 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
private class MessageDeliveryAction implements ServerTransaction.Action
{
private IncomingMessage _incommingMessage;
- private ArrayList<? extends BaseQueue> _destinationQueues;
+ private List<? extends BaseQueue> _destinationQueues;
public MessageDeliveryAction(IncomingMessage currentMessage,
- ArrayList<? extends BaseQueue> destinationQueues,
- boolean transactional)
+ List<? extends BaseQueue> destinationQueues)
{
_incommingMessage = currentMessage;
_destinationQueues = destinationQueues;
@@ -1179,8 +1176,10 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
final AMQMessage amqMessage = createAMQMessage(_incommingMessage);
MessageReference ref = amqMessage.newReference();
- for(final BaseQueue queue : _destinationQueues)
+ for(int i = 0; i < _destinationQueues.size(); i++)
{
+ BaseQueue queue = _destinationQueues.get(i);
+
BaseQueue.PostEnqueueAction action;
if(immediate)
@@ -1192,7 +1191,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
action = null;
}
- queue.enqueue(amqMessage, action);
+ queue.enqueue(amqMessage, isTransactional(), action);
if(queue instanceof AMQQueue)
{
@@ -1200,6 +1199,8 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
}
}
+
+ _incommingMessage.getStoredMessage().flushToStore();
ref.release();
}
catch (AMQException e)
@@ -1541,7 +1542,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
final InboundMessage m = new InboundMessageAdapter(rejectedQueueEntry);
- final ArrayList<? extends BaseQueue> destinationQueues = altExchange.route(m);
+ final List<? extends BaseQueue> destinationQueues = altExchange.route(m);
if (destinationQueues == null || destinationQueues.isEmpty())
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/ExtractResendAndRequeue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/ExtractResendAndRequeue.java
index 9da02e0600..9765636c25 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/ExtractResendAndRequeue.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/ExtractResendAndRequeue.java
@@ -22,8 +22,8 @@ package org.apache.qpid.server;
import org.apache.qpid.server.ack.UnacknowledgedMessageMap;
import org.apache.qpid.server.queue.QueueEntry;
+import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.subscription.Subscription;
-import org.apache.qpid.server.store.TransactionLog;
import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.server.txn.AutoCommitTransaction;
import org.apache.qpid.AMQException;
@@ -39,13 +39,13 @@ public class ExtractResendAndRequeue implements UnacknowledgedMessageMap.Visitor
private final Map<Long, QueueEntry> _msgToResend;
private final boolean _requeueIfUnabletoResend;
private final UnacknowledgedMessageMap _unacknowledgedMessageMap;
- private final TransactionLog _transactionLog;
+ private final MessageStore _transactionLog;
public ExtractResendAndRequeue(UnacknowledgedMessageMap unacknowledgedMessageMap,
Map<Long, QueueEntry> msgToRequeue,
Map<Long, QueueEntry> msgToResend,
boolean requeueIfUnabletoResend,
- TransactionLog txnLog)
+ MessageStore txnLog)
{
_unacknowledgedMessageMap = unacknowledgedMessageMap;
_msgToRequeue = msgToRequeue;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java
index 0c038c7800..2bfdd93030 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java
@@ -27,6 +27,7 @@ import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
+import org.apache.log4j.Logger;
import org.apache.qpid.server.Broker.InitException;
import org.apache.qpid.server.registry.ApplicationRegistry;
@@ -230,11 +231,77 @@ public class Main
{
parsePortArray(options, commandLine.getOptionValues(pe.getExcludeName()), pe);
}
- }
+ }
+
+ setExceptionHandler();
startBroker(options);
}
+ protected void setExceptionHandler()
+ {
+ Thread.UncaughtExceptionHandler handler = null;
+ String handlerClass = System.getProperty("qpid.broker.exceptionHandler");
+ if(handlerClass != null)
+ {
+ try
+ {
+ handler = (Thread.UncaughtExceptionHandler) Class.forName(handlerClass).newInstance();
+ }
+ catch (ClassNotFoundException e)
+ {
+
+ }
+ catch (InstantiationException e)
+ {
+
+ }
+ catch (IllegalAccessException e)
+ {
+
+ }
+ catch (ClassCastException e)
+ {
+
+ }
+ }
+
+ if(handler == null)
+ {
+ handler =
+ new Thread.UncaughtExceptionHandler()
+ {
+ public void uncaughtException(final Thread t, final Throwable e)
+ {
+ try
+ {
+ System.err.println("########################################################################");
+ System.err.println("#");
+ System.err.print("# Unhandled Exception ");
+ System.err.print(e.toString());
+ System.err.print(" in Thread ");
+ System.err.println(t.getName());
+ System.err.println("#");
+ System.err.println("# Exiting");
+ System.err.println("#");
+ System.err.println("########################################################################");
+ e.printStackTrace(System.err);
+
+ Logger logger = Logger.getLogger("org.apache.qpid.server.Main");
+ logger.error("Uncaught exception, shutting down.", e);
+ }
+ finally
+ {
+ Runtime.getRuntime().halt(1);
+ }
+
+ }
+ };
+
+ Thread.setDefaultUncaughtExceptionHandler(handler);
+ }
+ }
+
protected void startBroker(final BrokerOptions options) throws Exception
{
Broker broker = new Broker();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMap.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMap.java
index 3bad73d86d..f4b4932744 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMap.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMap.java
@@ -46,10 +46,6 @@ public interface UnacknowledgedMessageMap
void add(long deliveryTag, QueueEntry message);
- void collect(long deliveryTag, boolean multiple, Map<Long, QueueEntry> msgs);
-
- void remove(Map<Long,QueueEntry> msgs);
-
QueueEntry remove(long deliveryTag);
Collection<QueueEntry> cancelAllMessages();
@@ -67,6 +63,8 @@ public interface UnacknowledgedMessageMap
*/
Set<Long> getDeliveryTags();
+ Collection<QueueEntry> acknowledge(long deliveryTag, boolean multiple);
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java
index d920d97c1a..6a5d863526 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java
@@ -157,6 +157,14 @@ public class UnacknowledgedMessageMapImpl implements UnacknowledgedMessageMap
}
}
+ public Collection<QueueEntry> acknowledge(long deliveryTag, boolean multiple)
+ {
+ Map<Long, QueueEntry> ackedMessageMap = new LinkedHashMap<Long,QueueEntry>();
+ collect(deliveryTag, multiple, ackedMessageMap);
+ remove(ackedMessageMap);
+ return ackedMessageMap.values();
+ }
+
private void collect(long key, Map<Long, QueueEntry> msgs)
{
synchronized (_lock)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java
index 60c9a86b76..48f85d9bc9 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java
@@ -115,4 +115,9 @@ public class Binding
return result;
}
+ public String toString()
+ {
+ return "Binding{bindingKey="+_bindingKey+", exchange="+_exchange+", queue="+_queue+"}";
+ }
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java
index 0e03e33be8..4e031f0a84 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java
@@ -40,7 +40,10 @@ public class ConfigStore
private AtomicReference<SystemConfig> _root = new AtomicReference<SystemConfig>(null);
private final AtomicLong _objectIdSource = new AtomicLong(0l);
+ private final AtomicLong _persistentObjectIdSource = new AtomicLong(0l);
+ // TODO - should load/increment this on broker startup
+ private long _sequenceNumber = 1L;
public enum Event
{
@@ -167,9 +170,23 @@ public class ConfigStore
public UUID createId()
{
- return new UUID(0l, _objectIdSource.getAndIncrement());
+ return new UUID(((_sequenceNumber & 0xFFFl)<<48), _objectIdSource.incrementAndGet());
}
+ public UUID createPersistentId()
+ {
+ return new UUID(0L, _persistentObjectIdSource.incrementAndGet());
+ }
+
+ public void persistentIdInUse(UUID id)
+ {
+ long lsb = id.getLeastSignificantBits();
+ long currentId;
+ while((currentId = _persistentObjectIdSource.get()) < lsb)
+ {
+ _persistentObjectIdSource.compareAndSet(currentId, lsb);
+ }
+ }
public SystemConfig getRoot()
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java
index 5a6159df34..0b3a9076dd 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java
@@ -54,4 +54,8 @@ public interface LinkConfig extends ConfiguredObject<LinkConfigType, LinkConfig>
String src,
String dest,
String key, String tag, String excludes);
+
+ String getState();
+
+ String getLastError();
} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
index 4b42e39aa1..d3b89649c7 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
@@ -89,7 +89,6 @@ public class ServerConfiguration extends ConfigurationPlugin
envVarMap.put("QPID_PORT", "connector.port");
envVarMap.put("QPID_ENABLEDIRECTBUFFERS", "advanced.enableDirectBuffers");
envVarMap.put("QPID_SSLPORT", "connector.ssl.port");
- envVarMap.put("QPID_WRITEBIASED", "advanced.useWriteBiasedPool");
envVarMap.put("QPID_JMXPORT_REGISTRYSERVER", MGMT_JMXPORT_REGISTRYSERVER);
envVarMap.put("QPID_JMXPORT_CONNECTORSERVER", MGMT_JMXPORT_CONNECTORSERVER);
envVarMap.put("QPID_FRAMESIZE", "advanced.framesize");
@@ -736,11 +735,6 @@ public class ServerConfiguration extends ConfigurationPlugin
return getStringValue("connector.ssl.certType", "SunX509");
}
- public boolean getUseBiasedWrites()
- {
- return getBooleanValue("advanced.useWriteBiasedPool");
- }
-
public String getDefaultVirtualHost()
{
return getStringValue("virtualhosts.default");
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
index d693c6962b..5ff90b3499 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
@@ -351,11 +351,11 @@ public abstract class AbstractExchange implements Exchange, Managable
- public final ArrayList<? extends BaseQueue> route(final InboundMessage message)
+ public final List<? extends BaseQueue> route(final InboundMessage message)
{
_receivedMessageCount.incrementAndGet();
_receivedMessageSize.addAndGet(message.getSize());
- final ArrayList<? extends BaseQueue> queues = doRoute(message);
+ final List<? extends BaseQueue> queues = doRoute(message);
if(!queues.isEmpty())
{
_routedMessageCount.incrementAndGet();
@@ -364,7 +364,7 @@ public abstract class AbstractExchange implements Exchange, Managable
return queues;
}
- protected abstract ArrayList<? extends BaseQueue> doRoute(final InboundMessage message);
+ protected abstract List<? extends BaseQueue> doRoute(final InboundMessage message);
public long getMsgReceives()
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
index cb0d8ecf8f..8c0a5001db 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
@@ -34,6 +34,8 @@ import org.apache.qpid.server.virtualhost.VirtualHost;
import javax.management.JMException;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -41,8 +43,52 @@ public class DirectExchange extends AbstractExchange
{
private static final Logger _logger = Logger.getLogger(DirectExchange.class);
- private final ConcurrentHashMap<String, CopyOnWriteArraySet<Binding>> _bindingsByKey =
- new ConcurrentHashMap<String, CopyOnWriteArraySet<Binding>>();
+ private static final class BindingSet
+ {
+ private CopyOnWriteArraySet<Binding> _bindings = new CopyOnWriteArraySet<Binding>();
+ private List<BaseQueue> _queues = new ArrayList<BaseQueue>();
+
+ public synchronized void addBinding(Binding binding)
+ {
+ _bindings.add(binding);
+ recalculateQueues();
+ }
+
+
+ public synchronized void removeBinding(Binding binding)
+ {
+ _bindings.remove(binding);
+ recalculateQueues();
+ }
+
+ private void recalculateQueues()
+ {
+ List<BaseQueue> queues = new ArrayList<BaseQueue>(_bindings.size());
+
+ for(Binding b : _bindings)
+ {
+ if(!queues.contains(b.getQueue()))
+ {
+ queues.add(b.getQueue());
+ }
+ }
+ _queues = queues;
+ }
+
+
+ public List<BaseQueue> getQueues()
+ {
+ return _queues;
+ }
+
+ public CopyOnWriteArraySet<Binding> getBindings()
+ {
+ return _bindings;
+ }
+ }
+
+ private final ConcurrentHashMap<String, BindingSet> _bindingsByKey =
+ new ConcurrentHashMap<String, BindingSet>();
public static final ExchangeType<DirectExchange> TYPE = new ExchangeType<DirectExchange>()
{
@@ -91,33 +137,20 @@ public class DirectExchange extends AbstractExchange
}
- public ArrayList<? extends BaseQueue> doRoute(InboundMessage payload)
+ public List<? extends BaseQueue> doRoute(InboundMessage payload)
{
final String routingKey = payload.getRoutingKey();
- CopyOnWriteArraySet<Binding> bindings = _bindingsByKey.get(routingKey == null ? "" : routingKey);
+ BindingSet bindings = _bindingsByKey.get(routingKey == null ? "" : routingKey);
if(bindings != null)
{
- final ArrayList<BaseQueue> queues = new ArrayList<BaseQueue>(bindings.size());
-
- for(Binding binding : bindings)
- {
- queues.add(binding.getQueue());
- binding.incrementMatches();
- }
-
- if (_logger.isDebugEnabled())
- {
- _logger.debug("Publishing message to queue " + queues);
- }
-
- return queues;
+ return bindings.getQueues();
}
else
{
- return new ArrayList<BaseQueue>(0);
+ return Collections.emptyList();
}
@@ -132,16 +165,10 @@ public class DirectExchange extends AbstractExchange
public boolean isBound(AMQShortString routingKey, AMQQueue queue)
{
String bindingKey = (routingKey == null) ? "" : routingKey.toString();
- CopyOnWriteArraySet<Binding> bindings = _bindingsByKey.get(bindingKey);
+ BindingSet bindings = _bindingsByKey.get(bindingKey);
if(bindings != null)
{
- for(Binding binding : bindings)
- {
- if(binding.getQueue().equals(queue))
- {
- return true;
- }
- }
+ return bindings.getQueues().contains(queue);
}
return false;
@@ -150,22 +177,20 @@ public class DirectExchange extends AbstractExchange
public boolean isBound(AMQShortString routingKey)
{
String bindingKey = (routingKey == null) ? "" : routingKey.toString();
- CopyOnWriteArraySet<Binding> bindings = _bindingsByKey.get(bindingKey);
- return bindings != null && !bindings.isEmpty();
+ BindingSet bindings = _bindingsByKey.get(bindingKey);
+ return bindings != null && !bindings.getQueues().isEmpty();
}
public boolean isBound(AMQQueue queue)
{
- for (CopyOnWriteArraySet<Binding> bindings : _bindingsByKey.values())
+ for (BindingSet bindings : _bindingsByKey.values())
{
- for(Binding binding : bindings)
+ if(bindings.getQueues().contains(queue))
{
- if(binding.getQueue().equals(queue))
- {
- return true;
- }
+ return true;
}
+
}
return false;
}
@@ -184,19 +209,19 @@ public class DirectExchange extends AbstractExchange
assert queue != null;
assert routingKey != null;
- CopyOnWriteArraySet<Binding> bindings = _bindingsByKey.get(bindingKey);
+ BindingSet bindings = _bindingsByKey.get(bindingKey);
if(bindings == null)
{
- bindings = new CopyOnWriteArraySet<Binding>();
- CopyOnWriteArraySet<Binding> newBindings;
+ bindings = new BindingSet();
+ BindingSet newBindings;
if((newBindings = _bindingsByKey.putIfAbsent(bindingKey, bindings)) != null)
{
bindings = newBindings;
}
}
- bindings.add(binding);
+ bindings.addBinding(binding);
}
@@ -204,10 +229,10 @@ public class DirectExchange extends AbstractExchange
{
assert binding != null;
- CopyOnWriteArraySet<Binding> bindings = _bindingsByKey.get(binding.getBindingKey());
+ BindingSet bindings = _bindingsByKey.get(binding.getBindingKey());
if(bindings != null)
{
- bindings.remove(binding);
+ bindings.removeBinding(binding);
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java
index 29a3611709..29c354feae 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java
@@ -36,6 +36,7 @@ import org.apache.qpid.server.configuration.ExchangeConfig;
import javax.management.JMException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
public interface Exchange extends ExchangeReferrer, ExchangeConfig
{
@@ -70,7 +71,7 @@ public interface Exchange extends ExchangeReferrer, ExchangeConfig
*
* @return list of queues to which to route the message.
*/
- ArrayList<? extends BaseQueue> route(InboundMessage message);
+ List<? extends BaseQueue> route(InboundMessage message);
/**
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java
index e523eb24fb..3a8a86e654 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java
@@ -37,8 +37,11 @@ import org.apache.qpid.server.filter.JMSSelectorFilter;
import org.apache.qpid.server.message.InboundMessage;
import javax.management.JMException;
+import java.sql.Array;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+
import java.lang.ref.WeakReference;
public class TopicExchange extends AbstractExchange
@@ -77,8 +80,6 @@ public class TopicExchange extends AbstractExchange
private static final Logger _logger = Logger.getLogger(TopicExchange.class);
-
-
private final TopicParser _parser = new TopicParser();
private final Map<AMQShortString, TopicExchangeResult> _topicExchangeResults =
@@ -175,7 +176,6 @@ public class TopicExchange extends AbstractExchange
_bindings.put(binding, args);
}
-
}
private JMSSelectorFilter createSelectorFilter(final FieldTable args) throws AMQInvalidArgumentException
@@ -201,14 +201,23 @@ public class TopicExchange extends AbstractExchange
public ArrayList<BaseQueue> doRoute(InboundMessage payload)
{
- final AMQShortString routingKey = payload.getRoutingKey() == null
+ final AMQShortString routingKey = payload.getRoutingKeyShortString() == null
? AMQShortString.EMPTY_STRING
- : new AMQShortString(payload.getRoutingKey());
+ : payload.getRoutingKeyShortString();
+
+ final Collection<AMQQueue> matchedQueues = getMatchedQueues(payload, routingKey);
- // The copy here is unfortunate, but not too bad relevant to the amount of
- // things created and copied in getMatchedQueues
- ArrayList<BaseQueue> queues = new ArrayList<BaseQueue>();
- queues.addAll(getMatchedQueues(payload, routingKey));
+ ArrayList<BaseQueue> queues;
+
+ if(matchedQueues.getClass() == ArrayList.class)
+ {
+ queues = (ArrayList) matchedQueues;
+ }
+ else
+ {
+ queues = new ArrayList<BaseQueue>();
+ queues.addAll(matchedQueues);
+ }
if(queues == null || queues.isEmpty())
{
@@ -325,25 +334,28 @@ public class TopicExchange extends AbstractExchange
{
Collection<TopicMatcherResult> results = _parser.parse(routingKey);
- if(results.isEmpty())
+ switch(results.size())
{
- return Collections.EMPTY_SET;
- }
- else
- {
- Collection<AMQQueue> queues = results.size() == 1 ? null : new HashSet<AMQQueue>();
- for(TopicMatcherResult result : results)
- {
- TopicExchangeResult res = (TopicExchangeResult)result;
-
- for(Binding b : res.getBindings())
+ case 0:
+ return Collections.EMPTY_SET;
+ case 1:
+ TopicMatcherResult[] resultQueues = new TopicMatcherResult[1];
+ results.toArray(resultQueues);
+ return ((TopicExchangeResult)resultQueues[0]).processMessage(message, null);
+ default:
+ Collection<AMQQueue> queues = new HashSet<AMQQueue>();
+ for(TopicMatcherResult result : results)
{
- b.incrementMatches();
+ TopicExchangeResult res = (TopicExchangeResult)result;
+
+ for(Binding b : res.getBindings())
+ {
+ b.incrementMatches();
+ }
+
+ queues = res.processMessage(message, queues);
}
-
- queues = res.processMessage(message, queues);
- }
- return queues;
+ return queues;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java
index 41dc0d749a..d8b09a7841 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java
@@ -39,6 +39,7 @@ public final class TopicExchangeResult implements TopicMatcherResult
private final List<Binding> _bindings = new CopyOnWriteArrayList<Binding>();
private final Map<AMQQueue, Integer> _unfilteredQueues = new ConcurrentHashMap<AMQQueue, Integer>();
private final ConcurrentHashMap<AMQQueue, Map<MessageFilter,Integer>> _filteredQueues = new ConcurrentHashMap<AMQQueue, Map<MessageFilter, Integer>>();
+ private volatile ArrayList<AMQQueue> _unfilteredQueueList = new ArrayList<AMQQueue>(0);
public void addUnfilteredQueue(AMQQueue queue)
{
@@ -46,6 +47,9 @@ public final class TopicExchangeResult implements TopicMatcherResult
if(instances == null)
{
_unfilteredQueues.put(queue, 1);
+ ArrayList<AMQQueue> newList = new ArrayList<AMQQueue>(_unfilteredQueueList);
+ newList.add(queue);
+ _unfilteredQueueList = newList;
}
else
{
@@ -59,6 +63,10 @@ public final class TopicExchangeResult implements TopicMatcherResult
if(instances == 1)
{
_unfilteredQueues.remove(queue);
+ ArrayList<AMQQueue> newList = new ArrayList<AMQQueue>(_unfilteredQueueList);
+ newList.remove(queue);
+ _unfilteredQueueList = newList;
+
}
else
{
@@ -166,7 +174,7 @@ public final class TopicExchangeResult implements TopicMatcherResult
{
if(_filteredQueues.isEmpty())
{
- return new ArrayList<AMQQueue>(_unfilteredQueues.keySet());
+ return _unfilteredQueueList;
}
else
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherDFAState.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherDFAState.java
index 36076cf75b..4446536d4c 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherDFAState.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherDFAState.java
@@ -77,7 +77,7 @@ public class TopicMatcherDFAState
}
if(nextState == null)
{
- return Collections.EMPTY_SET;
+ return Collections.EMPTY_LIST;
}
// Shortcut if we are at a looping terminal state
if((nextState == this) && (_nextStateMap.size() == 1) && _nextStateMap.containsKey(TopicWord.ANY_WORD))
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java
index 2dff45c326..4db6ee3ad2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java
@@ -21,6 +21,7 @@
package org.apache.qpid.server.federation;
import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQStoreException;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.configuration.BridgeConfig;
import org.apache.qpid.server.configuration.BridgeConfigType;
@@ -44,32 +45,23 @@ import org.apache.qpid.server.transport.ServerSession;
import org.apache.qpid.server.txn.AutoCommitTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.DeliveryProperties;
-import org.apache.qpid.transport.MessageAcceptMode;
-import org.apache.qpid.transport.MessageAcquireMode;
-import org.apache.qpid.transport.MessageCreditUnit;
-import org.apache.qpid.transport.MessageFlowMode;
-import org.apache.qpid.transport.MessageReject;
-import org.apache.qpid.transport.MessageRejectCode;
-import org.apache.qpid.transport.MessageTransfer;
-import org.apache.qpid.transport.Option;
-import org.apache.qpid.transport.RangeSet;
-import org.apache.qpid.transport.Session;
-import org.apache.qpid.transport.SessionException;
-import org.apache.qpid.transport.SessionListener;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
+import org.apache.qpid.transport.*;
+
+import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class Bridge implements BridgeConfig
{
+ private static final String DURABLE = "durable";
+ private static final String DYNAMIC = "dynamic";
+ private static final String SRC_IS_QUEUE = "srcIsQueue";
+ private static final String SRC_IS_LOCAL = "srcIsLocal";
+ private static final String SOURCE = "source";
+ private static final String DESTINATION = "destination";
+ private static final String KEY = "key";
+ private static final String TAG = "tag";
+ private static final String EXCLUDES = "excludes";
private final boolean _durable;
private final boolean _dynamic;
private final boolean _queueBridge;
@@ -113,19 +105,36 @@ public class Bridge implements BridgeConfig
_key = key;
_tag = tag;
_excludes = excludes;
- _id = brokerLink.getConfigStore().createId();
+ _id = durable ? brokerLink.getConfigStore().createPersistentId() : brokerLink.getConfigStore().createId();
_transaction = new AutoCommitTransaction(getVirtualHost().getMessageStore());
- if(dynamic)
+ if(durable)
{
- if(srcIsLocal)
+ try
+ {
+ brokerLink.getVirtualHost().getDurableConfigurationStore().createBridge(this);
+ }
+ catch (AMQStoreException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ createDelegate();
+ }
+
+ private void createDelegate()
+ {
+ if(_dynamic)
+ {
+ if(_localSource)
{
// TODO
}
else
{
- if(srcIsQueue)
+ if(_queueBridge)
{
// TODO
}
@@ -137,9 +146,9 @@ public class Bridge implements BridgeConfig
}
else
{
- if(srcIsLocal)
+ if(_localSource)
{
- if(srcIsQueue)
+ if(_queueBridge)
{
_delegate = new StaticQueuePushBridge();
}
@@ -150,7 +159,7 @@ public class Bridge implements BridgeConfig
}
else
{
- if(srcIsQueue)
+ if(_queueBridge)
{
_delegate = new StaticQueuePullBridge();
}
@@ -162,6 +171,65 @@ public class Bridge implements BridgeConfig
}
}
+ public Bridge(final BrokerLink brokerLink,
+ final int bridgeNo,
+ final UUID id,
+ final long createTime,
+ final Map<String, String> arguments)
+ {
+ _link = brokerLink;
+ _bridgeNo = bridgeNo;
+ _id = id;
+ brokerLink.getConfigStore().persistentIdInUse(id);
+ _createTime = createTime;
+
+ _durable = Boolean.valueOf(arguments.get(DURABLE));
+ _dynamic = Boolean.valueOf(arguments.get(DYNAMIC));
+ _queueBridge = Boolean.valueOf(arguments.get(SRC_IS_QUEUE));
+ _localSource = Boolean.valueOf(arguments.get(SRC_IS_LOCAL));
+ _source = arguments.get(SOURCE);
+ _destination = arguments.get(DESTINATION);
+ _key = arguments.get(KEY);
+ _tag = arguments.get(TAG);
+ _excludes = arguments.get(EXCLUDES);
+
+ //TODO.
+ _transaction = new AutoCommitTransaction(getVirtualHost().getMessageStore());
+
+
+ if(_durable)
+ {
+ try
+ {
+ brokerLink.getVirtualHost().getDurableConfigurationStore().createBridge(this);
+ }
+ catch (AMQStoreException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ createDelegate();
+ }
+
+
+ public Map<String,String> getArguments()
+ {
+ Map<String,String> arguments = new HashMap<String, String>();
+
+ arguments.put(DURABLE, String.valueOf(_durable));
+ arguments.put(DYNAMIC, String.valueOf(_dynamic));
+ arguments.put(SRC_IS_QUEUE, String.valueOf(_queueBridge));
+ arguments.put(SRC_IS_LOCAL, String.valueOf(_localSource));
+ arguments.put(SOURCE, _source);
+ arguments.put(DESTINATION, _destination);
+ arguments.put(KEY, _key);
+ arguments.put(TAG, _tag);
+ arguments.put(EXCLUDES, _excludes);
+
+ return Collections.unmodifiableMap(arguments);
+ }
+
public UUID getId()
{
return _id;
@@ -336,6 +404,7 @@ public class Bridge implements BridgeConfig
}
+
private interface BridgeImpl
{
void setSession(Session session);
@@ -365,7 +434,8 @@ public class Bridge implements BridgeConfig
// TODO - deal with exchange not existing
DeliveryProperties delvProps = null;
- if(xfr.getHeader() != null && (delvProps = xfr.getHeader().get(DeliveryProperties.class)) != null && delvProps.hasTtl() && !delvProps.hasExpiration())
+ if(xfr.getHeader() != null && (delvProps = xfr.getHeader().getDeliveryProperties()) != null && delvProps.hasTtl() &&
+ !delvProps.hasExpiration())
{
delvProps.setExpiration(System.currentTimeMillis() + delvProps.getTtl());
}
@@ -377,7 +447,7 @@ public class Bridge implements BridgeConfig
storeMessage.flushToStore();
MessageTransferMessage message = new MessageTransferMessage(storeMessage, ((ServerSession)_session).getReference());
- ArrayList<? extends BaseQueue> queues = exchange.route(message);
+ List<? extends BaseQueue> queues = exchange.route(message);
@@ -391,7 +461,7 @@ public class Bridge implements BridgeConfig
{
if(xfr.getAcceptMode() == MessageAcceptMode.EXPLICIT)
{
- RangeSet rejects = new RangeSet();
+ RangeSet rejects = RangeSetFactory.createRangeSet();
rejects.add(xfr.getId());
MessageReject reject = new MessageReject(rejects, MessageRejectCode.UNROUTABLE, "Unroutable");
ssn.invoke(reject);
@@ -428,7 +498,7 @@ public class Bridge implements BridgeConfig
}
- private void enqueue(final ServerMessage message, final ArrayList<? extends BaseQueue> queues)
+ private void enqueue(final ServerMessage message, final List<? extends BaseQueue> queues)
{
_transaction.enqueue(queues,message, new ServerTransaction.Action()
{
@@ -456,8 +526,7 @@ public class Bridge implements BridgeConfig
{
// NO-OP
}
- });
-
+ }, 0L);
}
public void exception(final Session session, final SessionException exception)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java
index f330e2f708..a8f75d2b9b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.federation;
+import org.apache.qpid.AMQStoreException;
import org.apache.qpid.common.ServerPropertyNames;
import org.apache.qpid.server.configuration.ConfigStore;
import org.apache.qpid.server.configuration.ConfiguredObject;
@@ -29,16 +30,19 @@ import org.apache.qpid.server.configuration.LinkConfig;
import org.apache.qpid.server.configuration.LinkConfigType;
import org.apache.qpid.server.transport.ServerSession;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.Binary;
-import org.apache.qpid.transport.Connection;
-import org.apache.qpid.transport.ConnectionException;
-import org.apache.qpid.transport.ConnectionListener;
-import org.apache.qpid.transport.Session;
-import org.apache.qpid.transport.SessionDelegate;
-import org.apache.qpid.transport.TransportException;
-
-import java.util.Map;
-import java.util.UUID;
+import org.apache.qpid.transport.*;
+import org.apache.qpid.util.Strings;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslException;
+import java.io.IOException;
+import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ScheduledThreadPoolExecutor;
@@ -55,6 +59,14 @@ public class BrokerLink implements LinkConfig, ConnectionListener
private static final ScheduledThreadPoolExecutor _threadPool =
new ScheduledThreadPoolExecutor(CORE_POOL_SIZE);
+ private static final String TRANSPORT = "transport";
+ private static final String HOST = "host";
+ private static final String PORT = "port";
+ private static final String REMOTE_VHOST = "remoteVhost";
+ private static final String DURABLE = "durable";
+ private static final String AUTH_MECHANISM = "authMechanism";
+ private static final String USERNAME = "username";
+ private static final String PASSWORD = "password";
private final String _transport;
@@ -68,7 +80,7 @@ public class BrokerLink implements LinkConfig, ConnectionListener
private final VirtualHost _virtualHost;
private UUID _id;
private AtomicBoolean _closing = new AtomicBoolean();
- private final long _createTime = System.currentTimeMillis();
+ private final long _createTime;
private Connection _qpidConnection;
private AtomicReference<Thread> _executor = new AtomicReference<Thread>();
private AtomicInteger _bridgeId = new AtomicInteger();
@@ -88,8 +100,10 @@ public class BrokerLink implements LinkConfig, ConnectionListener
{
doMakeConnection();
}
- };;
- ;
+ };
+
+
+
public static enum State
{
@@ -205,6 +219,44 @@ public class BrokerLink implements LinkConfig, ConnectionListener
}
};
+ public BrokerLink(final VirtualHost virtualHost, UUID id, long createTime, Map<String, String> arguments)
+ {
+ _virtualHost = virtualHost;
+ _id = id;
+ virtualHost.getConfigStore().persistentIdInUse(id);
+ _createTime = createTime;
+ _transport = arguments.get(TRANSPORT);
+
+ _host = arguments.get(HOST);
+ _port = Integer.parseInt(arguments.get(PORT));
+ _remoteVhost = arguments.get(REMOTE_VHOST);
+ _durable = Boolean.parseBoolean(arguments.get(DURABLE));
+ _authMechanism = arguments.get("authMechanism");
+ _username = arguments.get("username");
+ _password = arguments.get("password");
+
+ if(_durable)
+ {
+ try
+ {
+ _virtualHost.getDurableConfigurationStore().createBrokerLink(this);
+ }
+ catch (AMQStoreException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ _qpidConnection = new Connection();
+ _connectionConfig = new ConnectionConfigAdapter();
+ _qpidConnection.addConnectionListener(this);
+
+
+ makeConnection();
+
+ }
+
public BrokerLink(final VirtualHost virtualHost,
final String transport,
@@ -212,10 +264,13 @@ public class BrokerLink implements LinkConfig, ConnectionListener
final int port,
final String remoteVhost,
final boolean durable,
- final String authMechanism, final String username, final String password)
+ final String authMechanism,
+ final String username,
+ final String password)
{
_virtualHost = virtualHost;
_transport = transport;
+ _createTime = System.currentTimeMillis();
_host = host;
_port = port;
_remoteVhost = remoteVhost;
@@ -223,15 +278,42 @@ public class BrokerLink implements LinkConfig, ConnectionListener
_authMechanism = authMechanism;
_username = username;
_password = password;
- _id = virtualHost.getConfigStore().createId();
+ _id = durable ? virtualHost.getConfigStore().createPersistentId() : virtualHost.getConfigStore().createId();
+
+ if(durable)
+ {
+ try
+ {
+ _virtualHost.getDurableConfigurationStore().createBrokerLink(this);
+ }
+ catch (AMQStoreException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
_qpidConnection = new Connection();
_connectionConfig = new ConnectionConfigAdapter();
_qpidConnection.addConnectionListener(this);
-
makeConnection();
}
+ public Map<String,String> getArguments()
+ {
+ Map<String,String> arguments = new HashMap<String, String>();
+
+ arguments.put(TRANSPORT, _transport);
+ arguments.put(HOST, _host);
+ arguments.put(PORT, String.valueOf(_port));
+ arguments.put(REMOTE_VHOST, _remoteVhost);
+ arguments.put(DURABLE, String.valueOf(_durable));
+ arguments.put(AUTH_MECHANISM, _authMechanism);
+ arguments.put(USERNAME, _username);
+ arguments.put(PASSWORD, _password);
+
+ return Collections.unmodifiableMap(arguments);
+ }
+
private final boolean updateState(State expected, State newState)
{
return _stateUpdater.compareAndSet(this,expected,newState);
@@ -250,9 +332,50 @@ public class BrokerLink implements LinkConfig, ConnectionListener
{
try
{
+ _qpidConnection.setConnectionDelegate(new ClientDelegate(new ConnectionSettings())
+ {
+ protected SaslClient createSaslClient(List<Object> brokerMechs) throws ConnectionException,
+ SaslException
+ {
+ Map<String,Object> saslProps = new HashMap<String,Object>();
+
+
+ CallbackHandler cbh = new CallbackHandler()
+ {
+ public void handle(final Callback[] callbacks)
+ throws IOException, UnsupportedCallbackException
+ {
+ for (int i = 0; i < callbacks.length; i++)
+ {
+ Callback cb = callbacks[i];
+ if (cb instanceof NameCallback)
+ {
+ ((NameCallback)cb).setName(_username);
+ }
+ else if (cb instanceof PasswordCallback)
+ {
+ ((PasswordCallback)cb).setPassword(_password.toCharArray());
+ }
+ else
+ {
+ throw new UnsupportedCallbackException(cb);
+ }
+ }
+
+ }
+ };
+ final SaslClient sc = Sasl.createSaslClient(new String[] {"PLAIN"}, null,
+ _conSettings.getSaslProtocol(),
+ _conSettings.getSaslServerName(),
+ saslProps, cbh);
+
+ return sc;
+ }});
+
_qpidConnection.connect(_host, _port, _remoteVhost, _username, _password, "ssl".equals(_transport), _authMechanism);
final Map<String,Object> serverProps = _qpidConnection.getServerProperties();
+
_remoteFederationTag = (String) serverProps.get(ServerPropertyNames.FEDERATION_TAG);
if(_remoteFederationTag == null)
{
@@ -445,6 +568,20 @@ public class BrokerLink implements LinkConfig, ConnectionListener
}
+ public void createBridge(final UUID id, final long createTime, final Map<String, String> arguments)
+ {
+ if(!_closing.get())
+ {
+ Bridge bridge = new Bridge(this, _bridgeId.incrementAndGet(), id, createTime, arguments);
+ if(_bridges.putIfAbsent(bridge, bridge) == null)
+ {
+
+ addBridge(bridge);
+ }
+ }
+ }
+
+
private void addBridge(final Bridge bridge)
{
getConfigStore().addConfiguredObject(bridge);
@@ -509,4 +646,34 @@ public class BrokerLink implements LinkConfig, ConnectionListener
{
return _remoteFederationTag;
}
+
+ public String getState()
+ {
+ return _state.name();
+ }
+
+ public String getLastError()
+ {
+ return _lastErrorMessage;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "BrokerLink{" +
+ " _id=" + _id +
+ ", _transport='" + _transport + '\'' +
+ ", _host='" + _host + '\'' +
+ ", _port=" + _port +
+ ", _remoteVhost='" + _remoteVhost + '\'' +
+ ", _durable=" + _durable +
+ ", _authMechanism='" + _authMechanism + '\'' +
+ ", _username='" + _username + '\'' +
+ ", _password='" + _password + '\'' +
+ ", _virtualHost=" + _virtualHost +
+ ", _createTime=" + _createTime +
+ ", _remoteFederationTag='" + _remoteFederationTag + '\'' +
+ ", _state=" + _state +
+ '}';
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/AbstractFlowCreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/AbstractFlowCreditManager.java
index cfe5aedd61..a77ed5700a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/AbstractFlowCreditManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/AbstractFlowCreditManager.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.flow;
+import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.Set;
import java.util.HashSet;
@@ -27,13 +28,16 @@ import java.util.HashSet;
public abstract class AbstractFlowCreditManager implements FlowCreditManager
{
protected final AtomicBoolean _suspended = new AtomicBoolean(false);
- private final Set<FlowCreditManagerListener> _listeners = new HashSet<FlowCreditManagerListener>();
+ private final ArrayList<FlowCreditManagerListener> _listeners = new ArrayList<FlowCreditManagerListener>();
public final void addStateListener(FlowCreditManagerListener listener)
{
synchronized(_listeners)
{
- _listeners.add(listener);
+ if(!_listeners.contains(listener))
+ {
+ _listeners.add(listener);
+ }
}
}
@@ -49,9 +53,10 @@ public abstract class AbstractFlowCreditManager implements FlowCreditManager
{
synchronized(_listeners)
{
- for(FlowCreditManagerListener listener : _listeners)
+ final int size = _listeners.size();
+ for(int i = 0; i<size; i++)
{
- listener.creditStateChanged(!suspended);
+ _listeners.get(i).creditStateChanged(!suspended);
}
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java
index 765dee2878..8875f21d0b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java
@@ -52,7 +52,6 @@ public class BasicConsumeMethodHandler implements StateAwareMethodListener<Basic
AMQProtocolSession protocolConnection = stateManager.getProtocolSession();
AMQChannel channel = protocolConnection.getChannel(channelId);
-
VirtualHost vHost = protocolConnection.getVirtualHost();
if (channel == null)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseHandler.java
index 9133cce6b7..32aa99534b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseHandler.java
@@ -65,7 +65,6 @@ public class ChannelCloseHandler implements StateAwareMethodListener<ChannelClos
{
throw body.getConnectionException(AMQConstant.CHANNEL_ERROR, "Trying to close unknown channel");
}
-
session.closeChannel(channelId);
// Client requested closure so we don't wait for ok we send it
stateManager.getProtocolSession().closeChannelOk(channelId);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelFlowHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelFlowHandler.java
index 696ca8a63b..5ccaa49de8 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelFlowHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelFlowHandler.java
@@ -55,7 +55,6 @@ public class ChannelFlowHandler implements StateAwareMethodListener<ChannelFlowB
{
throw body.getChannelNotFoundException(channelId);
}
-
channel.setSuspended(!body.getActive());
_logger.debug("Channel.Flow for channel " + channelId + ", active=" + body.getActive());
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseMethodHandler.java
index f8e4eab0b6..6eaba87b79 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseMethodHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseMethodHandler.java
@@ -49,7 +49,6 @@ public class ConnectionCloseMethodHandler implements StateAwareMethodListener<Co
public void methodReceived(AMQStateManager stateManager, ConnectionCloseBody body, int channelId) throws AMQException
{
AMQProtocolSession session = stateManager.getProtocolSession();
-
if (_logger.isInfoEnabled())
{
_logger.info("ConnectionClose received with reply code/reply text " + body.getReplyCode() + "/" +
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java
index ccd42204d9..21aea1510b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java
@@ -65,7 +65,6 @@ public class ExchangeBoundHandler implements StateAwareMethodListener<ExchangeBo
public void methodReceived(AMQStateManager stateManager, ExchangeBoundBody body, int channelId) throws AMQException
{
AMQProtocolSession session = stateManager.getProtocolSession();
-
VirtualHost virtualHost = session.getVirtualHost();
QueueRegistry queueRegistry = virtualHost.getQueueRegistry();
MethodRegistry methodRegistry = session.getMethodRegistry();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
index 0cfed77f2e..693b316607 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
@@ -85,6 +85,13 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
//TODO: do we need to check that the queue already exists with exactly the same "configuration"?
+ AMQChannel channel = protocolConnection.getChannel(channelId);
+
+ if (channel == null)
+ {
+ throw body.getChannelNotFoundException(channelId);
+ }
+
synchronized (queueRegistry)
{
queue = queueRegistry.getQueue(queueName);
@@ -183,12 +190,6 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
}
- AMQChannel channel = protocolConnection.getChannel(channelId);
-
- if (channel == null)
- {
- throw body.getChannelNotFoundException(channelId);
- }
//set this as the default queue on the channel:
channel.setDefaultQueue(queue);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java
index da52268e52..902e3ade85 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java
@@ -64,15 +64,17 @@ public class QueueDeleteHandler implements StateAwareMethodListener<QueueDeleteB
QueueRegistry queueRegistry = virtualHost.getQueueRegistry();
DurableConfigurationStore store = virtualHost.getDurableConfigurationStore();
+
+ AMQChannel channel = protocolConnection.getChannel(channelId);
+
+ if (channel == null)
+ {
+ throw body.getChannelNotFoundException(channelId);
+ }
+
AMQQueue queue;
if (body.getQueue() == null)
{
- AMQChannel channel = protocolConnection.getChannel(channelId);
-
- if (channel == null)
- {
- throw body.getChannelNotFoundException(channelId);
- }
//get the default queue on the channel:
queue = channel.getDefaultQueue();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java
index 759eec0129..6c3e11be5b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java
@@ -63,17 +63,14 @@ public class QueuePurgeHandler implements StateAwareMethodListener<QueuePurgeBod
QueueRegistry queueRegistry = virtualHost.getQueueRegistry();
AMQChannel channel = protocolConnection.getChannel(channelId);
-
-
+ if (channel == null)
+ {
+ throw body.getChannelNotFoundException(channelId);
+ }
AMQQueue queue;
if(body.getQueue() == null)
{
- if (channel == null)
- {
- throw body.getChannelNotFoundException(channelId);
- }
-
//get the default queue on the channel:
queue = channel.getDefaultQueue();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java
index f2119f7faa..3849c5af19 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java
@@ -66,14 +66,15 @@ public class QueueUnbindHandler implements StateAwareMethodListener<QueueUnbindB
final AMQQueue queue;
final AMQShortString routingKey;
- if (body.getQueue() == null)
+
+ AMQChannel channel = session.getChannel(channelId);
+ if (channel == null)
{
- AMQChannel channel = session.getChannel(channelId);
+ throw body.getChannelNotFoundException(channelId);
+ }
- if (channel == null)
- {
- throw body.getChannelNotFoundException(channelId);
- }
+ if (body.getQueue() == null)
+ {
queue = channel.getDefaultQueue();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java
index 9b357403a8..885b039e18 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java
@@ -22,6 +22,9 @@ package org.apache.qpid.server.logging.subjects;
import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.transport.ServerConnection;
+import org.apache.qpid.server.transport.ServerSession;
+
import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CHANNEL_FORMAT;
public class ChannelLogSubject extends AbstractLogSubject
@@ -52,5 +55,33 @@ public class ChannelLogSubject extends AbstractLogSubject
session.getVirtualHost().getName(),
channel.getChannelId());
}
-
+
+ public ChannelLogSubject(ServerSession session)
+ {
+ /**
+ * LOG FORMAT used by the AMQPConnectorActor follows
+ * ChannelLogSubject.CHANNEL_FORMAT :
+ * con:{0}({1}@{2}/{3})/ch:{4}
+ *
+ * Uses a MessageFormat call to insert the required values according to
+ * these indices:
+ *
+ * 0 - Connection ID
+ * 1 - User ID
+ * 2 - IP
+ * 3 - Virtualhost
+ * 4 - Channel ID
+ */
+ if(session.getConnection() instanceof ServerConnection)
+ {
+ ServerConnection connection = (ServerConnection) session.getConnection();
+ setLogStringWithFormat(CHANNEL_FORMAT,
+ connection == null ? -1L : connection.getConnectionId(),
+ session.getAuthorizedPrincipal() == null ? "?" : session.getAuthorizedPrincipal().getName(),
+ (connection == null || connection.getConfig() == null) ? "?" : connection.getConfig().getAddress(),
+ session.getVirtualHost().getName(),
+ session.getChannel());
+ }
+ }
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessage.java
index 4fcbaa237e..e36e467fea 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessage.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessage.java
@@ -37,7 +37,7 @@ import java.nio.ByteBuffer;
/**
* A deliverable message.
*/
-public class AMQMessage extends AbstractServerMessageImpl
+public class AMQMessage extends AbstractServerMessageImpl<MessageMetaData>
{
/** Used for debugging purposes. */
private static final Logger _log = Logger.getLogger(AMQMessage.class);
@@ -62,9 +62,7 @@ public class AMQMessage extends AbstractServerMessageImpl
private Object _sessionIdentifier;
private static final byte IMMEDIATE_AND_DELIVERED = (byte) (IMMEDIATE | DELIVERED_TO_CONSUMER);
- private final StoredMessage<MessageMetaData> _handle;
-
- WeakReference<AMQChannel> _channelRef;
+ private WeakReference<AMQChannel> _channelRef;
public AMQMessage(StoredMessage<MessageMetaData> handle)
{
@@ -75,7 +73,7 @@ public class AMQMessage extends AbstractServerMessageImpl
{
super(handle);
- _handle = handle;
+
final MessageMetaData metaData = handle.getMetaData();
_size = metaData.getContentSize();
final MessagePublishInfo messagePublishInfo = metaData.getMessagePublishInfo();
@@ -97,7 +95,7 @@ public class AMQMessage extends AbstractServerMessageImpl
public MessageMetaData getMessageMetaData()
{
- return _handle.getMetaData();
+ return getStoredMessage().getMetaData();
}
public ContentHeaderBody getContentHeaderBody() throws AMQException
@@ -107,7 +105,7 @@ public class AMQMessage extends AbstractServerMessageImpl
public Long getMessageId()
{
- return _handle.getMessageNumber();
+ return getStoredMessage().getMessageNumber();
}
/**
@@ -219,9 +217,9 @@ public class AMQMessage extends AbstractServerMessageImpl
return new AMQMessageReference(this);
}
- public Long getMessageNumber()
+ public long getMessageNumber()
{
- return getMessageId();
+ return getStoredMessage().getMessageNumber();
}
@@ -248,16 +246,13 @@ public class AMQMessage extends AbstractServerMessageImpl
public int getContent(ByteBuffer buf, int offset)
{
- return _handle.getContent(offset, buf);
+ return getStoredMessage().getContent(offset, buf);
}
- public StoredMessage<MessageMetaData> getStoredMessage()
+
+ public ByteBuffer getContent(int offset, int size)
{
- return _handle;
+ return getStoredMessage().getContent(offset, size);
}
- public SessionConfig getSessionConfig()
- {
- return _channelRef == null ? null : ((SessionConfig) _channelRef.get());
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AbstractServerMessageImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AbstractServerMessageImpl.java
index 80c28332c0..b1d43f0b50 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AbstractServerMessageImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AbstractServerMessageImpl.java
@@ -21,19 +21,30 @@
package org.apache.qpid.server.message;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+import org.apache.qpid.server.store.StorableMessageMetaData;
import org.apache.qpid.server.store.StoredMessage;
-public abstract class AbstractServerMessageImpl implements ServerMessage
+public abstract class AbstractServerMessageImpl<T extends StorableMessageMetaData> implements ServerMessage<T>
{
- private final AtomicInteger _referenceCount = new AtomicInteger(0);
- private final StoredMessage<?> _handle;
- public AbstractServerMessageImpl(StoredMessage<?> handle)
+ private static final AtomicIntegerFieldUpdater<AbstractServerMessageImpl> _refCountUpdater =
+ AtomicIntegerFieldUpdater.newUpdater(AbstractServerMessageImpl.class, "_referenceCount");
+
+ private volatile int _referenceCount = 0;
+ private final StoredMessage<T> _handle;
+
+ public AbstractServerMessageImpl(StoredMessage<T> handle)
{
_handle = handle;
}
+ public StoredMessage<T> getStoredMessage()
+ {
+ return _handle;
+ }
+
public boolean incrementReference()
{
return incrementReference(1);
@@ -41,9 +52,9 @@ public abstract class AbstractServerMessageImpl implements ServerMessage
public boolean incrementReference(int count)
{
- if(_referenceCount.addAndGet(count) <= 0)
+ if(_refCountUpdater.addAndGet(this, count) <= 0)
{
- _referenceCount.addAndGet(-count);
+ _refCountUpdater.addAndGet(this, -count);
return false;
}
else
@@ -62,7 +73,7 @@ public abstract class AbstractServerMessageImpl implements ServerMessage
*/
public void decrementReference()
{
- int count = _referenceCount.decrementAndGet();
+ int count = _refCountUpdater.decrementAndGet(this);
// note that the operation of decrementing the reference count and then removing the message does not
// have to be atomic since the ref count starts at 1 and the exchange itself decrements that after
@@ -73,7 +84,7 @@ public abstract class AbstractServerMessageImpl implements ServerMessage
// set the reference count way below 0 so that we can detect that the message has been deleted
// this is to guard against the message being spontaneously recreated (from the mgmt console)
// by copying from other queues at the same time as it is being removed.
- _referenceCount.set(Integer.MIN_VALUE/2);
+ _refCountUpdater.set(this,Integer.MIN_VALUE/2);
// must check if the handle is null since there may be cases where we decide to throw away a message
// and the handle has not yet been constructed
@@ -99,6 +110,6 @@ public abstract class AbstractServerMessageImpl implements ServerMessage
protected int getReferenceCount()
{
- return _referenceCount.get();
+ return _referenceCount;
}
} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/EnqueableMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/EnqueableMessage.java
index c32f80fc5b..7be91ad0ca 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/EnqueableMessage.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/EnqueableMessage.java
@@ -20,8 +20,11 @@
*/
package org.apache.qpid.server.message;
+import org.apache.qpid.server.store.StoredMessage;
+
public interface EnqueableMessage
{
- Long getMessageNumber();
+ long getMessageNumber();
boolean isPersistent();
+ StoredMessage getStoredMessage();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/InboundMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/InboundMessage.java
index 1b3fdb1870..79d5574a91 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/InboundMessage.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/InboundMessage.java
@@ -22,10 +22,12 @@ package org.apache.qpid.server.message;
import org.apache.qpid.server.queue.Filterable;
+import org.apache.qpid.framing.AMQShortString;
public interface InboundMessage extends Filterable
{
String getRoutingKey();
+ AMQShortString getRoutingKeyShortString();
AMQMessageHeader getMessageHeader();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageContentSource.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageContentSource.java
index 08a09c4a85..44741f57bd 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageContentSource.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageContentSource.java
@@ -26,6 +26,7 @@ import java.nio.ByteBuffer;
public interface MessageContentSource
{
public int getContent(ByteBuffer buf, int offset);
+ public ByteBuffer getContent(int offset, int size);
long getSize();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
index 5992e42fb7..9bfa0bb2fb 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
@@ -29,8 +29,8 @@ import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.server.store.StorableMessageMetaData;
import org.apache.qpid.server.store.MessageMetaDataType;
import org.apache.qpid.AMQException;
-import org.apache.qpid.server.util.ByteBufferInputStream;
import org.apache.qpid.server.util.ByteBufferOutputStream;
+import org.apache.qpid.util.ByteBufferInputStream;
import java.io.*;
import java.nio.ByteBuffer;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_0_10.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_0_10.java
index f9863f4945..17ebb6ee07 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_0_10.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_0_10.java
@@ -30,9 +30,12 @@ import org.apache.qpid.transport.MessageDeliveryMode;
import org.apache.qpid.transport.Struct;
import org.apache.qpid.transport.codec.BBEncoder;
import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.framing.AMQShortString;
import java.nio.ByteBuffer;
import java.lang.ref.SoftReference;
+import java.util.ArrayList;
+import java.util.List;
public class MessageMetaData_0_10 implements StorableMessageMetaData, InboundMessage
{
@@ -42,7 +45,6 @@ public class MessageMetaData_0_10 implements StorableMessageMetaData, InboundMes
private MessageTransferHeader _messageHeader;
private long _arrivalTime;
private int _bodySize;
- private volatile SoftReference<ByteBuffer> _body;
private static final int ENCODER_SIZE = 1 << 10;
@@ -53,21 +55,16 @@ public class MessageMetaData_0_10 implements StorableMessageMetaData, InboundMes
public MessageMetaData_0_10(MessageTransfer xfr)
{
- this(xfr.getHeader(), xfr.getBodySize(), xfr.getBody(), System.currentTimeMillis());
+ this(xfr.getHeader(), xfr.getBodySize(), System.currentTimeMillis());
}
private MessageMetaData_0_10(Header header, int bodySize, long arrivalTime)
{
- this(header, bodySize, null, arrivalTime);
- }
-
- private MessageMetaData_0_10(Header header, int bodySize, ByteBuffer xfrBody, long arrivalTime)
- {
_header = header;
if(_header != null)
{
- _deliveryProps = _header.get(DeliveryProperties.class);
- _messageProps = _header.get(MessageProperties.class);
+ _deliveryProps = _header.getDeliveryProperties();
+ _messageProps = _header.getMessageProperties();
}
else
{
@@ -78,21 +75,6 @@ public class MessageMetaData_0_10 implements StorableMessageMetaData, InboundMes
_arrivalTime = arrivalTime;
_bodySize = bodySize;
-
-
- if(xfrBody == null)
- {
- _body = null;
- }
- else
- {
- ByteBuffer body = ByteBuffer.allocate(_bodySize);
- body.put(xfrBody);
- body.flip();
- _body = new SoftReference<ByteBuffer>(body);
- }
-
-
}
@@ -122,16 +104,39 @@ public class MessageMetaData_0_10 implements StorableMessageMetaData, InboundMes
encoder.writeInt64(_arrivalTime);
encoder.writeInt32(_bodySize);
- Struct[] headers = _header == null ? new Struct[0] : _header.getStructs();
- encoder.writeInt32(headers.length);
+ int headersLength = 0;
+ if(_header.getDeliveryProperties() != null)
+ {
+ headersLength++;
+ }
+ if(_header.getMessageProperties() != null)
+ {
+ headersLength++;
+ }
+ if(_header.getNonStandardProperties() != null)
+ {
+ headersLength += _header.getNonStandardProperties().size();
+ }
+ encoder.writeInt32(headersLength);
- for(Struct header : headers)
+ if(_header.getDeliveryProperties() != null)
{
- encoder.writeStruct32(header);
-
+ encoder.writeStruct32(_header.getDeliveryProperties());
+ }
+ if(_header.getMessageProperties() != null)
+ {
+ encoder.writeStruct32(_header.getMessageProperties());
}
+ if(_header.getNonStandardProperties() != null)
+ {
+ for(Struct header : _header.getNonStandardProperties())
+ {
+ encoder.writeStruct32(header);
+ }
+
+ }
ByteBuffer buf = encoder.buffer();
return buf;
}
@@ -173,6 +178,11 @@ public class MessageMetaData_0_10 implements StorableMessageMetaData, InboundMes
return _deliveryProps == null ? null : _deliveryProps.getRoutingKey();
}
+ public AMQShortString getRoutingKeyShortString()
+ {
+ return AMQShortString.valueOf(getRoutingKey());
+ }
+
public AMQMessageHeader getMessageHeader()
{
return _messageHeader;
@@ -210,17 +220,6 @@ public class MessageMetaData_0_10 implements StorableMessageMetaData, InboundMes
return _header;
}
- public ByteBuffer getBody()
- {
- ByteBuffer body = _body == null ? null : _body.get();
- return body;
- }
-
- public void setBody(ByteBuffer body)
- {
- _body = new SoftReference<ByteBuffer>(body);
- }
-
private static class MetaDataFactory implements MessageMetaDataType.Factory<MessageMetaData_0_10>
{
public MessageMetaData_0_10 createMetaData(ByteBuffer buf)
@@ -232,14 +231,32 @@ public class MessageMetaData_0_10 implements StorableMessageMetaData, InboundMes
int bodySize = decoder.readInt32();
int headerCount = decoder.readInt32();
- Struct[] headers = new Struct[headerCount];
+ DeliveryProperties deliveryProperties = null;
+ MessageProperties messageProperties = null;
+ List<Struct> otherProps = null;
for(int i = 0 ; i < headerCount; i++)
{
- headers[i] = decoder.readStruct32();
+ Struct struct = decoder.readStruct32();
+ if(struct instanceof DeliveryProperties && deliveryProperties == null)
+ {
+ deliveryProperties = (DeliveryProperties) struct;
+ }
+ else if(struct instanceof MessageProperties && messageProperties == null)
+ {
+ messageProperties = (MessageProperties) struct;
+ }
+ else
+ {
+ if(otherProps == null)
+ {
+ otherProps = new ArrayList<Struct>();
+
+ }
+ otherProps.add(struct);
+ }
}
-
- Header header = new Header(headers);
+ Header header = new Header(deliveryProperties,messageProperties,otherProps);
return new MessageMetaData_0_10(header, bodySize, arrivalTime);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java
index d160d91f65..9cb5904bb3 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java
@@ -20,25 +20,30 @@
*/
package org.apache.qpid.server.message;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import org.apache.qpid.amqp_1_0.codec.ValueHandler;
import org.apache.qpid.amqp_1_0.messaging.SectionDecoder;
import org.apache.qpid.amqp_1_0.type.AmqpErrorException;
-import org.apache.qpid.amqp_1_0.type.Binary;
import org.apache.qpid.amqp_1_0.type.Section;
import org.apache.qpid.amqp_1_0.type.Symbol;
-import org.apache.qpid.amqp_1_0.type.UnsignedInteger;
import org.apache.qpid.amqp_1_0.type.codec.AMQPDescribedTypeRegistry;
-import org.apache.qpid.amqp_1_0.type.messaging.*;
-
-
+import org.apache.qpid.amqp_1_0.type.messaging.AmqpSequence;
+import org.apache.qpid.amqp_1_0.type.messaging.AmqpValue;
+import org.apache.qpid.amqp_1_0.type.messaging.ApplicationProperties;
+import org.apache.qpid.amqp_1_0.type.messaging.Data;
+import org.apache.qpid.amqp_1_0.type.messaging.DeliveryAnnotations;
+import org.apache.qpid.amqp_1_0.type.messaging.Footer;
+import org.apache.qpid.amqp_1_0.type.messaging.Header;
+import org.apache.qpid.amqp_1_0.type.messaging.MessageAnnotations;
import org.apache.qpid.amqp_1_0.type.messaging.Properties;
-import org.apache.qpid.configuration.Validator;
import org.apache.qpid.server.store.MessageMetaDataType;
import org.apache.qpid.server.store.StorableMessageMetaData;
-import java.nio.ByteBuffer;
-import java.util.*;
-
public class MessageMetaData_1_0 implements StorableMessageMetaData
{
// TODO move to somewhere more useful
@@ -312,6 +317,18 @@ public class MessageMetaData_1_0 implements StorableMessageMetaData
return buf.limit();
}
+ public int getContentSize()
+ {
+ ByteBuffer buf = _encoded;
+
+ if(buf == null)
+ {
+ buf = encodeAsBuffer();
+ _encoded = buf;
+ }
+ return buf.remaining();
+ }
+
public boolean isPersistent()
{
return _header != null && Boolean.TRUE.equals(_header.getDurable());
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferMessage.java
index 1a230a2590..c4d2a190e6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferMessage.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferMessage.java
@@ -24,32 +24,35 @@ import org.apache.qpid.transport.*;
import org.apache.qpid.server.configuration.SessionConfig;
import org.apache.qpid.server.store.StoredMessage;
import org.apache.qpid.server.transport.ServerSession;
+import org.apache.qpid.framing.AMQShortString;
import java.nio.ByteBuffer;
-import java.lang.ref.WeakReference;
-public class MessageTransferMessage extends AbstractServerMessageImpl implements InboundMessage
+public class MessageTransferMessage extends AbstractServerMessageImpl<MessageMetaData_0_10> implements InboundMessage
{
- private StoredMessage<MessageMetaData_0_10> _storeMessage;
- private WeakReference<Session> _sessionRef;
- public MessageTransferMessage(StoredMessage<MessageMetaData_0_10> storeMessage, WeakReference<Session> sessionRef)
+ private Object _connectionRef;
+
+ public MessageTransferMessage(StoredMessage<MessageMetaData_0_10> storeMessage, Object connectionRef)
{
super(storeMessage);
- _storeMessage = storeMessage;
- _sessionRef = sessionRef;
+ _connectionRef = connectionRef;
}
private MessageMetaData_0_10 getMetaData()
{
- return _storeMessage.getMetaData();
+ return getStoredMessage().getMetaData();
}
public String getRoutingKey()
{
return getMetaData().getRoutingKey();
+ }
+ public AMQShortString getRoutingKeyShortString()
+ {
+ return AMQShortString.valueOf(getRoutingKey());
}
public AMQMessageHeader getMessageHeader()
@@ -91,9 +94,9 @@ public class MessageTransferMessage extends AbstractServerMessageImpl implements
return new TransferMessageReference(this);
}
- public Long getMessageNumber()
+ public long getMessageNumber()
{
- return _storeMessage.getMessageNumber();
+ return getStoredMessage().getMessageNumber();
}
public long getArrivalTime()
@@ -103,7 +106,13 @@ public class MessageTransferMessage extends AbstractServerMessageImpl implements
public int getContent(ByteBuffer buf, int offset)
{
- return _storeMessage.getContent(offset, buf);
+ return getStoredMessage().getContent(offset, buf);
+ }
+
+
+ public ByteBuffer getContent(int offset, int size)
+ {
+ return getStoredMessage().getContent(offset,size);
}
public Header getHeader()
@@ -113,32 +122,13 @@ public class MessageTransferMessage extends AbstractServerMessageImpl implements
public ByteBuffer getBody()
{
- ByteBuffer body = getMetaData().getBody();
- if(body == null && getSize() != 0l)
- {
- final int size = (int) getSize();
- int pos = 0;
- body = ByteBuffer.allocate(size);
-
- while(pos < size)
- {
- pos += getContent(body, pos);
- }
-
- body.flip();
- getMetaData().setBody(body.duplicate());
- }
- return body;
+ return getContent(0, (int)getSize());
}
- public Session getSession()
+ public Object getConnectionReference()
{
- return _sessionRef == null ? null : _sessionRef.get();
+ return _connectionRef;
}
- public SessionConfig getSessionConfig()
- {
- return _sessionRef == null ? null : (ServerSession) _sessionRef.get();
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ServerMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ServerMessage.java
index e3cc9879fa..d354d3b145 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ServerMessage.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ServerMessage.java
@@ -22,14 +22,17 @@ package org.apache.qpid.server.message;
import java.nio.ByteBuffer;
-import org.apache.qpid.server.configuration.SessionConfig;
+import org.apache.qpid.server.store.StorableMessageMetaData;
+import org.apache.qpid.server.store.StoredMessage;
-public interface ServerMessage<T extends ServerMessage> extends EnqueableMessage, MessageContentSource
+public interface ServerMessage<T extends StorableMessageMetaData> extends EnqueableMessage, MessageContentSource
{
String getRoutingKey();
AMQMessageHeader getMessageHeader();
+ public StoredMessage<T> getStoredMessage();
+
boolean isPersistent();
long getSize();
@@ -38,13 +41,14 @@ public interface ServerMessage<T extends ServerMessage> extends EnqueableMessage
long getExpiration();
- MessageReference<T> newReference();
+ MessageReference newReference();
- Long getMessageNumber();
+ long getMessageNumber();
long getArrivalTime();
public int getContent(ByteBuffer buf, int offset);
- SessionConfig getSessionConfig();
+ public ByteBuffer getContent(int offset, int size);
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/HeaderPropertiesConverter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/HeaderPropertiesConverter.java
index aded3f3d2a..483bca894e 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/HeaderPropertiesConverter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/HeaderPropertiesConverter.java
@@ -40,8 +40,8 @@ public class HeaderPropertiesConverter
BasicContentHeaderProperties props = new BasicContentHeaderProperties();
Header header = messageTransferMessage.getHeader();
- DeliveryProperties deliveryProps = header.get(DeliveryProperties.class);
- MessageProperties messageProps = header.get(MessageProperties.class);
+ DeliveryProperties deliveryProps = header.getDeliveryProperties();
+ MessageProperties messageProps = header.getMessageProperties();
if(deliveryProps != null)
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_8/ProtocolOutputConverterImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_8/ProtocolOutputConverterImpl.java
index 3970e5a2d4..efd904f6aa 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_8/ProtocolOutputConverterImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_8/ProtocolOutputConverterImpl.java
@@ -1,420 +1,420 @@
-/*
- *
- * 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.
- *
- */
-
-/*
- * This file is auto-generated by Qpid Gentools v.0.1 - do not modify.
- * Supported AMQP versions:
- * 8-0
- */
-package org.apache.qpid.server.output.amqp0_8;
-
-import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
-import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.message.AMQMessage;
-import org.apache.qpid.server.queue.QueueEntry;
-import org.apache.qpid.server.output.ProtocolOutputConverter;
-import org.apache.qpid.server.output.HeaderPropertiesConverter;
-import org.apache.qpid.server.message.MessageContentSource;
-import org.apache.qpid.server.message.MessageTransferMessage;
-import org.apache.qpid.framing.*;
-import org.apache.qpid.framing.abstraction.MessagePublishInfo;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.transport.DeliveryProperties;
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-public class ProtocolOutputConverterImpl implements ProtocolOutputConverter
-{
-
- private static final MethodRegistry METHOD_REGISTRY = MethodRegistry.getMethodRegistry(ProtocolVersion.v8_0);
-
- public static Factory getInstanceFactory()
- {
- return new Factory()
- {
-
- public ProtocolOutputConverter newInstance(AMQProtocolSession session)
- {
- return new ProtocolOutputConverterImpl(session);
- }
- };
- }
-
-
- private final AMQProtocolSession _protocolSession;
-
- private ProtocolOutputConverterImpl(AMQProtocolSession session)
- {
- _protocolSession = session;
- }
-
-
- public AMQProtocolSession getProtocolSession()
- {
- return _protocolSession;
- }
-
- public void writeDeliver(QueueEntry entry, int channelId, long deliveryTag, AMQShortString consumerTag)
- throws AMQException
- {
- AMQBody deliverBody = createEncodedDeliverBody(entry, deliveryTag, consumerTag);
- writeMessageDelivery(entry, channelId, deliverBody);
- }
-
-
- private ContentHeaderBody getContentHeaderBody(QueueEntry entry)
- throws AMQException
- {
- if(entry.getMessage() instanceof AMQMessage)
- {
- return ((AMQMessage)entry.getMessage()).getContentHeaderBody();
- }
- else
- {
- final MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
- BasicContentHeaderProperties props = HeaderPropertiesConverter.convert(message);
- ContentHeaderBody chb = new ContentHeaderBody(props, org.apache.qpid.framing.amqp_8_0.BasicGetBodyImpl.CLASS_ID);
- chb.bodySize = message.getSize();
- return chb;
- }
- }
-
-
- private void writeMessageDelivery(QueueEntry entry, int channelId, AMQBody deliverBody)
- throws AMQException
- {
- writeMessageDelivery(entry.getMessage(), getContentHeaderBody(entry), channelId, deliverBody);
- }
-
- private void writeMessageDelivery(MessageContentSource message, ContentHeaderBody contentHeaderBody, int channelId, AMQBody deliverBody)
- throws AMQException
- {
-
-
- int bodySize = (int) message.getSize();
-
- if(bodySize == 0)
- {
- SmallCompositeAMQBodyBlock compositeBlock = new SmallCompositeAMQBodyBlock(channelId, deliverBody,
- contentHeaderBody);
-
- writeFrame(compositeBlock);
- }
- else
- {
- int maxBodySize = (int) getProtocolSession().getMaxFrameSize() - AMQFrame.getFrameOverhead();
-
-
- int capacity = bodySize > maxBodySize ? maxBodySize : bodySize;
-
- int writtenSize = capacity;
-
- AMQBody firstContentBody = new MessageContentSourceBody(message,0,capacity);
-
- CompositeAMQBodyBlock
- compositeBlock = new CompositeAMQBodyBlock(channelId, deliverBody, contentHeaderBody, firstContentBody);
- writeFrame(compositeBlock);
-
- while(writtenSize < bodySize)
- {
- capacity = bodySize - writtenSize > maxBodySize ? maxBodySize : bodySize - writtenSize;
- MessageContentSourceBody body = new MessageContentSourceBody(message, writtenSize, capacity);
- writtenSize += capacity;
-
- writeFrame(new AMQFrame(channelId, body));
- }
- }
- }
-
- private class MessageContentSourceBody implements AMQBody
- {
- public static final byte TYPE = 3;
- private int _length;
- private MessageContentSource _message;
- private int _offset;
-
- public MessageContentSourceBody(MessageContentSource message, int offset, int length)
- {
- _message = message;
- _offset = offset;
- _length = length;
- }
-
- public byte getFrameType()
- {
- return TYPE;
- }
-
- public int getSize()
- {
- return _length;
- }
-
- public void writePayload(DataOutputStream buffer) throws IOException
- {
- byte[] data = new byte[_length];
-
- _message.getContent(java.nio.ByteBuffer.wrap(data), _offset);
-
- buffer.write(data);
- }
-
- public void handle(int channelId, AMQVersionAwareProtocolSession amqProtocolSession) throws AMQException
- {
- throw new UnsupportedOperationException();
- }
- }
-
- private AMQDataBlock createContentHeaderBlock(final int channelId, final ContentHeaderBody contentHeaderBody)
- {
-
- AMQDataBlock contentHeader = ContentHeaderBody.createAMQFrame(channelId,
- contentHeaderBody);
- return contentHeader;
- }
-
-
- public void writeGetOk(QueueEntry entry, int channelId, long deliveryTag, int queueSize) throws AMQException
- {
- AMQBody deliver = createEncodedGetOkBody(entry, deliveryTag, queueSize);
- writeMessageDelivery(entry, channelId, deliver);
- }
-
-
- private AMQBody createEncodedDeliverBody(QueueEntry entry,
- final long deliveryTag,
- final AMQShortString consumerTag)
- throws AMQException
- {
-
- final AMQShortString exchangeName;
- final AMQShortString routingKey;
-
- if(entry.getMessage() instanceof AMQMessage)
- {
- final AMQMessage message = (AMQMessage) entry.getMessage();
- final MessagePublishInfo pb = message.getMessagePublishInfo();
- exchangeName = pb.getExchange();
- routingKey = pb.getRoutingKey();
- }
- else
- {
- MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
- DeliveryProperties delvProps = message.getHeader().get(DeliveryProperties.class);
- exchangeName = (delvProps == null || delvProps.getExchange() == null) ? null : new AMQShortString(delvProps.getExchange());
- routingKey = (delvProps == null || delvProps.getRoutingKey() == null) ? null : new AMQShortString(delvProps.getRoutingKey());
- }
-
- final boolean isRedelivered = entry.isRedelivered();
-
- final AMQBody returnBlock = new AMQBody()
- {
-
- public AMQBody _underlyingBody;
-
- public AMQBody createAMQBody()
- {
- return METHOD_REGISTRY.createBasicDeliverBody(consumerTag,
- deliveryTag,
- isRedelivered,
- exchangeName,
- routingKey);
-
-
-
-
-
- }
-
- public byte getFrameType()
- {
- return AMQMethodBody.TYPE;
- }
-
- public int getSize()
- {
- if(_underlyingBody == null)
- {
- _underlyingBody = createAMQBody();
- }
- return _underlyingBody.getSize();
- }
-
- public void writePayload(DataOutputStream buffer) throws IOException
- {
- if(_underlyingBody == null)
- {
- _underlyingBody = createAMQBody();
- }
- _underlyingBody.writePayload(buffer);
- }
-
- public void handle(final int channelId, final AMQVersionAwareProtocolSession amqMinaProtocolSession)
- throws AMQException
- {
- throw new AMQException("This block should never be dispatched!");
- }
- };
- return returnBlock;
- }
-
- private AMQBody createEncodedGetOkBody(QueueEntry entry, long deliveryTag, int queueSize)
- throws AMQException
- {
- final AMQShortString exchangeName;
- final AMQShortString routingKey;
-
- if(entry.getMessage() instanceof AMQMessage)
- {
- final AMQMessage message = (AMQMessage) entry.getMessage();
- final MessagePublishInfo pb = message.getMessagePublishInfo();
- exchangeName = pb.getExchange();
- routingKey = pb.getRoutingKey();
- }
- else
- {
- MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
- DeliveryProperties delvProps = message.getHeader().get(DeliveryProperties.class);
- exchangeName = (delvProps == null || delvProps.getExchange() == null) ? null : new AMQShortString(delvProps.getExchange());
- routingKey = (delvProps == null || delvProps.getRoutingKey() == null) ? null : new AMQShortString(delvProps.getRoutingKey());
- }
-
- final boolean isRedelivered = entry.isRedelivered();
-
- BasicGetOkBody getOkBody =
- METHOD_REGISTRY.createBasicGetOkBody(deliveryTag,
- isRedelivered,
- exchangeName,
- routingKey,
- queueSize);
-
- return getOkBody;
- }
-
- public byte getProtocolMinorVersion()
- {
- return getProtocolSession().getProtocolMinorVersion();
- }
-
- public byte getProtocolMajorVersion()
- {
- return getProtocolSession().getProtocolMajorVersion();
- }
-
- private AMQBody createEncodedReturnFrame(MessagePublishInfo messagePublishInfo,
- int replyCode,
- AMQShortString replyText) throws AMQException
- {
-
- BasicReturnBody basicReturnBody =
- METHOD_REGISTRY.createBasicReturnBody(replyCode,
- replyText,
- messagePublishInfo.getExchange(),
- messagePublishInfo.getRoutingKey());
-
-
- return basicReturnBody;
- }
-
- public void writeReturn(MessagePublishInfo messagePublishInfo, ContentHeaderBody header, MessageContentSource message, int channelId, int replyCode, AMQShortString replyText)
- throws AMQException
- {
-
- AMQBody returnFrame = createEncodedReturnFrame(messagePublishInfo, replyCode, replyText);
-
- writeMessageDelivery(message, header, channelId, returnFrame);
- }
-
-
- public void writeFrame(AMQDataBlock block)
- {
- getProtocolSession().writeFrame(block);
- }
-
-
- public void confirmConsumerAutoClose(int channelId, AMQShortString consumerTag)
- {
-
- BasicCancelOkBody basicCancelOkBody = METHOD_REGISTRY.createBasicCancelOkBody(consumerTag);
- writeFrame(basicCancelOkBody.generateFrame(channelId));
-
- }
-
-
- public static final class CompositeAMQBodyBlock extends AMQDataBlock
- {
- public static final int OVERHEAD = 3 * AMQFrame.getFrameOverhead();
-
- private final AMQBody _methodBody;
- private final AMQBody _headerBody;
- private final AMQBody _contentBody;
- private final int _channel;
-
-
- public CompositeAMQBodyBlock(int channel, AMQBody methodBody, AMQBody headerBody, AMQBody contentBody)
- {
- _channel = channel;
- _methodBody = methodBody;
- _headerBody = headerBody;
- _contentBody = contentBody;
-
- }
-
- public long getSize()
- {
- return OVERHEAD + _methodBody.getSize() + _headerBody.getSize() + _contentBody.getSize();
- }
-
- public void writePayload(DataOutputStream buffer) throws IOException
- {
- AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody, _contentBody);
- }
- }
-
- public static final class SmallCompositeAMQBodyBlock extends AMQDataBlock
- {
- public static final int OVERHEAD = 2 * AMQFrame.getFrameOverhead();
-
- private final AMQBody _methodBody;
- private final AMQBody _headerBody;
- private final int _channel;
-
-
- public SmallCompositeAMQBodyBlock(int channel, AMQBody methodBody, AMQBody headerBody)
- {
- _channel = channel;
- _methodBody = methodBody;
- _headerBody = headerBody;
-
- }
-
- public long getSize()
- {
- return OVERHEAD + _methodBody.getSize() + _headerBody.getSize() ;
- }
-
- public void writePayload(DataOutputStream buffer) throws IOException
- {
- AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody);
- }
- }
-}
+/*
+ *
+ * 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.
+ *
+ */
+
+/*
+ * This file is auto-generated by Qpid Gentools v.0.1 - do not modify.
+ * Supported AMQP versions:
+ * 8-0
+ */
+package org.apache.qpid.server.output.amqp0_8;
+
+import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.message.AMQMessage;
+import org.apache.qpid.server.queue.QueueEntry;
+import org.apache.qpid.server.output.ProtocolOutputConverter;
+import org.apache.qpid.server.output.HeaderPropertiesConverter;
+import org.apache.qpid.server.message.MessageContentSource;
+import org.apache.qpid.server.message.MessageTransferMessage;
+import org.apache.qpid.framing.*;
+import org.apache.qpid.framing.abstraction.MessagePublishInfo;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.transport.DeliveryProperties;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class ProtocolOutputConverterImpl implements ProtocolOutputConverter
+{
+
+ private static final MethodRegistry METHOD_REGISTRY = MethodRegistry.getMethodRegistry(ProtocolVersion.v8_0);
+
+ public static Factory getInstanceFactory()
+ {
+ return new Factory()
+ {
+
+ public ProtocolOutputConverter newInstance(AMQProtocolSession session)
+ {
+ return new ProtocolOutputConverterImpl(session);
+ }
+ };
+ }
+
+
+ private final AMQProtocolSession _protocolSession;
+
+ private ProtocolOutputConverterImpl(AMQProtocolSession session)
+ {
+ _protocolSession = session;
+ }
+
+
+ public AMQProtocolSession getProtocolSession()
+ {
+ return _protocolSession;
+ }
+
+ public void writeDeliver(QueueEntry entry, int channelId, long deliveryTag, AMQShortString consumerTag)
+ throws AMQException
+ {
+ AMQBody deliverBody = createEncodedDeliverBody(entry, deliveryTag, consumerTag);
+ writeMessageDelivery(entry, channelId, deliverBody);
+ }
+
+
+ private ContentHeaderBody getContentHeaderBody(QueueEntry entry)
+ throws AMQException
+ {
+ if(entry.getMessage() instanceof AMQMessage)
+ {
+ return ((AMQMessage)entry.getMessage()).getContentHeaderBody();
+ }
+ else
+ {
+ final MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
+ BasicContentHeaderProperties props = HeaderPropertiesConverter.convert(message);
+ ContentHeaderBody chb = new ContentHeaderBody(props, org.apache.qpid.framing.amqp_8_0.BasicGetBodyImpl.CLASS_ID);
+ chb.bodySize = message.getSize();
+ return chb;
+ }
+ }
+
+
+ private void writeMessageDelivery(QueueEntry entry, int channelId, AMQBody deliverBody)
+ throws AMQException
+ {
+ writeMessageDelivery(entry.getMessage(), getContentHeaderBody(entry), channelId, deliverBody);
+ }
+
+ private void writeMessageDelivery(MessageContentSource message, ContentHeaderBody contentHeaderBody, int channelId, AMQBody deliverBody)
+ throws AMQException
+ {
+
+
+ int bodySize = (int) message.getSize();
+
+ if(bodySize == 0)
+ {
+ SmallCompositeAMQBodyBlock compositeBlock = new SmallCompositeAMQBodyBlock(channelId, deliverBody,
+ contentHeaderBody);
+
+ writeFrame(compositeBlock);
+ }
+ else
+ {
+ int maxBodySize = (int) getProtocolSession().getMaxFrameSize() - AMQFrame.getFrameOverhead();
+
+
+ int capacity = bodySize > maxBodySize ? maxBodySize : bodySize;
+
+ int writtenSize = capacity;
+
+ AMQBody firstContentBody = new MessageContentSourceBody(message,0,capacity);
+
+ CompositeAMQBodyBlock
+ compositeBlock = new CompositeAMQBodyBlock(channelId, deliverBody, contentHeaderBody, firstContentBody);
+ writeFrame(compositeBlock);
+
+ while(writtenSize < bodySize)
+ {
+ capacity = bodySize - writtenSize > maxBodySize ? maxBodySize : bodySize - writtenSize;
+ MessageContentSourceBody body = new MessageContentSourceBody(message, writtenSize, capacity);
+ writtenSize += capacity;
+
+ writeFrame(new AMQFrame(channelId, body));
+ }
+ }
+ }
+
+ private class MessageContentSourceBody implements AMQBody
+ {
+ public static final byte TYPE = 3;
+ private int _length;
+ private MessageContentSource _message;
+ private int _offset;
+
+ public MessageContentSourceBody(MessageContentSource message, int offset, int length)
+ {
+ _message = message;
+ _offset = offset;
+ _length = length;
+ }
+
+ public byte getFrameType()
+ {
+ return TYPE;
+ }
+
+ public int getSize()
+ {
+ return _length;
+ }
+
+ public void writePayload(DataOutput buffer) throws IOException
+ {
+ byte[] data = new byte[_length];
+
+ _message.getContent(java.nio.ByteBuffer.wrap(data), _offset);
+
+ buffer.write(data);
+ }
+
+ public void handle(int channelId, AMQVersionAwareProtocolSession amqProtocolSession) throws AMQException
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private AMQDataBlock createContentHeaderBlock(final int channelId, final ContentHeaderBody contentHeaderBody)
+ {
+
+ AMQDataBlock contentHeader = ContentHeaderBody.createAMQFrame(channelId,
+ contentHeaderBody);
+ return contentHeader;
+ }
+
+
+ public void writeGetOk(QueueEntry entry, int channelId, long deliveryTag, int queueSize) throws AMQException
+ {
+ AMQBody deliver = createEncodedGetOkBody(entry, deliveryTag, queueSize);
+ writeMessageDelivery(entry, channelId, deliver);
+ }
+
+
+ private AMQBody createEncodedDeliverBody(QueueEntry entry,
+ final long deliveryTag,
+ final AMQShortString consumerTag)
+ throws AMQException
+ {
+
+ final AMQShortString exchangeName;
+ final AMQShortString routingKey;
+
+ if(entry.getMessage() instanceof AMQMessage)
+ {
+ final AMQMessage message = (AMQMessage) entry.getMessage();
+ final MessagePublishInfo pb = message.getMessagePublishInfo();
+ exchangeName = pb.getExchange();
+ routingKey = pb.getRoutingKey();
+ }
+ else
+ {
+ MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
+ DeliveryProperties delvProps = message.getHeader().getDeliveryProperties();
+ exchangeName = (delvProps == null || delvProps.getExchange() == null) ? null : new AMQShortString(delvProps.getExchange());
+ routingKey = (delvProps == null || delvProps.getRoutingKey() == null) ? null : new AMQShortString(delvProps.getRoutingKey());
+ }
+
+ final boolean isRedelivered = entry.isRedelivered();
+
+ final AMQBody returnBlock = new AMQBody()
+ {
+
+ public AMQBody _underlyingBody;
+
+ public AMQBody createAMQBody()
+ {
+ return METHOD_REGISTRY.createBasicDeliverBody(consumerTag,
+ deliveryTag,
+ isRedelivered,
+ exchangeName,
+ routingKey);
+
+
+
+
+
+ }
+
+ public byte getFrameType()
+ {
+ return AMQMethodBody.TYPE;
+ }
+
+ public int getSize()
+ {
+ if(_underlyingBody == null)
+ {
+ _underlyingBody = createAMQBody();
+ }
+ return _underlyingBody.getSize();
+ }
+
+ public void writePayload(DataOutput buffer) throws IOException
+ {
+ if(_underlyingBody == null)
+ {
+ _underlyingBody = createAMQBody();
+ }
+ _underlyingBody.writePayload(buffer);
+ }
+
+ public void handle(final int channelId, final AMQVersionAwareProtocolSession amqMinaProtocolSession)
+ throws AMQException
+ {
+ throw new AMQException("This block should never be dispatched!");
+ }
+ };
+ return returnBlock;
+ }
+
+ private AMQBody createEncodedGetOkBody(QueueEntry entry, long deliveryTag, int queueSize)
+ throws AMQException
+ {
+ final AMQShortString exchangeName;
+ final AMQShortString routingKey;
+
+ if(entry.getMessage() instanceof AMQMessage)
+ {
+ final AMQMessage message = (AMQMessage) entry.getMessage();
+ final MessagePublishInfo pb = message.getMessagePublishInfo();
+ exchangeName = pb.getExchange();
+ routingKey = pb.getRoutingKey();
+ }
+ else
+ {
+ MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
+ DeliveryProperties delvProps = message.getHeader().getDeliveryProperties();
+ exchangeName = (delvProps == null || delvProps.getExchange() == null) ? null : new AMQShortString(delvProps.getExchange());
+ routingKey = (delvProps == null || delvProps.getRoutingKey() == null) ? null : new AMQShortString(delvProps.getRoutingKey());
+ }
+
+ final boolean isRedelivered = entry.isRedelivered();
+
+ BasicGetOkBody getOkBody =
+ METHOD_REGISTRY.createBasicGetOkBody(deliveryTag,
+ isRedelivered,
+ exchangeName,
+ routingKey,
+ queueSize);
+
+ return getOkBody;
+ }
+
+ public byte getProtocolMinorVersion()
+ {
+ return getProtocolSession().getProtocolMinorVersion();
+ }
+
+ public byte getProtocolMajorVersion()
+ {
+ return getProtocolSession().getProtocolMajorVersion();
+ }
+
+ private AMQBody createEncodedReturnFrame(MessagePublishInfo messagePublishInfo,
+ int replyCode,
+ AMQShortString replyText) throws AMQException
+ {
+
+ BasicReturnBody basicReturnBody =
+ METHOD_REGISTRY.createBasicReturnBody(replyCode,
+ replyText,
+ messagePublishInfo.getExchange(),
+ messagePublishInfo.getRoutingKey());
+
+
+ return basicReturnBody;
+ }
+
+ public void writeReturn(MessagePublishInfo messagePublishInfo, ContentHeaderBody header, MessageContentSource message, int channelId, int replyCode, AMQShortString replyText)
+ throws AMQException
+ {
+
+ AMQBody returnFrame = createEncodedReturnFrame(messagePublishInfo, replyCode, replyText);
+
+ writeMessageDelivery(message, header, channelId, returnFrame);
+ }
+
+
+ public void writeFrame(AMQDataBlock block)
+ {
+ getProtocolSession().writeFrame(block);
+ }
+
+
+ public void confirmConsumerAutoClose(int channelId, AMQShortString consumerTag)
+ {
+
+ BasicCancelOkBody basicCancelOkBody = METHOD_REGISTRY.createBasicCancelOkBody(consumerTag);
+ writeFrame(basicCancelOkBody.generateFrame(channelId));
+
+ }
+
+
+ public static final class CompositeAMQBodyBlock extends AMQDataBlock
+ {
+ public static final int OVERHEAD = 3 * AMQFrame.getFrameOverhead();
+
+ private final AMQBody _methodBody;
+ private final AMQBody _headerBody;
+ private final AMQBody _contentBody;
+ private final int _channel;
+
+
+ public CompositeAMQBodyBlock(int channel, AMQBody methodBody, AMQBody headerBody, AMQBody contentBody)
+ {
+ _channel = channel;
+ _methodBody = methodBody;
+ _headerBody = headerBody;
+ _contentBody = contentBody;
+
+ }
+
+ public long getSize()
+ {
+ return OVERHEAD + _methodBody.getSize() + _headerBody.getSize() + _contentBody.getSize();
+ }
+
+ public void writePayload(DataOutput buffer) throws IOException
+ {
+ AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody, _contentBody);
+ }
+ }
+
+ public static final class SmallCompositeAMQBodyBlock extends AMQDataBlock
+ {
+ public static final int OVERHEAD = 2 * AMQFrame.getFrameOverhead();
+
+ private final AMQBody _methodBody;
+ private final AMQBody _headerBody;
+ private final int _channel;
+
+
+ public SmallCompositeAMQBodyBlock(int channel, AMQBody methodBody, AMQBody headerBody)
+ {
+ _channel = channel;
+ _methodBody = methodBody;
+ _headerBody = headerBody;
+
+ }
+
+ public long getSize()
+ {
+ return OVERHEAD + _methodBody.getSize() + _headerBody.getSize() ;
+ }
+
+ public void writePayload(DataOutput buffer) throws IOException
+ {
+ AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody);
+ }
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9/ProtocolOutputConverterImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9/ProtocolOutputConverterImpl.java
index aef3483282..010afcb1a9 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9/ProtocolOutputConverterImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9/ProtocolOutputConverterImpl.java
@@ -1,419 +1,418 @@
-package org.apache.qpid.server.output.amqp0_9;
-/*
- *
- * 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.
- *
- */
-
-import org.apache.qpid.server.output.ProtocolOutputConverter;
-import org.apache.qpid.server.output.HeaderPropertiesConverter;
-import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.message.AMQMessage;
-import org.apache.qpid.server.queue.QueueEntry;
-import org.apache.qpid.server.message.MessageContentSource;
-import org.apache.qpid.server.message.MessageTransferMessage;
-import org.apache.qpid.framing.*;
-import org.apache.qpid.framing.amqp_0_9.BasicGetBodyImpl;
-import org.apache.qpid.framing.abstraction.MessagePublishInfo;
-import org.apache.qpid.framing.abstraction.ProtocolVersionMethodConverter;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.transport.DeliveryProperties;
-import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-public class ProtocolOutputConverterImpl implements ProtocolOutputConverter
-{
- private static final MethodRegistry METHOD_REGISTRY = MethodRegistry.getMethodRegistry(ProtocolVersion.v0_9);
-
-
- public static Factory getInstanceFactory()
- {
- return new Factory()
- {
-
- public ProtocolOutputConverter newInstance(AMQProtocolSession session)
- {
- return new ProtocolOutputConverterImpl(session);
- }
- };
- }
-
- private final AMQProtocolSession _protocolSession;
-
- private ProtocolOutputConverterImpl(AMQProtocolSession session)
- {
- _protocolSession = session;
- }
-
-
- public AMQProtocolSession getProtocolSession()
- {
- return _protocolSession;
- }
-
- public void writeDeliver(QueueEntry entry, int channelId, long deliveryTag, AMQShortString consumerTag)
- throws AMQException
- {
- AMQBody deliverBody = createEncodedDeliverBody(entry, deliveryTag, consumerTag);
- writeMessageDelivery(entry, channelId, deliverBody);
- }
-
-
- private ContentHeaderBody getContentHeaderBody(QueueEntry entry)
- throws AMQException
- {
- if(entry.getMessage() instanceof AMQMessage)
- {
- return ((AMQMessage)entry.getMessage()).getContentHeaderBody();
- }
- else
- {
- final MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
- BasicContentHeaderProperties props = HeaderPropertiesConverter.convert(message);
- ContentHeaderBody chb = new ContentHeaderBody(props, BasicGetBodyImpl.CLASS_ID);
- chb.bodySize = message.getSize();
- return chb;
- }
- }
-
-
- private void writeMessageDelivery(QueueEntry entry, int channelId, AMQBody deliverBody)
- throws AMQException
- {
- writeMessageDelivery(entry.getMessage(), getContentHeaderBody(entry), channelId, deliverBody);
- }
-
- private void writeMessageDelivery(MessageContentSource message, ContentHeaderBody contentHeaderBody, int channelId, AMQBody deliverBody)
- throws AMQException
- {
-
-
- int bodySize = (int) message.getSize();
-
- if(bodySize == 0)
- {
- SmallCompositeAMQBodyBlock compositeBlock = new SmallCompositeAMQBodyBlock(channelId, deliverBody,
- contentHeaderBody);
-
- writeFrame(compositeBlock);
- }
- else
- {
- int maxBodySize = (int) getProtocolSession().getMaxFrameSize() - AMQFrame.getFrameOverhead();
-
-
- int capacity = bodySize > maxBodySize ? maxBodySize : bodySize;
-
- int writtenSize = capacity;
-
- AMQBody firstContentBody = new MessageContentSourceBody(message,0,capacity);
-
-
- CompositeAMQBodyBlock
- compositeBlock = new CompositeAMQBodyBlock(channelId, deliverBody, contentHeaderBody, firstContentBody);
- writeFrame(compositeBlock);
-
- while(writtenSize < bodySize)
- {
- capacity = bodySize - writtenSize > maxBodySize ? maxBodySize : bodySize - writtenSize;
- MessageContentSourceBody body = new MessageContentSourceBody(message, writtenSize, capacity);
- writtenSize += capacity;
-
- writeFrame(new AMQFrame(channelId, body));
- }
- }
- }
-
- private class MessageContentSourceBody implements AMQBody
- {
- public static final byte TYPE = 3;
- private int _length;
- private MessageContentSource _message;
- private int _offset;
-
- public MessageContentSourceBody(MessageContentSource message, int offset, int length)
- {
- _message = message;
- _offset = offset;
- _length = length;
- }
-
- public byte getFrameType()
- {
- return TYPE;
- }
-
- public int getSize()
- {
- return _length;
- }
-
- public void writePayload(DataOutputStream buffer) throws IOException
- {
- byte[] data = new byte[_length];
-
- _message.getContent(ByteBuffer.wrap(data), _offset);
-
- buffer.write(data);
- }
-
- public void handle(int channelId, AMQVersionAwareProtocolSession amqProtocolSession) throws AMQException
- {
- throw new UnsupportedOperationException();
- }
- }
-
-
- private AMQDataBlock createContentHeaderBlock(final int channelId, final ContentHeaderBody contentHeaderBody)
- {
-
- AMQDataBlock contentHeader = ContentHeaderBody.createAMQFrame(channelId,
- contentHeaderBody);
- return contentHeader;
- }
-
-
- public void writeGetOk(QueueEntry entry, int channelId, long deliveryTag, int queueSize) throws AMQException
- {
- AMQBody deliver = createEncodedGetOkBody(entry, deliveryTag, queueSize);
- writeMessageDelivery(entry, channelId, deliver);
- }
-
-
- private AMQBody createEncodedDeliverBody(QueueEntry entry,
- final long deliveryTag,
- final AMQShortString consumerTag)
- throws AMQException
- {
-
- final AMQShortString exchangeName;
- final AMQShortString routingKey;
-
- if(entry.getMessage() instanceof AMQMessage)
- {
- final AMQMessage message = (AMQMessage) entry.getMessage();
- final MessagePublishInfo pb = message.getMessagePublishInfo();
- exchangeName = pb.getExchange();
- routingKey = pb.getRoutingKey();
- }
- else
- {
- MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
- DeliveryProperties delvProps = message.getHeader().get(DeliveryProperties.class);
- exchangeName = (delvProps == null || delvProps.getExchange() == null) ? null : new AMQShortString(delvProps.getExchange());
- routingKey = (delvProps == null || delvProps.getRoutingKey() == null) ? null : new AMQShortString(delvProps.getRoutingKey());
- }
-
- final boolean isRedelivered = entry.isRedelivered();
-
- final AMQBody returnBlock = new AMQBody()
- {
-
- public AMQBody _underlyingBody;
-
- public AMQBody createAMQBody()
- {
- return METHOD_REGISTRY.createBasicDeliverBody(consumerTag,
- deliveryTag,
- isRedelivered,
- exchangeName,
- routingKey);
-
-
-
-
-
- }
-
- public byte getFrameType()
- {
- return AMQMethodBody.TYPE;
- }
-
- public int getSize()
- {
- if(_underlyingBody == null)
- {
- _underlyingBody = createAMQBody();
- }
- return _underlyingBody.getSize();
- }
-
- public void writePayload(DataOutputStream buffer) throws IOException
- {
- if(_underlyingBody == null)
- {
- _underlyingBody = createAMQBody();
- }
- _underlyingBody.writePayload(buffer);
- }
-
- public void handle(final int channelId, final AMQVersionAwareProtocolSession amqMinaProtocolSession)
- throws AMQException
- {
- throw new AMQException("This block should never be dispatched!");
- }
- };
- return returnBlock;
- }
-
- private AMQBody createEncodedGetOkBody(QueueEntry entry, long deliveryTag, int queueSize)
- throws AMQException
- {
- final AMQShortString exchangeName;
- final AMQShortString routingKey;
-
- if(entry.getMessage() instanceof AMQMessage)
- {
- final AMQMessage message = (AMQMessage) entry.getMessage();
- final MessagePublishInfo pb = message.getMessagePublishInfo();
- exchangeName = pb.getExchange();
- routingKey = pb.getRoutingKey();
- }
- else
- {
- MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
- DeliveryProperties delvProps = message.getHeader().get(DeliveryProperties.class);
- exchangeName = (delvProps == null || delvProps.getExchange() == null) ? null : new AMQShortString(delvProps.getExchange());
- routingKey = (delvProps == null || delvProps.getRoutingKey() == null) ? null : new AMQShortString(delvProps.getRoutingKey());
- }
-
- final boolean isRedelivered = entry.isRedelivered();
-
- BasicGetOkBody getOkBody =
- METHOD_REGISTRY.createBasicGetOkBody(deliveryTag,
- isRedelivered,
- exchangeName,
- routingKey,
- queueSize);
-
- return getOkBody;
- }
-
- public byte getProtocolMinorVersion()
- {
- return getProtocolSession().getProtocolMinorVersion();
- }
-
- public byte getProtocolMajorVersion()
- {
- return getProtocolSession().getProtocolMajorVersion();
- }
-
- private AMQBody createEncodedReturnFrame(MessagePublishInfo messagePublishInfo,
- int replyCode,
- AMQShortString replyText) throws AMQException
- {
-
- BasicReturnBody basicReturnBody =
- METHOD_REGISTRY.createBasicReturnBody(replyCode,
- replyText,
- messagePublishInfo.getExchange(),
- messagePublishInfo.getRoutingKey());
-
-
- return basicReturnBody;
- }
-
- public void writeReturn(MessagePublishInfo messagePublishInfo, ContentHeaderBody header, MessageContentSource message, int channelId, int replyCode, AMQShortString replyText)
- throws AMQException
- {
-
- AMQBody returnFrame = createEncodedReturnFrame(messagePublishInfo, replyCode, replyText);
-
- writeMessageDelivery(message, header, channelId, returnFrame);
- }
-
-
- public void writeFrame(AMQDataBlock block)
- {
- getProtocolSession().writeFrame(block);
- }
-
-
- public void confirmConsumerAutoClose(int channelId, AMQShortString consumerTag)
- {
-
- BasicCancelOkBody basicCancelOkBody = METHOD_REGISTRY.createBasicCancelOkBody(consumerTag);
- writeFrame(basicCancelOkBody.generateFrame(channelId));
-
- }
-
-
- public static final class CompositeAMQBodyBlock extends AMQDataBlock
- {
- public static final int OVERHEAD = 3 * AMQFrame.getFrameOverhead();
-
- private final AMQBody _methodBody;
- private final AMQBody _headerBody;
- private final AMQBody _contentBody;
- private final int _channel;
-
-
- public CompositeAMQBodyBlock(int channel, AMQBody methodBody, AMQBody headerBody, AMQBody contentBody)
- {
- _channel = channel;
- _methodBody = methodBody;
- _headerBody = headerBody;
- _contentBody = contentBody;
-
- }
-
- public long getSize()
- {
- return OVERHEAD + _methodBody.getSize() + _headerBody.getSize() + _contentBody.getSize();
- }
-
- public void writePayload(DataOutputStream buffer) throws IOException
- {
- AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody, _contentBody);
- }
- }
-
- public static final class SmallCompositeAMQBodyBlock extends AMQDataBlock
- {
- public static final int OVERHEAD = 2 * AMQFrame.getFrameOverhead();
-
- private final AMQBody _methodBody;
- private final AMQBody _headerBody;
- private final int _channel;
-
-
- public SmallCompositeAMQBodyBlock(int channel, AMQBody methodBody, AMQBody headerBody)
- {
- _channel = channel;
- _methodBody = methodBody;
- _headerBody = headerBody;
-
- }
-
- public long getSize()
- {
- return OVERHEAD + _methodBody.getSize() + _headerBody.getSize() ;
- }
-
- public void writePayload(DataOutputStream buffer) throws IOException
- {
- AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody);
- }
- }
-
-}
+package org.apache.qpid.server.output.amqp0_9;
+/*
+ *
+ * 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.
+ *
+ */
+
+import org.apache.qpid.server.output.ProtocolOutputConverter;
+import org.apache.qpid.server.output.HeaderPropertiesConverter;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.message.AMQMessage;
+import org.apache.qpid.server.queue.QueueEntry;
+import org.apache.qpid.server.message.MessageContentSource;
+import org.apache.qpid.server.message.MessageTransferMessage;
+import org.apache.qpid.framing.*;
+import org.apache.qpid.framing.amqp_0_9.BasicGetBodyImpl;
+import org.apache.qpid.framing.abstraction.MessagePublishInfo;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.transport.DeliveryProperties;
+import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
+
+import java.io.DataOutput;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class ProtocolOutputConverterImpl implements ProtocolOutputConverter
+{
+ private static final MethodRegistry METHOD_REGISTRY = MethodRegistry.getMethodRegistry(ProtocolVersion.v0_9);
+
+
+ public static Factory getInstanceFactory()
+ {
+ return new Factory()
+ {
+
+ public ProtocolOutputConverter newInstance(AMQProtocolSession session)
+ {
+ return new ProtocolOutputConverterImpl(session);
+ }
+ };
+ }
+
+ private final AMQProtocolSession _protocolSession;
+
+ private ProtocolOutputConverterImpl(AMQProtocolSession session)
+ {
+ _protocolSession = session;
+ }
+
+
+ public AMQProtocolSession getProtocolSession()
+ {
+ return _protocolSession;
+ }
+
+ public void writeDeliver(QueueEntry entry, int channelId, long deliveryTag, AMQShortString consumerTag)
+ throws AMQException
+ {
+ AMQBody deliverBody = createEncodedDeliverBody(entry, deliveryTag, consumerTag);
+ writeMessageDelivery(entry, channelId, deliverBody);
+ }
+
+
+ private ContentHeaderBody getContentHeaderBody(QueueEntry entry)
+ throws AMQException
+ {
+ if(entry.getMessage() instanceof AMQMessage)
+ {
+ return ((AMQMessage)entry.getMessage()).getContentHeaderBody();
+ }
+ else
+ {
+ final MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
+ BasicContentHeaderProperties props = HeaderPropertiesConverter.convert(message);
+ ContentHeaderBody chb = new ContentHeaderBody(props, BasicGetBodyImpl.CLASS_ID);
+ chb.bodySize = message.getSize();
+ return chb;
+ }
+ }
+
+
+ private void writeMessageDelivery(QueueEntry entry, int channelId, AMQBody deliverBody)
+ throws AMQException
+ {
+ writeMessageDelivery(entry.getMessage(), getContentHeaderBody(entry), channelId, deliverBody);
+ }
+
+ private void writeMessageDelivery(MessageContentSource message, ContentHeaderBody contentHeaderBody, int channelId, AMQBody deliverBody)
+ throws AMQException
+ {
+
+
+ int bodySize = (int) message.getSize();
+
+ if(bodySize == 0)
+ {
+ SmallCompositeAMQBodyBlock compositeBlock = new SmallCompositeAMQBodyBlock(channelId, deliverBody,
+ contentHeaderBody);
+
+ writeFrame(compositeBlock);
+ }
+ else
+ {
+ int maxBodySize = (int) getProtocolSession().getMaxFrameSize() - AMQFrame.getFrameOverhead();
+
+
+ int capacity = bodySize > maxBodySize ? maxBodySize : bodySize;
+
+ int writtenSize = capacity;
+
+ AMQBody firstContentBody = new MessageContentSourceBody(message,0,capacity);
+
+
+ CompositeAMQBodyBlock
+ compositeBlock = new CompositeAMQBodyBlock(channelId, deliverBody, contentHeaderBody, firstContentBody);
+ writeFrame(compositeBlock);
+
+ while(writtenSize < bodySize)
+ {
+ capacity = bodySize - writtenSize > maxBodySize ? maxBodySize : bodySize - writtenSize;
+ MessageContentSourceBody body = new MessageContentSourceBody(message, writtenSize, capacity);
+ writtenSize += capacity;
+
+ writeFrame(new AMQFrame(channelId, body));
+ }
+ }
+ }
+
+ private class MessageContentSourceBody implements AMQBody
+ {
+ public static final byte TYPE = 3;
+ private int _length;
+ private MessageContentSource _message;
+ private int _offset;
+
+ public MessageContentSourceBody(MessageContentSource message, int offset, int length)
+ {
+ _message = message;
+ _offset = offset;
+ _length = length;
+ }
+
+ public byte getFrameType()
+ {
+ return TYPE;
+ }
+
+ public int getSize()
+ {
+ return _length;
+ }
+
+ public void writePayload(DataOutput buffer) throws IOException
+ {
+ byte[] data = new byte[_length];
+
+ _message.getContent(ByteBuffer.wrap(data), _offset);
+
+ buffer.write(data);
+ }
+
+ public void handle(int channelId, AMQVersionAwareProtocolSession amqProtocolSession) throws AMQException
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+
+ private AMQDataBlock createContentHeaderBlock(final int channelId, final ContentHeaderBody contentHeaderBody)
+ {
+
+ AMQDataBlock contentHeader = ContentHeaderBody.createAMQFrame(channelId,
+ contentHeaderBody);
+ return contentHeader;
+ }
+
+
+ public void writeGetOk(QueueEntry entry, int channelId, long deliveryTag, int queueSize) throws AMQException
+ {
+ AMQBody deliver = createEncodedGetOkBody(entry, deliveryTag, queueSize);
+ writeMessageDelivery(entry, channelId, deliver);
+ }
+
+
+ private AMQBody createEncodedDeliverBody(QueueEntry entry,
+ final long deliveryTag,
+ final AMQShortString consumerTag)
+ throws AMQException
+ {
+
+ final AMQShortString exchangeName;
+ final AMQShortString routingKey;
+
+ if(entry.getMessage() instanceof AMQMessage)
+ {
+ final AMQMessage message = (AMQMessage) entry.getMessage();
+ final MessagePublishInfo pb = message.getMessagePublishInfo();
+ exchangeName = pb.getExchange();
+ routingKey = pb.getRoutingKey();
+ }
+ else
+ {
+ MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
+ DeliveryProperties delvProps = message.getHeader().getDeliveryProperties();
+ exchangeName = (delvProps == null || delvProps.getExchange() == null) ? null : new AMQShortString(delvProps.getExchange());
+ routingKey = (delvProps == null || delvProps.getRoutingKey() == null) ? null : new AMQShortString(delvProps.getRoutingKey());
+ }
+
+ final boolean isRedelivered = entry.isRedelivered();
+
+ final AMQBody returnBlock = new AMQBody()
+ {
+
+ public AMQBody _underlyingBody;
+
+ public AMQBody createAMQBody()
+ {
+ return METHOD_REGISTRY.createBasicDeliverBody(consumerTag,
+ deliveryTag,
+ isRedelivered,
+ exchangeName,
+ routingKey);
+
+
+
+
+
+ }
+
+ public byte getFrameType()
+ {
+ return AMQMethodBody.TYPE;
+ }
+
+ public int getSize()
+ {
+ if(_underlyingBody == null)
+ {
+ _underlyingBody = createAMQBody();
+ }
+ return _underlyingBody.getSize();
+ }
+
+ public void writePayload(DataOutput buffer) throws IOException
+ {
+ if(_underlyingBody == null)
+ {
+ _underlyingBody = createAMQBody();
+ }
+ _underlyingBody.writePayload(buffer);
+ }
+
+ public void handle(final int channelId, final AMQVersionAwareProtocolSession amqMinaProtocolSession)
+ throws AMQException
+ {
+ throw new AMQException("This block should never be dispatched!");
+ }
+ };
+ return returnBlock;
+ }
+
+ private AMQBody createEncodedGetOkBody(QueueEntry entry, long deliveryTag, int queueSize)
+ throws AMQException
+ {
+ final AMQShortString exchangeName;
+ final AMQShortString routingKey;
+
+ if(entry.getMessage() instanceof AMQMessage)
+ {
+ final AMQMessage message = (AMQMessage) entry.getMessage();
+ final MessagePublishInfo pb = message.getMessagePublishInfo();
+ exchangeName = pb.getExchange();
+ routingKey = pb.getRoutingKey();
+ }
+ else
+ {
+ MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
+ DeliveryProperties delvProps = message.getHeader().getDeliveryProperties();
+ exchangeName = (delvProps == null || delvProps.getExchange() == null) ? null : new AMQShortString(delvProps.getExchange());
+ routingKey = (delvProps == null || delvProps.getRoutingKey() == null) ? null : new AMQShortString(delvProps.getRoutingKey());
+ }
+
+ final boolean isRedelivered = entry.isRedelivered();
+
+ BasicGetOkBody getOkBody =
+ METHOD_REGISTRY.createBasicGetOkBody(deliveryTag,
+ isRedelivered,
+ exchangeName,
+ routingKey,
+ queueSize);
+
+ return getOkBody;
+ }
+
+ public byte getProtocolMinorVersion()
+ {
+ return getProtocolSession().getProtocolMinorVersion();
+ }
+
+ public byte getProtocolMajorVersion()
+ {
+ return getProtocolSession().getProtocolMajorVersion();
+ }
+
+ private AMQBody createEncodedReturnFrame(MessagePublishInfo messagePublishInfo,
+ int replyCode,
+ AMQShortString replyText) throws AMQException
+ {
+
+ BasicReturnBody basicReturnBody =
+ METHOD_REGISTRY.createBasicReturnBody(replyCode,
+ replyText,
+ messagePublishInfo.getExchange(),
+ messagePublishInfo.getRoutingKey());
+
+
+ return basicReturnBody;
+ }
+
+ public void writeReturn(MessagePublishInfo messagePublishInfo, ContentHeaderBody header, MessageContentSource message, int channelId, int replyCode, AMQShortString replyText)
+ throws AMQException
+ {
+
+ AMQBody returnFrame = createEncodedReturnFrame(messagePublishInfo, replyCode, replyText);
+
+ writeMessageDelivery(message, header, channelId, returnFrame);
+ }
+
+
+ public void writeFrame(AMQDataBlock block)
+ {
+ getProtocolSession().writeFrame(block);
+ }
+
+
+ public void confirmConsumerAutoClose(int channelId, AMQShortString consumerTag)
+ {
+
+ BasicCancelOkBody basicCancelOkBody = METHOD_REGISTRY.createBasicCancelOkBody(consumerTag);
+ writeFrame(basicCancelOkBody.generateFrame(channelId));
+
+ }
+
+
+ public static final class CompositeAMQBodyBlock extends AMQDataBlock
+ {
+ public static final int OVERHEAD = 3 * AMQFrame.getFrameOverhead();
+
+ private final AMQBody _methodBody;
+ private final AMQBody _headerBody;
+ private final AMQBody _contentBody;
+ private final int _channel;
+
+
+ public CompositeAMQBodyBlock(int channel, AMQBody methodBody, AMQBody headerBody, AMQBody contentBody)
+ {
+ _channel = channel;
+ _methodBody = methodBody;
+ _headerBody = headerBody;
+ _contentBody = contentBody;
+
+ }
+
+ public long getSize()
+ {
+ return OVERHEAD + _methodBody.getSize() + _headerBody.getSize() + _contentBody.getSize();
+ }
+
+ public void writePayload(DataOutput buffer) throws IOException
+ {
+ AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody, _contentBody);
+ }
+ }
+
+ public static final class SmallCompositeAMQBodyBlock extends AMQDataBlock
+ {
+ public static final int OVERHEAD = 2 * AMQFrame.getFrameOverhead();
+
+ private final AMQBody _methodBody;
+ private final AMQBody _headerBody;
+ private final int _channel;
+
+
+ public SmallCompositeAMQBodyBlock(int channel, AMQBody methodBody, AMQBody headerBody)
+ {
+ _channel = channel;
+ _methodBody = methodBody;
+ _headerBody = headerBody;
+
+ }
+
+ public long getSize()
+ {
+ return OVERHEAD + _methodBody.getSize() + _headerBody.getSize() ;
+ }
+
+ public void writePayload(DataOutput buffer) throws IOException
+ {
+ AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody);
+ }
+ }
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9_1/ProtocolOutputConverterImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9_1/ProtocolOutputConverterImpl.java
index 10748298bc..5e2b3e4556 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9_1/ProtocolOutputConverterImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9_1/ProtocolOutputConverterImpl.java
@@ -1,414 +1,425 @@
-package org.apache.qpid.server.output.amqp0_9_1;
-/*
- *
- * 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.
- *
- */
-
-import org.apache.qpid.server.output.ProtocolOutputConverter;
-import org.apache.qpid.server.output.HeaderPropertiesConverter;
-import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.message.AMQMessage;
-import org.apache.qpid.server.queue.QueueEntry;
-import org.apache.qpid.server.message.MessageContentSource;
-import org.apache.qpid.server.message.MessageTransferMessage;
-import org.apache.qpid.framing.*;
-import org.apache.qpid.framing.amqp_0_91.BasicGetBodyImpl;
-import org.apache.qpid.framing.abstraction.MessagePublishInfo;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.transport.DeliveryProperties;
-import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-public class ProtocolOutputConverterImpl implements ProtocolOutputConverter
-{
- private static final MethodRegistry METHOD_REGISTRY = MethodRegistry.getMethodRegistry(ProtocolVersion.v0_91);
-
- public static Factory getInstanceFactory()
- {
- return new Factory()
- {
-
- public ProtocolOutputConverter newInstance(AMQProtocolSession session)
- {
- return new ProtocolOutputConverterImpl(session);
- }
- };
- }
-
- private final AMQProtocolSession _protocolSession;
-
- private ProtocolOutputConverterImpl(AMQProtocolSession session)
- {
- _protocolSession = session;
- }
-
-
- public AMQProtocolSession getProtocolSession()
- {
- return _protocolSession;
- }
-
- public void writeDeliver(QueueEntry entry, int channelId, long deliveryTag, AMQShortString consumerTag)
- throws AMQException
- {
- AMQBody deliverBody = createEncodedDeliverBody(entry, deliveryTag, consumerTag);
- writeMessageDelivery(entry, channelId, deliverBody);
- }
-
-
- private ContentHeaderBody getContentHeaderBody(QueueEntry entry)
- throws AMQException
- {
- if(entry.getMessage() instanceof AMQMessage)
- {
- return ((AMQMessage)entry.getMessage()).getContentHeaderBody();
- }
- else
- {
- final MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
- BasicContentHeaderProperties props = HeaderPropertiesConverter.convert(message);
- ContentHeaderBody chb = new ContentHeaderBody(props, BasicGetBodyImpl.CLASS_ID);
- chb.bodySize = message.getSize();
- return chb;
- }
- }
-
-
- private void writeMessageDelivery(QueueEntry entry, int channelId, AMQBody deliverBody)
- throws AMQException
- {
- writeMessageDelivery(entry.getMessage(), getContentHeaderBody(entry), channelId, deliverBody);
- }
-
- private void writeMessageDelivery(MessageContentSource message, ContentHeaderBody contentHeaderBody, int channelId, AMQBody deliverBody)
- throws AMQException
- {
-
-
- int bodySize = (int) message.getSize();
-
- if(bodySize == 0)
- {
- SmallCompositeAMQBodyBlock compositeBlock = new SmallCompositeAMQBodyBlock(channelId, deliverBody,
- contentHeaderBody);
-
- writeFrame(compositeBlock);
- }
- else
- {
- int maxBodySize = (int) getProtocolSession().getMaxFrameSize() - AMQFrame.getFrameOverhead();
-
-
- int capacity = bodySize > maxBodySize ? maxBodySize : bodySize;
-
- int writtenSize = capacity;
-
- AMQBody firstContentBody = new MessageContentSourceBody(message,0,capacity);
-
- CompositeAMQBodyBlock
- compositeBlock = new CompositeAMQBodyBlock(channelId, deliverBody, contentHeaderBody, firstContentBody);
- writeFrame(compositeBlock);
-
- while(writtenSize < bodySize)
- {
- capacity = bodySize - writtenSize > maxBodySize ? maxBodySize : bodySize - writtenSize;
- MessageContentSourceBody body = new MessageContentSourceBody(message, writtenSize, capacity);
- writtenSize += capacity;
-
- writeFrame(new AMQFrame(channelId, body));
- }
- }
- }
-
- private class MessageContentSourceBody implements AMQBody
- {
- public static final byte TYPE = 3;
- private int _length;
- private MessageContentSource _message;
- private int _offset;
-
- public MessageContentSourceBody(MessageContentSource message, int offset, int length)
- {
- _message = message;
- _offset = offset;
- _length = length;
- }
-
- public byte getFrameType()
- {
- return TYPE;
- }
-
- public int getSize()
- {
- return _length;
- }
-
- public void writePayload(DataOutputStream buffer) throws IOException
- {
- byte[] data = new byte[_length];
-
- _message.getContent(java.nio.ByteBuffer.wrap(data), _offset);
-
- buffer.write(data);
- }
-
- public void handle(int channelId, AMQVersionAwareProtocolSession amqProtocolSession) throws AMQException
- {
- throw new UnsupportedOperationException();
- }
- }
-
- private AMQDataBlock createContentHeaderBlock(final int channelId, final ContentHeaderBody contentHeaderBody)
- {
-
- AMQDataBlock contentHeader = ContentHeaderBody.createAMQFrame(channelId,
- contentHeaderBody);
- return contentHeader;
- }
-
-
- public void writeGetOk(QueueEntry entry, int channelId, long deliveryTag, int queueSize) throws AMQException
- {
- AMQBody deliver = createEncodedGetOkBody(entry, deliveryTag, queueSize);
- writeMessageDelivery(entry, channelId, deliver);
- }
-
-
- private AMQBody createEncodedDeliverBody(QueueEntry entry,
- final long deliveryTag,
- final AMQShortString consumerTag)
- throws AMQException
- {
-
- final AMQShortString exchangeName;
- final AMQShortString routingKey;
-
- if(entry.getMessage() instanceof AMQMessage)
- {
- final AMQMessage message = (AMQMessage) entry.getMessage();
- final MessagePublishInfo pb = message.getMessagePublishInfo();
- exchangeName = pb.getExchange();
- routingKey = pb.getRoutingKey();
- }
- else
- {
- MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
- DeliveryProperties delvProps = message.getHeader().get(DeliveryProperties.class);
- exchangeName = (delvProps == null || delvProps.getExchange() == null) ? null : new AMQShortString(delvProps.getExchange());
- routingKey = (delvProps == null || delvProps.getRoutingKey() == null) ? null : new AMQShortString(delvProps.getRoutingKey());
- }
-
- final boolean isRedelivered = entry.isRedelivered();
-
- final AMQBody returnBlock = new AMQBody()
- {
-
- public AMQBody _underlyingBody;
-
- public AMQBody createAMQBody()
- {
- return METHOD_REGISTRY.createBasicDeliverBody(consumerTag,
- deliveryTag,
- isRedelivered,
- exchangeName,
- routingKey);
-
-
-
-
-
- }
-
- public byte getFrameType()
- {
- return AMQMethodBody.TYPE;
- }
-
- public int getSize()
- {
- if(_underlyingBody == null)
- {
- _underlyingBody = createAMQBody();
- }
- return _underlyingBody.getSize();
- }
-
- public void writePayload(DataOutputStream buffer) throws IOException
- {
- if(_underlyingBody == null)
- {
- _underlyingBody = createAMQBody();
- }
- _underlyingBody.writePayload(buffer);
- }
-
- public void handle(final int channelId, final AMQVersionAwareProtocolSession amqMinaProtocolSession)
- throws AMQException
- {
- throw new AMQException("This block should never be dispatched!");
- }
- };
- return returnBlock;
- }
-
- private AMQBody createEncodedGetOkBody(QueueEntry entry, long deliveryTag, int queueSize)
- throws AMQException
- {
- final AMQShortString exchangeName;
- final AMQShortString routingKey;
-
- if(entry.getMessage() instanceof AMQMessage)
- {
- final AMQMessage message = (AMQMessage) entry.getMessage();
- final MessagePublishInfo pb = message.getMessagePublishInfo();
- exchangeName = pb.getExchange();
- routingKey = pb.getRoutingKey();
- }
- else
- {
- MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
- DeliveryProperties delvProps = message.getHeader().get(DeliveryProperties.class);
- exchangeName = (delvProps == null || delvProps.getExchange() == null) ? null : new AMQShortString(delvProps.getExchange());
- routingKey = (delvProps == null || delvProps.getRoutingKey() == null) ? null : new AMQShortString(delvProps.getRoutingKey());
- }
-
- final boolean isRedelivered = entry.isRedelivered();
-
- BasicGetOkBody getOkBody =
- METHOD_REGISTRY.createBasicGetOkBody(deliveryTag,
- isRedelivered,
- exchangeName,
- routingKey,
- queueSize);
-
- return getOkBody;
- }
-
- public byte getProtocolMinorVersion()
- {
- return getProtocolSession().getProtocolMinorVersion();
- }
-
- public byte getProtocolMajorVersion()
- {
- return getProtocolSession().getProtocolMajorVersion();
- }
-
- private AMQBody createEncodedReturnFrame(MessagePublishInfo messagePublishInfo,
- int replyCode,
- AMQShortString replyText) throws AMQException
- {
-
- BasicReturnBody basicReturnBody =
- METHOD_REGISTRY.createBasicReturnBody(replyCode,
- replyText,
- messagePublishInfo.getExchange(),
- messagePublishInfo.getRoutingKey());
-
-
- return basicReturnBody;
- }
-
- public void writeReturn(MessagePublishInfo messagePublishInfo, ContentHeaderBody header, MessageContentSource message, int channelId, int replyCode, AMQShortString replyText)
- throws AMQException
- {
-
- AMQBody returnFrame = createEncodedReturnFrame(messagePublishInfo, replyCode, replyText);
-
- writeMessageDelivery(message, header, channelId, returnFrame);
- }
-
-
- public void writeFrame(AMQDataBlock block)
- {
- getProtocolSession().writeFrame(block);
- }
-
-
- public void confirmConsumerAutoClose(int channelId, AMQShortString consumerTag)
- {
-
- BasicCancelOkBody basicCancelOkBody = METHOD_REGISTRY.createBasicCancelOkBody(consumerTag);
- writeFrame(basicCancelOkBody.generateFrame(channelId));
-
- }
-
-
- public static final class CompositeAMQBodyBlock extends AMQDataBlock
- {
- public static final int OVERHEAD = 3 * AMQFrame.getFrameOverhead();
-
- private final AMQBody _methodBody;
- private final AMQBody _headerBody;
- private final AMQBody _contentBody;
- private final int _channel;
-
-
- public CompositeAMQBodyBlock(int channel, AMQBody methodBody, AMQBody headerBody, AMQBody contentBody)
- {
- _channel = channel;
- _methodBody = methodBody;
- _headerBody = headerBody;
- _contentBody = contentBody;
-
- }
-
- public long getSize()
- {
- return OVERHEAD + _methodBody.getSize() + _headerBody.getSize() + _contentBody.getSize();
- }
-
- public void writePayload(DataOutputStream buffer) throws IOException
- {
- AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody, _contentBody);
- }
- }
-
- public static final class SmallCompositeAMQBodyBlock extends AMQDataBlock
- {
- public static final int OVERHEAD = 2 * AMQFrame.getFrameOverhead();
-
- private final AMQBody _methodBody;
- private final AMQBody _headerBody;
- private final int _channel;
-
-
- public SmallCompositeAMQBodyBlock(int channel, AMQBody methodBody, AMQBody headerBody)
- {
- _channel = channel;
- _methodBody = methodBody;
- _headerBody = headerBody;
-
- }
-
- public long getSize()
- {
- return OVERHEAD + _methodBody.getSize() + _headerBody.getSize() ;
- }
-
- public void writePayload(DataOutputStream buffer) throws IOException
- {
- AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody);
- }
- }
-
+package org.apache.qpid.server.output.amqp0_9_1;
+/*
+ *
+ * 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.
+ *
+ */
+
+import org.apache.qpid.server.output.ProtocolOutputConverter;
+import org.apache.qpid.server.output.HeaderPropertiesConverter;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.message.AMQMessage;
+import org.apache.qpid.server.queue.QueueEntry;
+import org.apache.qpid.server.message.MessageContentSource;
+import org.apache.qpid.server.message.MessageTransferMessage;
+import org.apache.qpid.framing.*;
+import org.apache.qpid.framing.amqp_0_91.BasicGetBodyImpl;
+import org.apache.qpid.framing.abstraction.MessagePublishInfo;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.transport.DeliveryProperties;
+import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
+
+import java.io.DataOutput;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class ProtocolOutputConverterImpl implements ProtocolOutputConverter
+{
+ private static final MethodRegistry METHOD_REGISTRY = MethodRegistry.getMethodRegistry(ProtocolVersion.v0_91);
+
+ public static Factory getInstanceFactory()
+ {
+ return new Factory()
+ {
+
+ public ProtocolOutputConverter newInstance(AMQProtocolSession session)
+ {
+ return new ProtocolOutputConverterImpl(session);
+ }
+ };
+ }
+
+ private final AMQProtocolSession _protocolSession;
+
+ private ProtocolOutputConverterImpl(AMQProtocolSession session)
+ {
+ _protocolSession = session;
+ }
+
+
+ public AMQProtocolSession getProtocolSession()
+ {
+ return _protocolSession;
+ }
+
+ public void writeDeliver(QueueEntry entry, int channelId, long deliveryTag, AMQShortString consumerTag)
+ throws AMQException
+ {
+ AMQBody deliverBody = createEncodedDeliverBody(entry, deliveryTag, consumerTag);
+ writeMessageDelivery(entry, channelId, deliverBody);
+ }
+
+
+ private ContentHeaderBody getContentHeaderBody(QueueEntry entry)
+ throws AMQException
+ {
+ if(entry.getMessage() instanceof AMQMessage)
+ {
+ return ((AMQMessage)entry.getMessage()).getContentHeaderBody();
+ }
+ else
+ {
+ final MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
+ BasicContentHeaderProperties props = HeaderPropertiesConverter.convert(message);
+ ContentHeaderBody chb = new ContentHeaderBody(props, BasicGetBodyImpl.CLASS_ID);
+ chb.bodySize = message.getSize();
+ return chb;
+ }
+ }
+
+
+ private void writeMessageDelivery(QueueEntry entry, int channelId, AMQBody deliverBody)
+ throws AMQException
+ {
+ writeMessageDelivery(entry.getMessage(), getContentHeaderBody(entry), channelId, deliverBody);
+ }
+
+ private void writeMessageDelivery(MessageContentSource message, ContentHeaderBody contentHeaderBody, int channelId, AMQBody deliverBody)
+ throws AMQException
+ {
+
+
+ int bodySize = (int) message.getSize();
+
+ if(bodySize == 0)
+ {
+ SmallCompositeAMQBodyBlock compositeBlock = new SmallCompositeAMQBodyBlock(channelId, deliverBody,
+ contentHeaderBody);
+
+ writeFrame(compositeBlock);
+ }
+ else
+ {
+ int maxBodySize = (int) getProtocolSession().getMaxFrameSize() - AMQFrame.getFrameOverhead();
+
+
+ int capacity = bodySize > maxBodySize ? maxBodySize : bodySize;
+
+ int writtenSize = capacity;
+
+ AMQBody firstContentBody = new MessageContentSourceBody(message,0,capacity);
+
+ CompositeAMQBodyBlock
+ compositeBlock = new CompositeAMQBodyBlock(channelId, deliverBody, contentHeaderBody, firstContentBody);
+ writeFrame(compositeBlock);
+
+ while(writtenSize < bodySize)
+ {
+ capacity = bodySize - writtenSize > maxBodySize ? maxBodySize : bodySize - writtenSize;
+ MessageContentSourceBody body = new MessageContentSourceBody(message, writtenSize, capacity);
+ writtenSize += capacity;
+
+ writeFrame(new AMQFrame(channelId, body));
+ }
+ }
+ }
+
+ private class MessageContentSourceBody implements AMQBody
+ {
+ public static final byte TYPE = 3;
+ private int _length;
+ private MessageContentSource _message;
+ private int _offset;
+
+ public MessageContentSourceBody(MessageContentSource message, int offset, int length)
+ {
+ _message = message;
+ _offset = offset;
+ _length = length;
+ }
+
+ public byte getFrameType()
+ {
+ return TYPE;
+ }
+
+ public int getSize()
+ {
+ return _length;
+ }
+
+ public void writePayload(DataOutput buffer) throws IOException
+ {
+ ByteBuffer buf = _message.getContent(_offset, _length);
+
+ if(buf.hasArray())
+ {
+ buffer.write(buf.array(), buf.arrayOffset()+buf.position(), buf.remaining());
+ }
+ else
+ {
+
+ byte[] data = new byte[_length];
+
+ buf.get(data);
+
+ buffer.write(data);
+ }
+ }
+
+ public void handle(int channelId, AMQVersionAwareProtocolSession amqProtocolSession) throws AMQException
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private AMQDataBlock createContentHeaderBlock(final int channelId, final ContentHeaderBody contentHeaderBody)
+ {
+
+ AMQDataBlock contentHeader = ContentHeaderBody.createAMQFrame(channelId,
+ contentHeaderBody);
+ return contentHeader;
+ }
+
+
+ public void writeGetOk(QueueEntry entry, int channelId, long deliveryTag, int queueSize) throws AMQException
+ {
+ AMQBody deliver = createEncodedGetOkBody(entry, deliveryTag, queueSize);
+ writeMessageDelivery(entry, channelId, deliver);
+ }
+
+
+ private AMQBody createEncodedDeliverBody(QueueEntry entry,
+ final long deliveryTag,
+ final AMQShortString consumerTag)
+ throws AMQException
+ {
+
+ final AMQShortString exchangeName;
+ final AMQShortString routingKey;
+
+ if(entry.getMessage() instanceof AMQMessage)
+ {
+ final AMQMessage message = (AMQMessage) entry.getMessage();
+ final MessagePublishInfo pb = message.getMessagePublishInfo();
+ exchangeName = pb.getExchange();
+ routingKey = pb.getRoutingKey();
+ }
+ else
+ {
+ MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
+ DeliveryProperties delvProps = message.getHeader().getDeliveryProperties();
+ exchangeName = (delvProps == null || delvProps.getExchange() == null) ? null : new AMQShortString(delvProps.getExchange());
+ routingKey = (delvProps == null || delvProps.getRoutingKey() == null) ? null : new AMQShortString(delvProps.getRoutingKey());
+ }
+
+ final boolean isRedelivered = entry.isRedelivered();
+
+ final AMQBody returnBlock = new AMQBody()
+ {
+
+ public AMQBody _underlyingBody;
+
+ public AMQBody createAMQBody()
+ {
+ return METHOD_REGISTRY.createBasicDeliverBody(consumerTag,
+ deliveryTag,
+ isRedelivered,
+ exchangeName,
+ routingKey);
+
+
+
+
+
+ }
+
+ public byte getFrameType()
+ {
+ return AMQMethodBody.TYPE;
+ }
+
+ public int getSize()
+ {
+ if(_underlyingBody == null)
+ {
+ _underlyingBody = createAMQBody();
+ }
+ return _underlyingBody.getSize();
+ }
+
+ public void writePayload(DataOutput buffer) throws IOException
+ {
+ if(_underlyingBody == null)
+ {
+ _underlyingBody = createAMQBody();
+ }
+ _underlyingBody.writePayload(buffer);
+ }
+
+ public void handle(final int channelId, final AMQVersionAwareProtocolSession amqMinaProtocolSession)
+ throws AMQException
+ {
+ throw new AMQException("This block should never be dispatched!");
+ }
+ };
+ return returnBlock;
+ }
+
+ private AMQBody createEncodedGetOkBody(QueueEntry entry, long deliveryTag, int queueSize)
+ throws AMQException
+ {
+ final AMQShortString exchangeName;
+ final AMQShortString routingKey;
+
+ if(entry.getMessage() instanceof AMQMessage)
+ {
+ final AMQMessage message = (AMQMessage) entry.getMessage();
+ final MessagePublishInfo pb = message.getMessagePublishInfo();
+ exchangeName = pb.getExchange();
+ routingKey = pb.getRoutingKey();
+ }
+ else
+ {
+ MessageTransferMessage message = (MessageTransferMessage) entry.getMessage();
+ DeliveryProperties delvProps = message.getHeader().getDeliveryProperties();
+ exchangeName = (delvProps == null || delvProps.getExchange() == null) ? null : new AMQShortString(delvProps.getExchange());
+ routingKey = (delvProps == null || delvProps.getRoutingKey() == null) ? null : new AMQShortString(delvProps.getRoutingKey());
+ }
+
+ final boolean isRedelivered = entry.isRedelivered();
+
+ BasicGetOkBody getOkBody =
+ METHOD_REGISTRY.createBasicGetOkBody(deliveryTag,
+ isRedelivered,
+ exchangeName,
+ routingKey,
+ queueSize);
+
+ return getOkBody;
+ }
+
+ public byte getProtocolMinorVersion()
+ {
+ return getProtocolSession().getProtocolMinorVersion();
+ }
+
+ public byte getProtocolMajorVersion()
+ {
+ return getProtocolSession().getProtocolMajorVersion();
+ }
+
+ private AMQBody createEncodedReturnFrame(MessagePublishInfo messagePublishInfo,
+ int replyCode,
+ AMQShortString replyText) throws AMQException
+ {
+
+ BasicReturnBody basicReturnBody =
+ METHOD_REGISTRY.createBasicReturnBody(replyCode,
+ replyText,
+ messagePublishInfo.getExchange(),
+ messagePublishInfo.getRoutingKey());
+
+
+ return basicReturnBody;
+ }
+
+ public void writeReturn(MessagePublishInfo messagePublishInfo, ContentHeaderBody header, MessageContentSource message, int channelId, int replyCode, AMQShortString replyText)
+ throws AMQException
+ {
+
+ AMQBody returnFrame = createEncodedReturnFrame(messagePublishInfo, replyCode, replyText);
+
+ writeMessageDelivery(message, header, channelId, returnFrame);
+ }
+
+
+ public void writeFrame(AMQDataBlock block)
+ {
+ getProtocolSession().writeFrame(block);
+ }
+
+
+ public void confirmConsumerAutoClose(int channelId, AMQShortString consumerTag)
+ {
+
+ BasicCancelOkBody basicCancelOkBody = METHOD_REGISTRY.createBasicCancelOkBody(consumerTag);
+ writeFrame(basicCancelOkBody.generateFrame(channelId));
+
+ }
+
+
+ public static final class CompositeAMQBodyBlock extends AMQDataBlock
+ {
+ public static final int OVERHEAD = 3 * AMQFrame.getFrameOverhead();
+
+ private final AMQBody _methodBody;
+ private final AMQBody _headerBody;
+ private final AMQBody _contentBody;
+ private final int _channel;
+
+
+ public CompositeAMQBodyBlock(int channel, AMQBody methodBody, AMQBody headerBody, AMQBody contentBody)
+ {
+ _channel = channel;
+ _methodBody = methodBody;
+ _headerBody = headerBody;
+ _contentBody = contentBody;
+
+ }
+
+ public long getSize()
+ {
+ return OVERHEAD + _methodBody.getSize() + _headerBody.getSize() + _contentBody.getSize();
+ }
+
+ public void writePayload(DataOutput buffer) throws IOException
+ {
+ AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody, _contentBody);
+ }
+ }
+
+ public static final class SmallCompositeAMQBodyBlock extends AMQDataBlock
+ {
+ public static final int OVERHEAD = 2 * AMQFrame.getFrameOverhead();
+
+ private final AMQBody _methodBody;
+ private final AMQBody _headerBody;
+ private final int _channel;
+
+
+ public SmallCompositeAMQBodyBlock(int channel, AMQBody methodBody, AMQBody headerBody)
+ {
+ _channel = channel;
+ _methodBody = methodBody;
+ _headerBody = headerBody;
+
+ }
+
+ public long getSize()
+ {
+ return OVERHEAD + _methodBody.getSize() + _headerBody.getSize() ;
+ }
+
+ public void writePayload(DataOutput buffer) throws IOException
+ {
+ AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody);
+ }
+ }
+
} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
index 4e5088808a..241ab3fcb9 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
@@ -93,6 +93,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
// to save boxing the channelId and looking up in a map... cache in an array the low numbered
// channels. This value must be of the form 2^x - 1.
private static final int CHANNEL_CACHE_SIZE = 0xff;
+ private static final int REUSABLE_BYTE_BUFFER_CAPACITY = 65 * 1024;
private AMQShortString _contextKey;
@@ -262,6 +263,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
closeProtocolSession();
}
}
+ receiveComplete();
}
catch (Exception e)
{
@@ -270,6 +272,15 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
}
}
+ private void receiveComplete()
+ {
+ for (AMQChannel channel : _channelMap.values())
+ {
+ channel.receivedComplete();
+ }
+
+ }
+
public void dataBlockReceived(AMQDataBlock message) throws Exception
{
_lastReceived = message;
@@ -387,35 +398,51 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
}
}
+
+ private final byte[] _reusableBytes = new byte[REUSABLE_BYTE_BUFFER_CAPACITY];
+ private final ByteBuffer _reusableByteBuffer = ByteBuffer.wrap(_reusableBytes);
+ private final BytesDataOutput _reusableDataOutput = new BytesDataOutput(_reusableBytes);
+
private ByteBuffer asByteBuffer(AMQDataBlock block)
{
- final ByteBuffer buf = ByteBuffer.allocate((int) block.getSize());
+ final int size = (int) block.getSize();
- try
- {
- block.writePayload(new DataOutputStream(new OutputStream()
- {
+ final byte[] data;
- @Override
- public void write(int b) throws IOException
- {
- buf.put((byte) b);
- }
+ if(size > REUSABLE_BYTE_BUFFER_CAPACITY)
+ {
+ data= new byte[size];
+ }
+ else
+ {
- @Override
- public void write(byte[] b, int off, int len) throws IOException
- {
- buf.put(b, off, len);
- }
- }));
+ data = _reusableBytes;
+ }
+ _reusableDataOutput.setBuffer(data);
+
+ try
+ {
+ block.writePayload(_reusableDataOutput);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
- buf.flip();
+ final ByteBuffer buf;
+
+ if(size <= REUSABLE_BYTE_BUFFER_CAPACITY)
+ {
+ buf = _reusableByteBuffer;
+ buf.position(0);
+ }
+ else
+ {
+ buf = ByteBuffer.wrap(data);
+ }
+ buf.limit(_reusableDataOutput.length());
+
return buf;
}
@@ -1418,8 +1445,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
_deferFlush = deferFlush;
}
-
-
public String getUserName()
{
return getAuthorizedPrincipal().getName();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java
index bc63403a86..c55fe321fc 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java
@@ -22,6 +22,8 @@ package org.apache.qpid.server.protocol;
import org.apache.qpid.AMQException;
import org.apache.qpid.server.logging.LogSubject;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.SimpleAMQQueue;
public interface AMQSessionModel
{
@@ -51,4 +53,8 @@ public interface AMQSessionModel
* @param idleClose time in milliseconds before closing connection with idle transaction
*/
public void checkTransactionStatus(long openWarn, long openClose, long idleWarn, long idleClose) throws AMQException;
+
+ void block(AMQQueue queue);
+
+ void unblock(AMQQueue queue);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java
index 3faf896aae..42b49cb546 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java
@@ -20,17 +20,14 @@
*/
package org.apache.qpid.server.protocol.v1_0;
+import java.util.List;
+import org.apache.qpid.AMQException;
import org.apache.qpid.amqp_1_0.type.Outcome;
import org.apache.qpid.amqp_1_0.type.messaging.Accepted;
-
-import org.apache.qpid.AMQException;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.txn.ServerTransaction;
-import java.util.ArrayList;
-import java.util.Arrays;
-
public class ExchangeDestination implements ReceivingDestination, SendingDestination
{
private static final Accepted ACCEPTED = new Accepted();
@@ -50,7 +47,7 @@ public class ExchangeDestination implements ReceivingDestination, SendingDestina
public Outcome send(final Message_1_0 message, ServerTransaction txn)
{
- final ArrayList<? extends BaseQueue> queues = _exchange.route(message);
+ final List<? extends BaseQueue> queues = _exchange.route(message);
txn.enqueue(queues,message, new ServerTransaction.Action()
{
@@ -77,7 +74,7 @@ public class ExchangeDestination implements ReceivingDestination, SendingDestina
{
// NO-OP
}
- });
+ }, System.currentTimeMillis());
return ACCEPTED;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java
index 5082d7097a..140a815f57 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java
@@ -21,20 +21,18 @@
package org.apache.qpid.server.protocol.v1_0;
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.util.List;
+import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.configuration.SessionConfig;
-import org.apache.qpid.server.message.AMQMessageHeader;
import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.message.MessageMetaData_1_0;
import org.apache.qpid.server.message.MessageReference;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.store.StoredMessage;
-import java.lang.ref.WeakReference;
-import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.List;
-
-public class Message_1_0 implements ServerMessage<Message_1_0>, InboundMessage
+public class Message_1_0 implements ServerMessage, InboundMessage
{
private final StoredMessage<MessageMetaData_1_0> _storedMessage;
private List<ByteBuffer> _fragments;
@@ -63,6 +61,11 @@ public class Message_1_0 implements ServerMessage<Message_1_0>, InboundMessage
}
}
+ public AMQShortString getRoutingKeyShortString()
+ {
+ return AMQShortString.valueOf(getRoutingKey());
+ }
+
private MessageMetaData_1_0 getMessageMetaData()
{
return _storedMessage.getMetaData();
@@ -73,6 +76,11 @@ public class Message_1_0 implements ServerMessage<Message_1_0>, InboundMessage
return getMessageMetaData().getMessageHeader();
}
+ public StoredMessage getStoredMessage()
+ {
+ return _storedMessage;
+ }
+
public boolean isPersistent()
{
return getMessageMetaData().isPersistent();
@@ -105,7 +113,7 @@ public class Message_1_0 implements ServerMessage<Message_1_0>, InboundMessage
return new Reference(this);
}
- public Long getMessageNumber()
+ public long getMessageNumber()
{
return _storedMessage.getMessageNumber();
}
@@ -120,6 +128,14 @@ public class Message_1_0 implements ServerMessage<Message_1_0>, InboundMessage
return _storedMessage.getContent(offset, buf);
}
+ public ByteBuffer getContent(int offset, int size)
+ {
+ ByteBuffer buf = ByteBuffer.allocate(size);
+ buf.limit(getContent(buf, offset));
+
+ return buf;
+ }
+
public SessionConfig getSessionConfig()
{
return null; //TODO
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLink_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLink_1_0.java
index 5c0143d809..c994ac9a2a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLink_1_0.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLink_1_0.java
@@ -20,6 +20,12 @@
*/
package org.apache.qpid.server.protocol.v1_0;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import org.apache.qpid.amqp_1_0.messaging.SectionDecoderImpl;
import org.apache.qpid.amqp_1_0.transport.DeliveryStateHandler;
import org.apache.qpid.amqp_1_0.transport.LinkEndpoint;
@@ -35,17 +41,12 @@ import org.apache.qpid.amqp_1_0.type.transaction.TransactionalState;
import org.apache.qpid.amqp_1_0.type.transport.Detach;
import org.apache.qpid.amqp_1_0.type.transport.ReceiverSettleMode;
import org.apache.qpid.amqp_1_0.type.transport.Transfer;
-
import org.apache.qpid.server.message.MessageMetaData_1_0;
import org.apache.qpid.server.store.StoredMessage;
import org.apache.qpid.server.txn.AutoCommitTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import java.lang.ref.WeakReference;
-import java.nio.ByteBuffer;
-import java.util.*;
-
public class ReceivingLink_1_0 implements ReceivingLinkListener, Link_1_0, DeliveryStateHandler
{
private VirtualHost _vhost;
@@ -181,7 +182,7 @@ public class ReceivingLink_1_0 implements ReceivingLinkListener, Link_1_0, Deliv
else
{
Session_1_0 session = getSession();
- transaction = session != null ? session.getTransaction(null) : new AutoCommitTransaction(_vhost.getTransactionLog());
+ transaction = session != null ? session.getTransaction(null) : new AutoCommitTransaction(_vhost.getMessageStore());
}
Outcome outcome = _destination.send(message, transaction);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java
index 1b335cf964..ed9d58994a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java
@@ -439,7 +439,7 @@ public class SendingLink_1_0 implements SendingLinkListener, Link_1_0, DeliveryS
if(outcome instanceof Accepted)
{
- AutoCommitTransaction txn = new AutoCommitTransaction(_vhost.getTransactionLog());
+ AutoCommitTransaction txn = new AutoCommitTransaction(_vhost.getMessageStore());
if(_subscription.acquires())
{
txn.dequeue(Collections.singleton(queueEntry),
@@ -459,7 +459,7 @@ public class SendingLink_1_0 implements SendingLinkListener, Link_1_0, DeliveryS
}
else if(outcome instanceof Released)
{
- AutoCommitTransaction txn = new AutoCommitTransaction(_vhost.getTransactionLog());
+ AutoCommitTransaction txn = new AutoCommitTransaction(_vhost.getMessageStore());
if(_subscription.acquires())
{
txn.dequeue(Collections.singleton(queueEntry),
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/TxnCoordinatorLink_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/TxnCoordinatorLink_1_0.java
index 0e700dc10b..a05d14816a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/TxnCoordinatorLink_1_0.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/TxnCoordinatorLink_1_0.java
@@ -124,7 +124,7 @@ public class TxnCoordinatorLink_1_0 implements ReceivingLinkListener, Link_1_0
}
txnId = Integer.valueOf(txnId.intValue() + 1);
- _openTransactions.put(txnId, new LocalTransaction(_vhost.getTransactionLog()));
+ _openTransactions.put(txnId, new LocalTransaction(_vhost.getMessageStore()));
Declared state = new Declared();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
index 6dfdc5e8b4..32d9c4878a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
@@ -149,7 +149,13 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
void removeMessagesFromQueue(long fromMessageId, long toMessageId);
-
+ static interface Visitor
+ {
+ boolean visit(QueueEntry entry);
+ }
+
+ void visit(Visitor visitor);
+
long getMaximumMessageSize();
@@ -217,7 +223,7 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
Map<String, Object> getArguments();
- void checkCapacity(AMQChannel channel);
+ void checkCapacity(AMQSessionModel channel);
/**
* ExistingExclusiveSubscription signals a failure to create a subscription, because an exclusive subscription
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
index b4765d6227..143a6ae8ca 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
@@ -557,7 +557,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
List<String> list = new ArrayList<String>();
AMQMessageHeader header = msg.getMessageHeader();
- MessageProperties msgProps = msg.getHeader().get(MessageProperties.class);
+ MessageProperties msgProps = msg.getHeader().getMessageProperties();
String appID = null;
String userID = null;
@@ -619,7 +619,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
throw new OperationsException("\"From MessageId\" should be greater than 0 and less than \"To MessageId\"");
}
- ServerTransaction txn = new LocalTransaction(_queue.getVirtualHost().getTransactionLog());
+ ServerTransaction txn = new LocalTransaction(_queue.getVirtualHost().getMessageStore());
_queue.moveMessagesToAnotherQueue(fromMessageId, toMessageId, toQueueName, txn);
txn.commit();
}
@@ -654,7 +654,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
throw new OperationsException("\"From MessageId\" should be greater than 0 and less than \"To MessageId\"");
}
- ServerTransaction txn = new LocalTransaction(_queue.getVirtualHost().getTransactionLog());
+ ServerTransaction txn = new LocalTransaction(_queue.getVirtualHost().getMessageStore());
_queue.copyMessagesToAnotherQueue(fromMessageId, toMessageId, toQueueName, txn);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/BaseQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/BaseQueue.java
index 05e0efd9a6..0bd40e8f13 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/BaseQueue.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/BaseQueue.java
@@ -35,6 +35,7 @@ public interface BaseQueue extends TransactionLogResource
void enqueue(ServerMessage message) throws AMQException;
void enqueue(ServerMessage message, PostEnqueueAction action) throws AMQException;
+ void enqueue(ServerMessage message, boolean transactional, PostEnqueueAction action) throws AMQException;
boolean isDurable();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java
index c4762c98c9..ab0a567114 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java
@@ -100,7 +100,7 @@ public class ConflationQueueList extends SimpleQueueEntryList
{
if(entry.acquire())
{
- ServerTransaction txn = new AutoCommitTransaction(getQueue().getVirtualHost().getTransactionLog());
+ ServerTransaction txn = new AutoCommitTransaction(getQueue().getVirtualHost().getMessageStore());
txn.dequeue(entry.getQueue(),entry.getMessage(),
new ServerTransaction.Action()
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java
index 26112d9f53..31e9725e47 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server.queue;
import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.message.AMQMessageHeader;
+import org.apache.qpid.framing.AMQShortString;
public class InboundMessageAdapter implements InboundMessage
{
@@ -44,6 +45,11 @@ public class InboundMessageAdapter implements InboundMessage
}
+ public AMQShortString getRoutingKeyShortString()
+ {
+ return AMQShortString.valueOf(_entry.getMessage());
+ }
+
public String getRoutingKey()
{
return _entry.getMessage().getRoutingKey();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java
index a56f5685b8..19a7a15ad1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java
@@ -63,7 +63,7 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes
* delivered. It is <b>cleared after delivery has been attempted</b>. Any persistent record of destinations is done
* by the message handle.
*/
- private ArrayList<? extends BaseQueue> _destinationQueues;
+ private List<? extends BaseQueue> _destinationQueues;
private long _expiration;
@@ -126,12 +126,18 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes
public MessageMetaData headersReceived()
{
- _messageMetaData = new MessageMetaData(_messagePublishInfo, _contentHeaderBody, 0);
+
+ return headersReceived(System.currentTimeMillis());
+ }
+
+ public MessageMetaData headersReceived(long currentTime)
+ {
+ _messageMetaData = new MessageMetaData(_messagePublishInfo, _contentHeaderBody, 0, currentTime);
return _messageMetaData;
}
- public ArrayList<? extends BaseQueue> getDestinationQueues()
+ public List<? extends BaseQueue> getDestinationQueues()
{
return _destinationQueues;
}
@@ -158,6 +164,11 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes
return _messagePublishInfo.getExchange();
}
+ public AMQShortString getRoutingKeyShortString()
+ {
+ return _messagePublishInfo.getRoutingKey();
+ }
+
public String getRoutingKey()
{
return _messagePublishInfo.getRoutingKey() == null ? null : _messagePublishInfo.getRoutingKey().toString();
@@ -209,7 +220,7 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes
return getContentHeader().bodySize;
}
- public Long getMessageNumber()
+ public long getMessageNumber()
{
return _storedMessageHandle.getMessageNumber();
}
@@ -225,7 +236,7 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes
}
- public void enqueue(final ArrayList<? extends BaseQueue> queues)
+ public void enqueue(final List<? extends BaseQueue> queues)
{
_destinationQueues = queues;
}
@@ -288,6 +299,15 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes
}
+
+ public ByteBuffer getContent(int offset, int size)
+ {
+ ByteBuffer buf = ByteBuffer.allocate(size);
+ getContent(buf,offset);
+ buf.flip();
+ return buf;
+ }
+
public void setStoredMessage(StoredMessage<MessageMetaData> storedMessageHandle)
{
_storedMessageHandle = storedMessageHandle;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/OutOfOrderQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/OutOfOrderQueue.java
index b16d1eb8e3..0220a553a7 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/OutOfOrderQueue.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/OutOfOrderQueue.java
@@ -1,12 +1,14 @@
package org.apache.qpid.server.queue;
import java.util.Map;
+
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.subscription.SubscriptionList;
import org.apache.qpid.server.virtualhost.VirtualHost;
public abstract class OutOfOrderQueue extends SimpleAMQQueue
{
+
protected OutOfOrderQueue(String name, boolean durable, String owner,
boolean autoDelete, boolean exclusive, VirtualHost virtualHost,
QueueEntryListFactory entryListFactory, Map<String, Object> arguments)
@@ -27,11 +29,8 @@ public abstract class OutOfOrderQueue extends SimpleAMQQueue
QueueContext context = (QueueContext) subscription.getQueueContext();
if(context != null)
{
- QueueEntry subnode = context._lastSeenEntry;
QueueEntry released = context._releasedEntry;
-
- while(subnode != null && entry.compareTo(subnode) < 0 && !entry.isAcquired()
- && (released == null || released.compareTo(entry) > 0))
+ while(!entry.isAcquired() && (released == null || released.compareTo(entry) > 0))
{
if(QueueContext._releasedUpdater.compareAndSet(context,released,entry))
{
@@ -39,14 +38,11 @@ public abstract class OutOfOrderQueue extends SimpleAMQQueue
}
else
{
- subnode = context._lastSeenEntry;
released = context._releasedEntry;
}
-
}
}
}
-
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
index 37fad54c07..142cfddb39 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
@@ -75,6 +75,11 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
{
return State.AVAILABLE;
}
+
+ public String toString()
+ {
+ return getState().name();
+ }
}
@@ -85,6 +90,11 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
{
return State.DEQUEUED;
}
+
+ public String toString()
+ {
+ return getState().name();
+ }
}
@@ -95,6 +105,11 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
{
return State.DELETED;
}
+
+ public String toString()
+ {
+ return getState().name();
+ }
}
public final class ExpiredState extends EntryState
@@ -104,6 +119,11 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
{
return State.EXPIRED;
}
+
+ public String toString()
+ {
+ return getState().name();
+ }
}
@@ -113,6 +133,11 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
{
return State.ACQUIRED;
}
+
+ public String toString()
+ {
+ return getState().name();
+ }
}
public final class SubscriptionAcquiredState extends EntryState
@@ -134,6 +159,11 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
{
return _subscription;
}
+
+ public String toString()
+ {
+ return "{" + getState().name() + " : " + _subscription +"}";
+ }
}
public final class SubscriptionAssignedState extends EntryState
@@ -155,6 +185,12 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
{
return _subscription;
}
+
+
+ public String toString()
+ {
+ return "{" + getState().name() + " : " + _subscription +"}";
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
index f1e50427b1..82c6a2f127 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
@@ -35,6 +35,7 @@ import org.apache.qpid.server.message.MessageReference;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.txn.AutoCommitTransaction;
+import org.apache.qpid.server.txn.LocalTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
public abstract class QueueEntryImpl implements QueueEntry
@@ -420,7 +421,7 @@ public abstract class QueueEntryImpl implements QueueEntry
if (rerouteQueues != null && rerouteQueues.size() != 0)
{
- ServerTransaction txn = new AutoCommitTransaction(getQueue().getVirtualHost().getTransactionLog());
+ ServerTransaction txn = new LocalTransaction(getQueue().getVirtualHost().getMessageStore());
txn.enqueue(rerouteQueues, message, new ServerTransaction.Action()
{
@@ -443,7 +444,8 @@ public abstract class QueueEntryImpl implements QueueEntry
{
}
- });
+ }, 0L);
+
txn.dequeue(currentQueue, message, new ServerTransaction.Action()
{
public void postCommit()
@@ -456,8 +458,10 @@ public abstract class QueueEntryImpl implements QueueEntry
}
});
- }
+
+ txn.commit();
}
+ }
}
public boolean isQueueDeleted()
@@ -545,4 +549,11 @@ public abstract class QueueEntryImpl implements QueueEntry
_deliveryCountUpdater.decrementAndGet(this);
}
+ public String toString()
+ {
+ return "QueueEntryImpl{" +
+ "_entryId=" + _entryId +
+ ", _state=" + _state +
+ '}';
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryList.java
index 77c4b912e0..641aaa0a08 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryList.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryList.java
@@ -35,4 +35,6 @@ public interface QueueEntryList<Q extends QueueEntry>
Q getHead();
void entryDeleted(Q queueEntry);
+
+ int getPriorities();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java
index 5270f9f740..0d44fe7cf3 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java
@@ -22,7 +22,6 @@ package org.apache.qpid.server.queue;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
-import org.apache.qpid.pool.ReadWriteRunnable;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.queue.QueueRunner;
import org.apache.qpid.server.queue.SimpleAMQQueue;
@@ -38,7 +37,7 @@ import java.util.concurrent.atomic.AtomicLong;
* when straight-through delivery of a message to a subscription isn't
* possible during the enqueue operation.
*/
-public class QueueRunner implements ReadWriteRunnable
+public class QueueRunner implements Runnable
{
private static final Logger _logger = Logger.getLogger(QueueRunner.class);
@@ -51,13 +50,11 @@ public class QueueRunner implements ReadWriteRunnable
private final AtomicInteger _scheduled = new AtomicInteger(IDLE);
- private static final long ITERATIONS = SimpleAMQQueue.MAX_ASYNC_DELIVERIES;
private final AtomicBoolean _stateChange = new AtomicBoolean();
private final AtomicLong _lastRunAgain = new AtomicLong();
private final AtomicLong _lastRunTime = new AtomicLong();
- private long _runs;
private long _continues;
public QueueRunner(SimpleAMQQueue queue)
@@ -65,8 +62,6 @@ public class QueueRunner implements ReadWriteRunnable
_queue = queue;
}
- private int trouble = 0;
-
public void run()
{
if(_scheduled.compareAndSet(SCHEDULED,RUNNING))
@@ -103,16 +98,6 @@ public class QueueRunner implements ReadWriteRunnable
}
}
- public boolean isRead()
- {
- return false;
- }
-
- public boolean isWrite()
- {
- return true;
- }
-
public String toString()
{
return "QueueRunner-" + _queue.getLogActor();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
index 08dab4e5fc..4faca15eb0 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
@@ -18,22 +18,33 @@
*/
package org.apache.qpid.server.queue;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import javax.management.JMException;
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.ReadWriteRunnable;
import org.apache.qpid.pool.ReferenceCountingExecutorService;
-import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.configuration.ConfigStore;
import org.apache.qpid.server.configuration.ConfiguredObject;
import org.apache.qpid.server.configuration.QueueConfigType;
import org.apache.qpid.server.configuration.QueueConfiguration;
import org.apache.qpid.server.configuration.SessionConfig;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.logging.LogSubject;
@@ -43,8 +54,12 @@ import org.apache.qpid.server.logging.messages.QueueMessages;
import org.apache.qpid.server.logging.subjects.QueueLogSubject;
import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.security.AuthorizationHolder;
+import org.apache.qpid.server.subscription.AssignedSubscriptionMessageGroupManager;
+import org.apache.qpid.server.subscription.DefinedGroupMessageGroupManager;
+import org.apache.qpid.server.subscription.MessageGroupManager;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.subscription.SubscriptionList;
import org.apache.qpid.server.txn.AutoCommitTransaction;
@@ -52,27 +67,15 @@ import org.apache.qpid.server.txn.LocalTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import javax.management.JMException;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.AtomicReference;
-
-public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
+public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, MessageGroupManager.SubscriptionResetHelper
{
private static final Logger _logger = Logger.getLogger(SimpleAMQQueue.class);
+ private static final String QPID_GROUP_HEADER_KEY = "qpid.group_header_key";
+ private static final String QPID_SHARED_MSG_GROUP = "qpid.shared_msg_group";
+ private static final String QPID_DEFAULT_MESSAGE_GROUP = "qpid.default-message-group";
+ private static final String QPID_NO_GROUP = "qpid.no-group";
+ // TODO - should make this configurable at the vhost / broker level
+ private static final int DEFAULT_MAX_GROUPS = 255;
private final VirtualHost _virtualHost;
@@ -164,7 +167,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
private AtomicInteger _deliveredMessages = new AtomicInteger();
private AtomicBoolean _stopped = new AtomicBoolean(false);
- private final ConcurrentMap<AMQChannel, Boolean> _blockedChannels = new ConcurrentHashMap<AMQChannel, Boolean>();
+ private final ConcurrentMap<AMQSessionModel, Boolean> _blockedChannels = new ConcurrentHashMap<AMQSessionModel, Boolean>();
private final AtomicBoolean _deleted = new AtomicBoolean(false);
private final List<Task> _deleteTaskList = new CopyOnWriteArrayList<Task>();
@@ -190,6 +193,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
/** the maximum delivery count for each message on this queue or 0 if maximum delivery count is not to be enforced. */
private int _maximumDeliveryCount = ApplicationRegistry.getInstance().getConfiguration().getMaxDeliveryCount();
+ private final MessageGroupManager _messageGroupManager;
protected SimpleAMQQueue(AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete, boolean exclusive, VirtualHost virtualHost, Map<String,Object> arguments)
{
@@ -245,25 +249,15 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
_logSubject = new QueueLogSubject(this);
_logActor = new QueueActor(this, CurrentActor.get().getRootMessageLogger());
- // Log the correct creation message
-
- // Extract the number of priorities for this Queue.
- // Leave it as 0 if we are a SimpleQueueEntryList
- int priorities = 0;
- if (entryListFactory instanceof PriorityQueueList.Factory)
- {
- priorities = ((PriorityQueueList)_entries).getPriorities();
- }
-
// Log the creation of this Queue.
// The priorities display is toggled on if we set priorities > 0
CurrentActor.get().message(_logSubject,
QueueMessages.CREATED(String.valueOf(_owner),
- priorities,
- _owner != null,
- autoDelete,
- durable, !durable,
- priorities > 0));
+ _entries.getPriorities(),
+ _owner != null,
+ autoDelete,
+ durable, !durable,
+ _entries.getPriorities() > 0));
getConfigStore().addConfiguredObject(this);
@@ -277,6 +271,26 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
_logger.error("AMQQueue MBean creation has failed ", e);
}
+ if(arguments != null && arguments.containsKey(QPID_GROUP_HEADER_KEY))
+ {
+ if(arguments.containsKey(QPID_SHARED_MSG_GROUP) && String.valueOf(arguments.get(QPID_SHARED_MSG_GROUP)).equals("1"))
+ {
+ String defaultGroup = String.valueOf(arguments.get(QPID_DEFAULT_MESSAGE_GROUP));
+ _messageGroupManager =
+ new DefinedGroupMessageGroupManager(String.valueOf(arguments.get(QPID_GROUP_HEADER_KEY)),
+ defaultGroup == null ? QPID_NO_GROUP : defaultGroup,
+ this);
+ }
+ else
+ {
+ _messageGroupManager = new AssignedSubscriptionMessageGroupManager(String.valueOf(arguments.get(QPID_GROUP_HEADER_KEY)), DEFAULT_MAX_GROUPS);
+ }
+ }
+ else
+ {
+ _messageGroupManager = null;
+ }
+
resetNotifications();
}
@@ -292,7 +306,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
// ------ Getters and Setters
- public void execute(ReadWriteRunnable runnable)
+ public void execute(Runnable runnable)
{
_asyncDelivery.execute(runnable);
}
@@ -491,6 +505,11 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
setExclusiveSubscriber(null);
subscription.setQueueContext(null);
+ if(_messageGroupManager != null)
+ {
+ resetSubPointersForGroups(subscription, true);
+ }
+
// auto-delete queues must be deleted if there are no remaining subscribers
if (_autoDelete && getDeleteOnNoConsumers() && !subscription.isTransient() && getConsumerCount() == 0 )
@@ -515,6 +534,34 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
+ public void resetSubPointersForGroups(Subscription subscription, boolean clearAssignments)
+ {
+ QueueEntry entry = _messageGroupManager.findEarliestAssignedAvailableEntry(subscription);
+ if(clearAssignments)
+ {
+ _messageGroupManager.clearAssignments(subscription);
+ }
+
+ if(entry != null)
+ {
+ SubscriptionList.SubscriptionNodeIterator subscriberIter = _subscriptionList.iterator();
+ // iterate over all the subscribers, and if they are in advance of this queue entry then move them backwards
+ while (subscriberIter.advance())
+ {
+ Subscription sub = subscriberIter.getNode().getSubscription();
+
+ // we don't make browsers send the same stuff twice
+ if (sub.seesRequeues())
+ {
+ updateSubRequeueEntry(sub, entry);
+ }
+ }
+
+ deliverAsync();
+
+ }
+ }
+
public boolean getDeleteOnNoConsumers()
{
return _deleteOnNoConsumers;
@@ -592,7 +639,16 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
public void enqueue(ServerMessage message, PostEnqueueAction action) throws AMQException
{
- incrementTxnEnqueueStats(message);
+ enqueue(message, false, action);
+ }
+
+ public void enqueue(ServerMessage message, boolean transactional, PostEnqueueAction action) throws AMQException
+ {
+
+ if(transactional)
+ {
+ incrementTxnEnqueueStats(message);
+ }
incrementQueueCount();
incrementQueueSize(message);
@@ -689,21 +745,20 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
{
try
{
- if (subscriptionReadyAndHasInterest(sub, entry)
- && !sub.isSuspended())
+ if (!sub.isSuspended()
+ && subscriptionReadyAndHasInterest(sub, entry)
+ && mightAssign(sub, entry)
+ && !sub.wouldSuspend(entry))
{
- if (!sub.wouldSuspend(entry))
+ if (sub.acquires() && !(assign(sub, entry) && entry.acquire(sub)))
{
- if (sub.acquires() && !entry.acquire(sub))
- {
- // restore credit here that would have been taken away by wouldSuspend since we didn't manage
- // to acquire the entry for this subscription
- sub.restoreCredit(entry);
- }
- else
- {
- deliverMessage(sub, entry, false);
- }
+ // restore credit here that would have been taken away by wouldSuspend since we didn't manage
+ // to acquire the entry for this subscription
+ sub.restoreCredit(entry);
+ }
+ else
+ {
+ deliverMessage(sub, entry, false);
}
}
}
@@ -714,6 +769,20 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
}
+ private boolean assign(final Subscription sub, final QueueEntry entry)
+ {
+ return _messageGroupManager == null || _messageGroupManager.acceptMessage(sub, entry);
+ }
+
+
+ private boolean mightAssign(final Subscription sub, final QueueEntry entry)
+ {
+ if(_messageGroupManager == null || !sub.acquires())
+ return true;
+ Subscription assigned = _messageGroupManager.getAssignedSubscription(entry);
+ return (assigned == null) || (assigned == sub);
+ }
+
protected void checkSubscriptionsNotAheadOfDelivery(final QueueEntry entry)
{
// This method is only required for queues which mess with ordering
@@ -739,13 +808,8 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
private void incrementTxnEnqueueStats(final ServerMessage message)
{
- SessionConfig session = message.getSessionConfig();
-
- if(session !=null && session.isTransactional())
- {
- _msgTxnEnqueues.incrementAndGet();
- _byteTxnEnqueues.addAndGet(message.getSize());
- }
+ _msgTxnEnqueues.incrementAndGet();
+ _byteTxnEnqueues.addAndGet(message.getSize());
}
private void incrementTxnDequeueStats(QueueEntry entry)
@@ -1057,6 +1121,8 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
public boolean filterComplete();
}
+
+
public List<QueueEntry> getMessagesOnTheQueue(final long fromMessageId, final long toMessageId)
{
return getMessagesOnTheQueue(new QueueEntryFilter()
@@ -1111,6 +1177,24 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
+ public void visit(final Visitor visitor)
+ {
+ QueueEntryIterator queueListIterator = _entries.iterator();
+
+ while(queueListIterator.advance())
+ {
+ QueueEntry node = queueListIterator.getNode();
+
+ if(!node.isDispensed())
+ {
+ if(visitor.visit(node))
+ {
+ break;
+ }
+ }
+ }
+ }
+
/**
* Returns a list of QueEntries from a given range of queue positions, eg messages 5 to 10 on the queue.
*
@@ -1487,7 +1571,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
{
}
- });
+ }, 0L);
txn.dequeue(this, entry.getMessage(),
new ServerTransaction.Action()
{
@@ -1565,7 +1649,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
}
- public void checkCapacity(AMQChannel channel)
+ public void checkCapacity(AMQSessionModel channel)
{
if(_capacity != 0l)
{
@@ -1575,10 +1659,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
//Overfull log message
_logActor.message(_logSubject, QueueMessages.OVERFULL(_atomicQueueSize.get(), _capacity));
- if(_blockedChannels.putIfAbsent(channel, Boolean.TRUE)==null)
- {
- channel.block(this);
- }
+ _blockedChannels.putIfAbsent(channel, Boolean.TRUE);
+
+ channel.block(this);
if(_atomicQueueSize.get() <= _flowResumeCapacity)
{
@@ -1610,7 +1693,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
- for(AMQChannel c : _blockedChannels.keySet())
+ for(AMQSessionModel c : _blockedChannels.keySet())
{
c.unblock(this);
_blockedChannels.remove(c);
@@ -1752,11 +1835,11 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
if (node != null && node.isAvailable())
{
- if (sub.hasInterest(node))
+ if (sub.hasInterest(node) && mightAssign(sub, node))
{
if (!sub.wouldSuspend(node))
{
- if (sub.acquires() && !node.acquire(sub))
+ if (sub.acquires() && !(assign(sub, node) && node.acquire(sub)))
{
// restore credit here that would have been taken away by wouldSuspend since we didn't manage
// to acquire the entry for this subscription
@@ -1813,7 +1896,8 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
QueueEntry node = (releasedNode != null && lastSeen.compareTo(releasedNode)>=0) ? releasedNode : _entries.next(lastSeen);
boolean expired = false;
- while (node != null && (!node.isAvailable() || (expired = node.expired()) || !sub.hasInterest(node)))
+ while (node != null && (!node.isAvailable() || (expired = node.expired()) || !sub.hasInterest(node) ||
+ !mightAssign(sub,node)))
{
if (expired)
{
@@ -1841,6 +1925,19 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
}
+ public boolean isEntryAheadOfSubscription(QueueEntry entry, Subscription sub)
+ {
+ QueueContext context = (QueueContext) sub.getQueueContext();
+ if(context != null)
+ {
+ QueueEntry releasedNode = context._releasedEntry;
+ return releasedNode == null || releasedNode.compareTo(entry) < 0;
+ }
+ else
+ {
+ return false;
+ }
+ }
/**
* Used by queue Runners to asynchronously deliver messages to consumers.
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java
index 0bb5dcc219..b40e5a28c2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java
@@ -185,6 +185,11 @@ public class SimpleQueueEntryList implements QueueEntryList<SimpleQueueEntryImpl
advanceHead();
}
+ public int getPriorities()
+ {
+ return 0;
+ }
+
static class Factory implements QueueEntryListFactory
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SortedQueueEntryList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SortedQueueEntryList.java
index 5f8ab16c06..414a123c43 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SortedQueueEntryList.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SortedQueueEntryList.java
@@ -51,13 +51,11 @@ public class SortedQueueEntryList implements QueueEntryList<SortedQueueEntryImpl
_propertyName = propertyName;
}
- @Override
public AMQQueue getQueue()
{
return _queue;
}
- @Override
public SortedQueueEntryImpl add(final ServerMessage message)
{
synchronized(_lock)
@@ -286,7 +284,6 @@ public class SortedQueueEntryList implements QueueEntryList<SortedQueueEntryImpl
return (node == null ? Colour.BLACK : node.getColour()) == colour;
}
- @Override
public SortedQueueEntryImpl next(final SortedQueueEntryImpl node)
{
synchronized(_lock)
@@ -316,13 +313,11 @@ public class SortedQueueEntryList implements QueueEntryList<SortedQueueEntryImpl
}
}
- @Override
public QueueEntryIterator<SortedQueueEntryImpl> iterator()
{
return new QueueEntryIteratorImpl(_head);
}
- @Override
public SortedQueueEntryImpl getHead()
{
return _head;
@@ -333,7 +328,6 @@ public class SortedQueueEntryList implements QueueEntryList<SortedQueueEntryImpl
return _root;
}
- @Override
public void entryDeleted(final SortedQueueEntryImpl entry)
{
synchronized(_lock)
@@ -431,6 +425,11 @@ public class SortedQueueEntryList implements QueueEntryList<SortedQueueEntryImpl
}
}
+ public int getPriorities()
+ {
+ return 0;
+ }
+
/**
* Swaps the position of the node in the tree with it's successor
* (that is the node with the next highest key)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SubFlushRunner.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SubFlushRunner.java
index fbef23dca1..48f2efb342 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SubFlushRunner.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SubFlushRunner.java
@@ -21,18 +21,17 @@ package org.apache.qpid.server.queue;
*/
-import org.apache.qpid.pool.ReadWriteRunnable;
-import org.apache.qpid.server.subscription.Subscription;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.AMQException;
-import org.apache.log4j.Logger;
-
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.log4j.Logger;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.subscription.Subscription;
+
-class SubFlushRunner implements ReadWriteRunnable
+class SubFlushRunner implements Runnable
{
private static final Logger _logger = Logger.getLogger(SubFlushRunner.class);
@@ -90,16 +89,6 @@ class SubFlushRunner implements ReadWriteRunnable
return (SimpleAMQQueue) _sub.getQueue();
}
- public boolean isRead()
- {
- return false;
- }
-
- public boolean isWrite()
- {
- return true;
- }
-
public String toString()
{
return "SubFlushRunner-" + _sub.getLogActor();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
index 7eb1b54693..6753cf4560 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
@@ -148,7 +148,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
BrokerConfig broker = new BrokerConfigAdapter(instance);
- SystemConfig system = (SystemConfig) store.getRoot();
+ SystemConfig system = store.getRoot();
system.addBroker(broker);
instance.setBroker(broker);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java
index 6a36b22400..f77b8d2dfa 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java
@@ -165,7 +165,6 @@ public class BrokerConfigAdapter implements BrokerConfig
/**
* @see org.apache.qpid.server.configuration.BrokerConfig#getFeatures()
*/
- @Override
public List<String> getFeatures()
{
final List<String> features = new ArrayList<String>();
@@ -176,4 +175,16 @@ public class BrokerConfigAdapter implements BrokerConfig
return Collections.unmodifiableList(features);
}
+
+ @Override
+ public String toString()
+ {
+ return "BrokerConfigAdapter{" +
+ "_id=" + _id +
+ ", _system=" + _system +
+ ", _vhosts=" + _vhosts +
+ ", _createTime=" + _createTime +
+ ", _federationTag='" + _federationTag + '\'' +
+ '}';
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
index abf9e3379d..2a1ae8a870 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
@@ -32,11 +32,9 @@ import static org.apache.qpid.server.security.access.Operation.UNBIND;
import java.net.SocketAddress;
import java.security.Principal;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import javax.security.auth.Subject;
@@ -192,6 +190,15 @@ public class SecurityManager
return _logger;
}
+ private static class CachedPropertiesMap extends LinkedHashMap<String, PublishAccessCheck>
+ {
+ @Override
+ protected boolean removeEldestEntry(Entry<String, PublishAccessCheck> eldest)
+ {
+ return size() >= 200;
+ }
+ }
+
private abstract class AccessCheck
{
abstract Result allowed(SecurityPlugin plugin);
@@ -204,56 +211,61 @@ public class SecurityManager
return true;
}
- HashMap<String, SecurityPlugin> remainingPlugins = new HashMap<String, SecurityPlugin>(_globalPlugins);
+ Map<String, SecurityPlugin> remainingPlugins = _globalPlugins.isEmpty()
+ ? Collections.<String, SecurityPlugin>emptyMap()
+ : _hostPlugins.isEmpty() ? _globalPlugins : new HashMap<String, SecurityPlugin>(_globalPlugins);
- for (Entry<String, SecurityPlugin> hostEntry : _hostPlugins.entrySet())
+ if(!_hostPlugins.isEmpty())
{
- // Create set of global only plugins
- SecurityPlugin globalPlugin = remainingPlugins.get(hostEntry.getKey());
- if (globalPlugin != null)
- {
- remainingPlugins.remove(hostEntry.getKey());
- }
-
- Result host = checker.allowed(hostEntry.getValue());
-
- if (host == Result.DENIED)
- {
- // Something vetoed the access, we're done
- return false;
- }
-
- // host allow overrides global allow, so only check global on abstain or defer
- if (host != Result.ALLOWED)
- {
- if (globalPlugin == null)
- {
- if (host == Result.DEFER)
- {
- host = hostEntry.getValue().getDefault();
- }
- if (host == Result.DENIED)
+ for (Entry<String, SecurityPlugin> hostEntry : _hostPlugins.entrySet())
+ {
+ // Create set of global only plugins
+ SecurityPlugin globalPlugin = remainingPlugins.get(hostEntry.getKey());
+ if (globalPlugin != null)
+ {
+ remainingPlugins.remove(hostEntry.getKey());
+ }
+
+ Result host = checker.allowed(hostEntry.getValue());
+
+ if (host == Result.DENIED)
+ {
+ // Something vetoed the access, we're done
+ return false;
+ }
+
+ // host allow overrides global allow, so only check global on abstain or defer
+ if (host != Result.ALLOWED)
+ {
+ if (globalPlugin == null)
{
- return false;
+ if (host == Result.DEFER)
+ {
+ host = hostEntry.getValue().getDefault();
+ }
+ if (host == Result.DENIED)
+ {
+ return false;
+ }
}
- }
- else
- {
- Result global = checker.allowed(globalPlugin);
- if (global == Result.DEFER)
- {
- global = globalPlugin.getDefault();
- }
- if (global == Result.ABSTAIN && host == Result.DEFER)
- {
- global = hostEntry.getValue().getDefault();
- }
- if (global == Result.DENIED)
+ else
{
- return false;
+ Result global = checker.allowed(globalPlugin);
+ if (global == Result.DEFER)
+ {
+ global = globalPlugin.getDefault();
+ }
+ if (global == Result.ABSTAIN && host == Result.DEFER)
+ {
+ global = hostEntry.getValue().getDefault();
+ }
+ if (global == Result.DENIED)
+ {
+ return false;
+ }
}
- }
- }
+ }
+ }
}
for (SecurityPlugin plugin : remainingPlugins.values())
@@ -371,15 +383,41 @@ public class SecurityManager
});
}
- public boolean authorisePublish(final boolean immediate, final String routingKey, final String exchangeName)
+
+ private ConcurrentHashMap<String, ConcurrentHashMap<String, PublishAccessCheck>> _immediatePublishPropsCache
+ = new ConcurrentHashMap<String, ConcurrentHashMap<String, PublishAccessCheck>>();
+ private ConcurrentHashMap<String, ConcurrentHashMap<String, PublishAccessCheck>> _publishPropsCache
+ = new ConcurrentHashMap<String, ConcurrentHashMap<String, PublishAccessCheck>>();
+
+ public boolean authorisePublish(final boolean immediate, String routingKey, String exchangeName)
{
- return checkAllPlugins(new AccessCheck()
+ if(routingKey == null)
{
- Result allowed(SecurityPlugin plugin)
+ routingKey = "";
+ }
+ if(exchangeName == null)
+ {
+ exchangeName = "";
+ }
+ PublishAccessCheck check;
+ ConcurrentHashMap<String, ConcurrentHashMap<String, PublishAccessCheck>> cache =
+ immediate ? _immediatePublishPropsCache : _publishPropsCache;
+
+ ConcurrentHashMap<String, PublishAccessCheck> exchangeMap = cache.get(exchangeName);
+ if(exchangeMap == null)
+ {
+ cache.putIfAbsent(exchangeName, new ConcurrentHashMap<String, PublishAccessCheck>());
+ exchangeMap = cache.get(exchangeName);
+ }
+
+ check = exchangeMap.get(routingKey);
+ if(check == null)
{
- return plugin.authorise(PUBLISH, EXCHANGE, new ObjectProperties(exchangeName, routingKey, immediate));
+ check = new PublishAccessCheck(new ObjectProperties(exchangeName, routingKey, immediate));
+ exchangeMap.put(routingKey, check);
}
- });
+
+ return checkAllPlugins(check);
}
public boolean authorisePurge(final AMQQueue queue)
@@ -413,4 +451,19 @@ public class SecurityManager
return current;
}
+
+ private class PublishAccessCheck extends AccessCheck
+ {
+ private final ObjectProperties _props;
+
+ public PublishAccessCheck(ObjectProperties props)
+ {
+ _props = props;
+ }
+
+ Result allowed(SecurityPlugin plugin)
+ {
+ return plugin.authorise(PUBLISH, EXCHANGE, _props);
+ }
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
index e4bf8df340..8a52d31f97 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
@@ -18,10 +18,7 @@
*/
package org.apache.qpid.server.security.access;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import org.apache.commons.lang.StringUtils;
import org.apache.qpid.framing.AMQShortString;
@@ -35,7 +32,7 @@ import org.apache.qpid.server.queue.AMQQueue;
* {@link #equals(Object)} and {@link #hashCode()} are intended for use in maps. This is due to the wildcard matching
* described above.
*/
-public class ObjectProperties extends HashMap<ObjectProperties.Property, String>
+public class ObjectProperties
{
/** serialVersionUID */
private static final long serialVersionUID = -1356019341374170495L;
@@ -93,7 +90,9 @@ public class ObjectProperties extends HashMap<ObjectProperties.Property, String>
return properties;
}
}
-
+
+ private final EnumMap<Property, String> _properties = new EnumMap<Property, String>(Property.class);
+
public static List<String> getAllPropertyNames()
{
List<String> properties = new ArrayList<String>();
@@ -113,7 +112,7 @@ public class ObjectProperties extends HashMap<ObjectProperties.Property, String>
{
super();
- putAll(copy);
+ _properties.putAll(copy._properties);
}
public ObjectProperties(String name)
@@ -231,7 +230,7 @@ public class ObjectProperties extends HashMap<ObjectProperties.Property, String>
public List<String> getPropertyNames()
{
List<String> properties = new ArrayList<String>();
- for (Property property : keySet())
+ for (Property property : _properties.keySet())
{
properties.add(property.getName());
}
@@ -240,17 +239,22 @@ public class ObjectProperties extends HashMap<ObjectProperties.Property, String>
public Boolean isSet(Property key)
{
- return containsKey(key) && Boolean.valueOf(get(key));
+ return _properties.containsKey(key) && Boolean.valueOf(_properties.get(key));
}
-
+
+ public String get(Property key)
+ {
+ return _properties.get(key);
+ }
+
public String getName()
{
- return get(Property.NAME);
+ return _properties.get(Property.NAME);
}
public void setName(String name)
{
- put(Property.NAME, name);
+ _properties.put(Property.NAME, name);
}
public void setName(AMQShortString name)
@@ -262,39 +266,38 @@ public class ObjectProperties extends HashMap<ObjectProperties.Property, String>
{
return put(key, value == null ? "" : value.asString());
}
-
- @Override
+
public String put(Property key, String value)
{
- return super.put(key, value == null ? "" : value.trim());
+ return _properties.put(key, value == null ? "" : value.trim());
}
public void put(Property key, Boolean value)
{
if (value != null)
{
- super.put(key, Boolean.toString(value));
+ _properties.put(key, Boolean.toString(value));
}
}
public boolean matches(ObjectProperties properties)
{
- if (properties.keySet().isEmpty())
+ if (properties._properties.keySet().isEmpty())
{
return true;
}
- if (!keySet().containsAll(properties.keySet()))
+ if (!_properties.keySet().containsAll(properties._properties.keySet()))
{
return false;
}
- for (Map.Entry<Property,String> entry : properties.entrySet())
+ for (Map.Entry<Property,String> entry : properties._properties.entrySet())
{
Property key = entry.getKey();
String ruleValue = entry.getValue();
- String thisValue = get(key);
+ String thisValue = _properties.get(key);
if (!valueMatches(thisValue, ruleValue))
{
@@ -315,4 +318,29 @@ public class ObjectProperties extends HashMap<ObjectProperties.Property, String>
&& thisValue.length() > ruleValue.length()
&& thisValue.startsWith(ruleValue.substring(0, ruleValue.length() - 2)));
}
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ObjectProperties that = (ObjectProperties) o;
+
+ if (_properties != null ? !_properties.equals(that._properties) : that._properties != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return _properties != null ? _properties.hashCode() : 0;
+ }
+
+ @Override
+ public String toString()
+ {
+ return _properties.toString();
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java
index a883f656be..09e7fe0a11 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java
@@ -21,6 +21,9 @@
package org.apache.qpid.server.store;
import java.nio.ByteBuffer;
+import java.util.Map;
+import java.util.UUID;
+
import org.apache.qpid.framing.FieldTable;
public interface ConfigurationRecoveryHandler
@@ -42,7 +45,19 @@ public interface ConfigurationRecoveryHandler
public static interface BindingRecoveryHandler
{
void binding(String exchangeName, String queueName, String bindingKey, ByteBuffer buf);
- void completeBindingRecovery();
+ BrokerLinkRecoveryHandler completeBindingRecovery();
+ }
+
+ public static interface BrokerLinkRecoveryHandler
+ {
+ BridgeRecoveryHandler brokerLink(UUID id, long createTime, Map<String,String> arguments);
+ void completeBrokerLinkRecovery();
+ }
+
+ public static interface BridgeRecoveryHandler
+ {
+ void bridge(UUID id, long createTime, Map<String,String> arguments);
+ void completeBridgeRecoveryForLink();
}
public static interface QueueEntryRecoveryHandler
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java
index d3f46d2e90..45083c1595 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java
@@ -21,7 +21,9 @@
package org.apache.qpid.server.store;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
+import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.lang.ref.SoftReference;
@@ -36,7 +38,10 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
@@ -47,11 +52,14 @@ import org.apache.qpid.AMQStoreException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.federation.Bridge;
+import org.apache.qpid.server.federation.BrokerLink;
import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.messages.ConfigStoreMessages;
import org.apache.qpid.server.logging.messages.MessageStoreMessages;
import org.apache.qpid.server.logging.messages.TransactionLogMessages;
+import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.queue.AMQQueue;
/**
@@ -60,7 +68,7 @@ import org.apache.qpid.server.queue.AMQQueue;
*
* TODO extract the SQL statements into a generic JDBC store
*/
-public class DerbyMessageStore implements MessageStore
+public class DerbyMessageStore implements MessageStore, DurableConfigurationStore
{
private static final Logger _logger = Logger.getLogger(DerbyMessageStore.class);
@@ -80,6 +88,10 @@ public class DerbyMessageStore implements MessageStore
private static final String META_DATA_TABLE_NAME = "QPID_META_DATA";
private static final String MESSAGE_CONTENT_TABLE_NAME = "QPID_MESSAGE_CONTENT";
+ private static final String LINKS_TABLE_NAME = "QPID_LINKS";
+ private static final String BRIDGES_TABLE_NAME = "QPID_BRIDGES";
+
+
private static final int DB_VERSION = 3;
@@ -135,6 +147,49 @@ public class DerbyMessageStore implements MessageStore
private static final String DELETE_FROM_META_DATA = "DELETE FROM " + META_DATA_TABLE_NAME + " WHERE message_id = ?";
private static final String SELECT_ALL_FROM_META_DATA = "SELECT message_id, meta_data FROM " + META_DATA_TABLE_NAME;
+ private static final String CREATE_LINKS_TABLE =
+ "CREATE TABLE "+LINKS_TABLE_NAME+" ( id_lsb bigint not null,"
+ + " id_msb bigint not null,"
+ + " create_time bigint not null,"
+ + " arguments blob, PRIMARY KEY ( id_lsb, id_msb ))";
+ private static final String SELECT_FROM_LINKS =
+ "SELECT create_time, arguments FROM " + LINKS_TABLE_NAME + " WHERE id_lsb = ? and id_msb";
+ private static final String DELETE_FROM_LINKS = "DELETE FROM " + LINKS_TABLE_NAME
+ + " WHERE id_lsb = ? and id_msb = ?";
+ private static final String SELECT_ALL_FROM_LINKS = "SELECT id_lsb, id_msb, create_time, "
+ + "arguments FROM " + LINKS_TABLE_NAME;
+ private static final String FIND_LINK = "SELECT id_lsb, id_msb FROM " + LINKS_TABLE_NAME + " WHERE id_lsb = ? and"
+ + " id_msb = ?";
+ private static final String INSERT_INTO_LINKS = "INSERT INTO " + LINKS_TABLE_NAME + "( id_lsb, "
+ + "id_msb, create_time, arguments ) values (?, ?, ?, ?)";
+
+
+ private static final String CREATE_BRIDGES_TABLE =
+ "CREATE TABLE "+BRIDGES_TABLE_NAME+" ( id_lsb bigint not null,"
+ + " id_msb bigint not null,"
+ + " create_time bigint not null,"
+ + " link_id_lsb bigint not null,"
+ + " link_id_msb bigint not null,"
+ + " arguments blob, PRIMARY KEY ( id_lsb, id_msb ))";
+ private static final String SELECT_FROM_BRIDGES =
+ "SELECT create_time, link_id_lsb, link_id_msb, arguments FROM "
+ + BRIDGES_TABLE_NAME + " WHERE id_lsb = ? and id_msb = ?";
+ private static final String DELETE_FROM_BRIDGES = "DELETE FROM " + BRIDGES_TABLE_NAME
+ + " WHERE id_lsb = ? and id_msb = ?";
+ private static final String SELECT_ALL_FROM_BRIDGES = "SELECT id_lsb, id_msb, "
+ + " create_time,"
+ + " link_id_lsb, link_id_msb, "
+ + "arguments FROM " + BRIDGES_TABLE_NAME
+ + " WHERE link_id_lsb = ? and link_id_msb = ?";
+ private static final String FIND_BRIDGE = "SELECT id_lsb, id_msb FROM " + BRIDGES_TABLE_NAME +
+ " WHERE id_lsb = ? and id_msb = ?";
+ private static final String INSERT_INTO_BRIDGES = "INSERT INTO " + BRIDGES_TABLE_NAME + "( id_lsb, id_msb, "
+ + "create_time, "
+ + "link_id_lsb, link_id_msb, "
+ + "arguments )"
+ + " values (?, ?, ?, ?, ?, ?)";
+
+
private static final String DERBY_SINGLE_DB_SHUTDOWN_CODE = "08006";
@@ -197,12 +252,16 @@ public class DerbyMessageStore implements MessageStore
Configuration storeConfiguration,
LogSubject logSubject) throws Exception
{
- CurrentActor.get().message(_logSubject, MessageStoreMessages.CREATED(this.getClass().getName()));
-
if(!_configured)
{
_logSubject = logSubject;
+ }
+
+ CurrentActor.get().message(_logSubject, MessageStoreMessages.CREATED(this.getClass().getName()));
+
+ if(!_configured)
+ {
commonConfiguration(name, storeConfiguration, logSubject);
_configured = true;
@@ -219,6 +278,11 @@ public class DerbyMessageStore implements MessageStore
Configuration storeConfiguration,
LogSubject logSubject) throws Exception
{
+
+ if(!_configured)
+ {
+ _logSubject = logSubject;
+ }
CurrentActor.get().message(_logSubject, TransactionLogMessages.CREATED(this.getClass().getName()));
if(!_configured)
@@ -283,6 +347,8 @@ public class DerbyMessageStore implements MessageStore
createQueueEntryTable(conn);
createMetaDataTable(conn);
createMessageContentTable(conn);
+ createLinkTable(conn);
+ createBridgeTable(conn);
conn.close();
}
@@ -419,6 +485,40 @@ public class DerbyMessageStore implements MessageStore
}
+ private void createLinkTable(final Connection conn) throws SQLException
+ {
+ if(!tableExists(LINKS_TABLE_NAME, conn))
+ {
+ Statement stmt = conn.createStatement();
+ try
+ {
+ stmt.execute(CREATE_LINKS_TABLE);
+ }
+ finally
+ {
+ stmt.close();
+ }
+ }
+ }
+
+
+ private void createBridgeTable(final Connection conn) throws SQLException
+ {
+ if(!tableExists(BRIDGES_TABLE_NAME, conn))
+ {
+ Statement stmt = conn.createStatement();
+ try
+ {
+ stmt.execute(CREATE_BRIDGES_TABLE);
+ }
+ finally
+ {
+ stmt.close();
+ }
+ }
+ }
+
+
private boolean tableExists(final String tableName, final Connection conn) throws SQLException
@@ -459,7 +559,8 @@ public class DerbyMessageStore implements MessageStore
List<String> exchanges = loadExchanges(erh);
ConfigurationRecoveryHandler.BindingRecoveryHandler brh = erh.completeExchangeRecovery();
recoverBindings(brh, exchanges);
- brh.completeBindingRecovery();
+ ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler lrh = brh.completeBindingRecovery();
+ recoverBrokerLinks(lrh);
}
catch (SQLException e)
{
@@ -470,6 +571,144 @@ public class DerbyMessageStore implements MessageStore
}
+ private void recoverBrokerLinks(final ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler lrh)
+ throws SQLException
+ {
+ _logger.info("Recovering broker links...");
+
+ Connection conn = null;
+ try
+ {
+ conn = newAutoCommitConnection();
+
+ PreparedStatement stmt = conn.prepareStatement(SELECT_ALL_FROM_LINKS);
+
+ try
+ {
+ ResultSet rs = stmt.executeQuery();
+
+ try
+ {
+
+ while(rs.next())
+ {
+ UUID id = new UUID(rs.getLong(2), rs.getLong(1));
+ long createTime = rs.getLong(3);
+ Blob argumentsAsBlob = rs.getBlob(4);
+
+ byte[] dataAsBytes = argumentsAsBlob.getBytes(1,(int) argumentsAsBlob.length());
+
+ DataInputStream dis = new DataInputStream(new ByteArrayInputStream(dataAsBytes));
+ int size = dis.readInt();
+
+ Map<String,String> arguments = new HashMap<String, String>();
+
+ for(int i = 0; i < size; i++)
+ {
+ arguments.put(dis.readUTF(), dis.readUTF());
+ }
+
+ ConfigurationRecoveryHandler.BridgeRecoveryHandler brh = lrh.brokerLink(id, createTime, arguments);
+
+ recoverBridges(brh, id);
+
+ }
+ }
+ catch (IOException e)
+ {
+ throw new SQLException(e.getMessage(), e);
+ }
+ finally
+ {
+ rs.close();
+ }
+ }
+ finally
+ {
+ stmt.close();
+ }
+
+ }
+ finally
+ {
+ if(conn != null)
+ {
+ conn.close();
+ }
+ }
+
+ }
+
+ private void recoverBridges(final ConfigurationRecoveryHandler.BridgeRecoveryHandler brh, final UUID linkId)
+ throws SQLException
+ {
+ _logger.info("Recovering bridges for link " + linkId + "...");
+
+ Connection conn = null;
+ try
+ {
+ conn = newAutoCommitConnection();
+
+ PreparedStatement stmt = conn.prepareStatement(SELECT_ALL_FROM_BRIDGES);
+ stmt.setLong(1, linkId.getLeastSignificantBits());
+ stmt.setLong(2, linkId.getMostSignificantBits());
+
+
+ try
+ {
+ ResultSet rs = stmt.executeQuery();
+
+ try
+ {
+
+ while(rs.next())
+ {
+ UUID id = new UUID(rs.getLong(2), rs.getLong(1));
+ long createTime = rs.getLong(3);
+ Blob argumentsAsBlob = rs.getBlob(6);
+
+ byte[] dataAsBytes = argumentsAsBlob.getBytes(1,(int) argumentsAsBlob.length());
+
+ DataInputStream dis = new DataInputStream(new ByteArrayInputStream(dataAsBytes));
+ int size = dis.readInt();
+
+ Map<String,String> arguments = new HashMap<String, String>();
+
+ for(int i = 0; i < size; i++)
+ {
+ arguments.put(dis.readUTF(), dis.readUTF());
+ }
+
+ brh.bridge(id, createTime, arguments);
+
+ }
+ brh.completeBridgeRecoveryForLink();
+ }
+ catch (IOException e)
+ {
+ throw new SQLException(e.getMessage(), e);
+ }
+ finally
+ {
+ rs.close();
+ }
+ }
+ finally
+ {
+ stmt.close();
+ }
+
+ }
+ finally
+ {
+ if(conn != null)
+ {
+ conn.close();
+ }
+ }
+
+ }
+
private void loadQueues(ConfigurationRecoveryHandler.QueueRecoveryHandler qrh) throws SQLException
{
Connection conn = newAutoCommitConnection();
@@ -697,7 +936,7 @@ public class DerbyMessageStore implements MessageStore
if (results == 0)
{
- throw new RuntimeException("Message metadata not found for message id " + messageId);
+ _logger.warn("Message metadata not found for message id " + messageId);
}
if (_logger.isDebugEnabled())
@@ -1180,6 +1419,233 @@ public class DerbyMessageStore implements MessageStore
}
+ public void createBrokerLink(final BrokerLink link) throws AMQStoreException
+ {
+ _logger.debug("public void createBrokerLink(BrokerLink = " + link + "): called");
+
+ if (_state != State.RECOVERING)
+ {
+ try
+ {
+ Connection conn = newAutoCommitConnection();
+
+ PreparedStatement stmt = conn.prepareStatement(FIND_LINK);
+ try
+ {
+
+ stmt.setLong(1, link.getId().getLeastSignificantBits());
+ stmt.setLong(2, link.getId().getMostSignificantBits());
+ ResultSet rs = stmt.executeQuery();
+ try
+ {
+
+ // If we don't have any data in the result set then we can add this queue
+ if (!rs.next())
+ {
+ PreparedStatement insertStmt = conn.prepareStatement(INSERT_INTO_LINKS);
+
+ try
+ {
+
+ insertStmt.setLong(1, link.getId().getLeastSignificantBits());
+ insertStmt.setLong(2, link.getId().getMostSignificantBits());
+ insertStmt.setLong(3, link.getCreateTime());
+
+ byte[] argumentBytes = convertStringMapToBytes(link.getArguments());
+ ByteArrayInputStream bis = new ByteArrayInputStream(argumentBytes);
+
+ insertStmt.setBinaryStream(4,bis,argumentBytes.length);
+
+ insertStmt.execute();
+ }
+ finally
+ {
+ insertStmt.close();
+ }
+ }
+ }
+ finally
+ {
+ rs.close();
+ }
+ }
+ finally
+ {
+ stmt.close();
+ }
+ conn.close();
+
+ }
+ catch (SQLException e)
+ {
+ throw new AMQStoreException("Error writing " + link + " to database: " + e.getMessage(), e);
+ }
+ }
+ }
+
+ private byte[] convertStringMapToBytes(final Map<String, String> arguments) throws AMQStoreException
+ {
+ byte[] argumentBytes;
+ if(arguments == null)
+ {
+ argumentBytes = new byte[0];
+ }
+ else
+ {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ DataOutputStream dos = new DataOutputStream(bos);
+
+
+ try
+ {
+ dos.writeInt(arguments.size());
+ for(Map.Entry<String,String> arg : arguments.entrySet())
+ {
+ dos.writeUTF(arg.getKey());
+ dos.writeUTF(arg.getValue());
+ }
+ }
+ catch (IOException e)
+ {
+ // This should never happen
+ throw new AMQStoreException(e.getMessage(), e);
+ }
+ argumentBytes = bos.toByteArray();
+ }
+ return argumentBytes;
+ }
+
+ public void deleteBrokerLink(final BrokerLink link) throws AMQStoreException
+ {
+ _logger.debug("public void deleteBrokerLink( " + link + "): called");
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ try
+ {
+ conn = newAutoCommitConnection();
+ stmt = conn.prepareStatement(DELETE_FROM_LINKS);
+ stmt.setLong(1, link.getId().getLeastSignificantBits());
+ stmt.setLong(2, link.getId().getMostSignificantBits());
+ int results = stmt.executeUpdate();
+
+ if (results == 0)
+ {
+ throw new AMQStoreException("Link " + link + " not found");
+ }
+ }
+ catch (SQLException e)
+ {
+ throw new AMQStoreException("Error deleting Link " + link + " from database: " + e.getMessage(), e);
+ }
+ finally
+ {
+ closePreparedStatement(stmt);
+ closeConnection(conn);
+ }
+
+
+ }
+
+ public void createBridge(final Bridge bridge) throws AMQStoreException
+ {
+ _logger.debug("public void createBridge(BrokerLink = " + bridge + "): called");
+
+ if (_state != State.RECOVERING)
+ {
+ try
+ {
+ Connection conn = newAutoCommitConnection();
+
+ PreparedStatement stmt = conn.prepareStatement(FIND_BRIDGE);
+ try
+ {
+
+ UUID id = bridge.getId();
+ stmt.setLong(1, id.getLeastSignificantBits());
+ stmt.setLong(2, id.getMostSignificantBits());
+ ResultSet rs = stmt.executeQuery();
+ try
+ {
+
+ // If we don't have any data in the result set then we can add this queue
+ if (!rs.next())
+ {
+ PreparedStatement insertStmt = conn.prepareStatement(INSERT_INTO_BRIDGES);
+
+ try
+ {
+
+ insertStmt.setLong(1, id.getLeastSignificantBits());
+ insertStmt.setLong(2, id.getMostSignificantBits());
+
+ insertStmt.setLong(3, bridge.getCreateTime());
+
+ UUID linkId = bridge.getLink().getId();
+ insertStmt.setLong(4, linkId.getLeastSignificantBits());
+ insertStmt.setLong(5, linkId.getMostSignificantBits());
+
+ byte[] argumentBytes = convertStringMapToBytes(bridge.getArguments());
+ ByteArrayInputStream bis = new ByteArrayInputStream(argumentBytes);
+
+ insertStmt.setBinaryStream(6,bis,argumentBytes.length);
+
+ insertStmt.execute();
+ }
+ finally
+ {
+ insertStmt.close();
+ }
+ }
+ }
+ finally
+ {
+ rs.close();
+ }
+ }
+ finally
+ {
+ stmt.close();
+ }
+ conn.close();
+
+ }
+ catch (SQLException e)
+ {
+ throw new AMQStoreException("Error writing " + bridge + " to database: " + e.getMessage(), e);
+ }
+ }
+ }
+
+ public void deleteBridge(final Bridge bridge) throws AMQStoreException
+ {
+ _logger.debug("public void deleteBridge( " + bridge + "): called");
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ try
+ {
+ conn = newAutoCommitConnection();
+ stmt = conn.prepareStatement(DELETE_FROM_BRIDGES);
+ stmt.setLong(1, bridge.getId().getLeastSignificantBits());
+ stmt.setLong(2, bridge.getId().getMostSignificantBits());
+ int results = stmt.executeUpdate();
+
+ if (results == 0)
+ {
+ throw new AMQStoreException("Bridge " + bridge + " not found");
+ }
+ }
+ catch (SQLException e)
+ {
+ throw new AMQStoreException("Error deleting bridge " + bridge + " from database: " + e.getMessage(), e);
+ }
+ finally
+ {
+ closePreparedStatement(stmt);
+ closeConnection(conn);
+ }
+
+ }
+
public Transaction newTransaction()
{
return new DerbyTransaction();
@@ -1678,14 +2144,26 @@ public class DerbyMessageStore implements MessageStore
}
}
- public void enqueueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException
+ public void enqueueMessage(TransactionLogResource queue, EnqueableMessage message) throws AMQStoreException
{
- DerbyMessageStore.this.enqueueMessage(_connWrapper, queue, messageId);
+ if(message.getStoredMessage() instanceof StoredDerbyMessage)
+ {
+ try
+ {
+ ((StoredDerbyMessage)message.getStoredMessage()).store(_connWrapper.getConnection());
+ }
+ catch (SQLException e)
+ {
+ throw new AMQStoreException("Exception on enqueuing message " + _messageId, e);
+ }
+ }
+
+ DerbyMessageStore.this.enqueueMessage(_connWrapper, queue, message.getMessageNumber());
}
- public void dequeueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException
+ public void dequeueMessage(TransactionLogResource queue, EnqueableMessage message) throws AMQStoreException
{
- DerbyMessageStore.this.dequeueMessage(_connWrapper, queue, messageId);
+ DerbyMessageStore.this.dequeueMessage(_connWrapper, queue, message.getMessageNumber());
}
@@ -1709,8 +2187,11 @@ public class DerbyMessageStore implements MessageStore
{
private final long _messageId;
+ private StorableMessageMetaData _metaData;
private volatile SoftReference<StorableMessageMetaData> _metaDataRef;
- private Connection _conn;
+ private byte[] _data;
+ private volatile SoftReference<byte[]> _dataRef;
+
StoredDerbyMessage(long messageId, StorableMessageMetaData metaData)
{
@@ -1721,27 +2202,19 @@ public class DerbyMessageStore implements MessageStore
StoredDerbyMessage(long messageId,
StorableMessageMetaData metaData, boolean persist)
{
- try
- {
- _messageId = messageId;
+ _messageId = messageId;
+
- _metaDataRef = new SoftReference<StorableMessageMetaData>(metaData);
- if(persist)
- {
- _conn = newConnection();
- storeMetaData(_conn, messageId, metaData);
- }
- }
- catch (SQLException e)
+ _metaDataRef = new SoftReference<StorableMessageMetaData>(metaData);
+ if(persist)
{
- throw new RuntimeException(e);
+ _metaData = metaData;
}
-
}
public StorableMessageMetaData getMetaData()
{
- StorableMessageMetaData metaData = _metaDataRef.get();
+ StorableMessageMetaData metaData = _metaData == null ? _metaDataRef.get() : _metaData;
if(metaData == null)
{
try
@@ -1765,27 +2238,62 @@ public class DerbyMessageStore implements MessageStore
public void addContent(int offsetInMessage, java.nio.ByteBuffer src)
{
- DerbyMessageStore.this.addContent(_conn, _messageId, offsetInMessage, src);
+ src = src.slice();
+
+ if(_data == null)
+ {
+ _data = new byte[src.remaining()];
+ _dataRef = new SoftReference<byte[]>(_data);
+ src.duplicate().get(_data);
+ }
+ else
+ {
+ byte[] oldData = _data;
+ _data = new byte[oldData.length + src.remaining()];
+ _dataRef = new SoftReference<byte[]>(_data);
+
+ System.arraycopy(oldData,0,_data,0,oldData.length);
+ src.duplicate().get(_data, oldData.length, src.remaining());
+ }
+
}
public int getContent(int offsetInMessage, java.nio.ByteBuffer dst)
{
- return DerbyMessageStore.this.getContent(_messageId, offsetInMessage, dst);
+ byte[] data = _dataRef == null ? null : _dataRef.get();
+ if(data != null)
+ {
+ int length = Math.min(dst.remaining(), data.length - offsetInMessage);
+ dst.put(data, offsetInMessage, length);
+ return length;
+ }
+ else
+ {
+ return DerbyMessageStore.this.getContent(_messageId, offsetInMessage, dst);
+ }
+ }
+
+
+ public ByteBuffer getContent(int offsetInMessage, int size)
+ {
+ ByteBuffer buf = ByteBuffer.allocate(size);
+ getContent(offsetInMessage, buf);
+ buf.position(0);
+ return buf;
}
- public StoreFuture flushToStore()
+ public synchronized StoreFuture flushToStore()
{
try
{
- if(_conn != null)
+ if(_metaData != null)
{
- if(_logger.isDebugEnabled())
- {
- _logger.debug("Flushing message " + _messageId + " to store");
- }
+ Connection conn = newConnection();
+
+ store(conn);
- _conn.commit();
- _conn.close();
+ conn.commit();
+ conn.close();
}
}
catch (SQLException e)
@@ -1796,16 +2304,34 @@ public class DerbyMessageStore implements MessageStore
}
throw new RuntimeException(e);
}
- finally
+ return IMMEDIATE_FUTURE;
+ }
+
+ private synchronized void store(final Connection conn) throws SQLException
+ {
+ if(_metaData != null)
{
- _conn = null;
+ try
+ {
+ storeMetaData(conn, _messageId, _metaData);
+ DerbyMessageStore.this.addContent(conn, _messageId, 0,
+ _data == null ? ByteBuffer.allocate(0) : ByteBuffer.wrap(_data));
+ }
+ finally
+ {
+ _metaData = null;
+ _data = null;
+ }
+ }
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Storing message " + _messageId + " to store");
}
- return IMMEDIATE_FUTURE;
}
public void remove()
{
- flushToStore();
DerbyMessageStore.this.removeMessage(_messageId);
}
}
@@ -1839,4 +2365,5 @@ public class DerbyMessageStore implements MessageStore
}
}
}
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java
index 5fb23653cb..9cd2567b7d 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java
@@ -25,6 +25,8 @@ import org.apache.qpid.AMQStoreException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.federation.Bridge;
+import org.apache.qpid.server.federation.BrokerLink;
import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.queue.AMQQueue;
@@ -128,4 +130,12 @@ public interface DurableConfigurationStore
* @throws AMQStoreException If the operation fails for any reason.
*/
void updateQueue(AMQQueue queue) throws AMQStoreException;
+
+ void createBrokerLink(BrokerLink link) throws AMQStoreException;
+
+ void deleteBrokerLink(BrokerLink link) throws AMQStoreException;
+
+ void createBridge(Bridge bridge) throws AMQStoreException;
+
+ void deleteBridge(Bridge bridge) throws AMQStoreException;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java
index d008d42fa0..c5393f73a2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java
@@ -31,14 +31,18 @@ import org.apache.qpid.AMQStoreException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.federation.Bridge;
+import org.apache.qpid.server.federation.BrokerLink;
import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.messages.ConfigStoreMessages;
import org.apache.qpid.server.logging.messages.MessageStoreMessages;
+import org.apache.qpid.server.message.EnqueableMessage;
+import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.queue.AMQQueue;
/** A simple message store that stores the messages in a threadsafe structure in memory. */
-public class MemoryMessageStore implements MessageStore
+public class MemoryMessageStore implements MessageStore, DurableConfigurationStore
{
private static final Logger _log = Logger.getLogger(MemoryMessageStore.class);
@@ -53,11 +57,11 @@ public class MemoryMessageStore implements MessageStore
private static final Transaction IN_MEMORY_TRANSACTION = new Transaction()
{
- public void enqueueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException
+ public void enqueueMessage(TransactionLogResource queue, EnqueableMessage message) throws AMQStoreException
{
}
- public void dequeueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException
+ public void dequeueMessage(TransactionLogResource queue, EnqueableMessage message) throws AMQStoreException
{
}
@@ -155,6 +159,26 @@ public class MemoryMessageStore implements MessageStore
// Not required to do anything
}
+ public void createBrokerLink(final BrokerLink link) throws AMQStoreException
+ {
+
+ }
+
+ public void deleteBrokerLink(final BrokerLink link) throws AMQStoreException
+ {
+
+ }
+
+ public void createBridge(final Bridge bridge) throws AMQStoreException
+ {
+
+ }
+
+ public void deleteBridge(final Bridge bridge) throws AMQStoreException
+ {
+
+ }
+
public void configureTransactionLog(String name,
TransactionLogRecoveryHandler recoveryHandler,
Configuration storeConfiguration,
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java
index e2fca2f9c7..88c95ad65e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java
@@ -20,14 +20,16 @@
*/
package org.apache.qpid.server.store;
+import org.apache.qpid.AMQStoreException;
import org.apache.qpid.server.logging.LogSubject;
import org.apache.commons.configuration.Configuration;
+import org.apache.qpid.server.message.EnqueableMessage;
/**
* MessageStore defines the interface to a storage area, which can be used to preserve the state of messages.
*
*/
-public interface MessageStore extends DurableConfigurationStore, TransactionLog
+public interface MessageStore
{
StoreFuture IMMEDIATE_FUTURE = new StoreFuture()
{
@@ -77,4 +79,69 @@ public interface MessageStore extends DurableConfigurationStore, TransactionLog
boolean isPersistent();
+
+ public static interface Transaction
+ {
+ /**
+ * Places a message onto a specified queue, in a given transactional context.
+ *
+ *
+ *
+ * @param queue The queue to place the message on.
+ * @param message
+ * @throws org.apache.qpid.AMQStoreException If the operation fails for any reason.
+ */
+ void enqueueMessage(TransactionLogResource queue, EnqueableMessage message) throws AMQStoreException;
+
+ /**
+ * Extracts a message from a specified queue, in a given transactional context.
+ *
+ * @param queue The queue to place the message on.
+ * @param message The message to dequeue.
+ * @throws AMQStoreException If the operation fails for any reason, or if the specified message does not exist.
+ */
+ void dequeueMessage(TransactionLogResource queue, EnqueableMessage message) throws AMQStoreException;
+
+
+ /**
+ * Commits all operations performed within a given transactional context.
+ *
+ * @throws AMQStoreException If the operation fails for any reason.
+ */
+ void commitTran() throws AMQStoreException;
+
+ /**
+ * Commits all operations performed within a given transactional context.
+ *
+ * @throws AMQStoreException If the operation fails for any reason.
+ */
+ StoreFuture commitTranAsync() throws AMQStoreException;
+
+ /**
+ * Abandons all operations performed within a given transactional context.
+ *
+ * @throws AMQStoreException If the operation fails for any reason.
+ */
+ void abortTran() throws AMQStoreException;
+
+
+
+ }
+
+ public void configureTransactionLog(String name,
+ TransactionLogRecoveryHandler recoveryHandler,
+ Configuration storeConfiguration,
+ LogSubject logSubject) throws Exception;
+
+ Transaction newTransaction();
+
+
+
+ public static interface StoreFuture
+ {
+ boolean isComplete();
+
+ void waitForCompletion();
+ }
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/StorableMessageMetaData.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/StorableMessageMetaData.java
index 2381301c30..12d2a6a6c7 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/StorableMessageMetaData.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/StorableMessageMetaData.java
@@ -30,5 +30,7 @@ public interface StorableMessageMetaData
int writeToBuffer(int offsetInMetaData, ByteBuffer dest);
+ int getContentSize();
+
boolean isPersistent();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/StoredMemoryMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/StoredMemoryMessage.java
index fba4745523..144cc629bd 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/StoredMemoryMessage.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/StoredMemoryMessage.java
@@ -42,36 +42,87 @@ public class StoredMemoryMessage implements StoredMessage
public void addContent(int offsetInMessage, ByteBuffer src)
{
- src = src.duplicate();
- if(_content == null || offsetInMessage + src.remaining() > _content.capacity())
+ if(_content == null)
{
- ByteBuffer newContent = ByteBuffer.allocate(offsetInMessage+src.remaining());
- if(_content != null)
+ if(offsetInMessage == 0)
{
- newContent.duplicate().put(_content.array());
+ _content = src.slice();
+ }
+ else
+ {
+ final int contentSize = _metaData.getContentSize();
+ int size = (contentSize < offsetInMessage + src.remaining())
+ ? offsetInMessage + src.remaining()
+ : contentSize;
+ _content = ByteBuffer.allocate(size);
+ addContent(offsetInMessage, src);
}
- _content = newContent;
}
+ else
+ {
+ if(_content.limit() >= offsetInMessage + src.remaining())
+ {
+ _content.position(offsetInMessage);
+ _content.put(src);
+ _content.position(0);
+ }
+ else
+ {
+ final int contentSize = _metaData.getContentSize();
+ int size = (contentSize < offsetInMessage + src.remaining())
+ ? offsetInMessage + src.remaining()
+ : contentSize;
+ ByteBuffer oldContent = _content;
+ _content = ByteBuffer.allocate(size);
+ _content.put(oldContent);
+ _content.position(0);
+ addContent(offsetInMessage, src);
+ }
- ByteBuffer dst = _content.duplicate();
- dst.position(offsetInMessage);
- dst.put(src);
+ }
}
public int getContent(int offset, ByteBuffer dst)
{
- ByteBuffer src = _content.duplicate();
- src.position(offset);
- src = src.slice();
- if(dst.remaining() < src.limit())
+ if(_content == null)
{
- src.limit(dst.remaining());
+ return 0;
}
+ ByteBuffer src = _content.duplicate();
+
+ int oldPosition = src.position();
+
+ src.position(oldPosition + offset);
+
+ int length = dst.remaining() < src.remaining() ? dst.remaining() : src.remaining();
+ src.limit(oldPosition + length);
+
dst.put(src);
- return src.limit();
+
+
+ return length;
+ }
+
+
+ public ByteBuffer getContent(int offsetInMessage, int size)
+ {
+ if(_content == null)
+ {
+ return null;
+ }
+ ByteBuffer buf = _content.duplicate();
+
+ if(offsetInMessage != 0)
+ {
+ buf.position(offsetInMessage);
+ buf = buf.slice();
+ }
+
+ buf.limit(size);
+ return buf;
}
- public TransactionLog.StoreFuture flushToStore()
+ public MessageStore.StoreFuture flushToStore()
{
return MessageStore.IMMEDIATE_FUTURE;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/StoredMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/StoredMessage.java
index 0bc45c6718..d4a0381929 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/StoredMessage.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/StoredMessage.java
@@ -32,7 +32,9 @@ public interface StoredMessage<M extends StorableMessageMetaData>
int getContent(int offsetInMessage, ByteBuffer dst);
- TransactionLog.StoreFuture flushToStore();
+ ByteBuffer getContent(int offsetInMessage, int size);
+
+ MessageStore.StoreFuture flushToStore();
void remove();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/TransactionLog.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/TransactionLog.java
index d196a91930..da7f8d18b2 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/TransactionLog.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/TransactionLog.java
@@ -20,72 +20,7 @@
*/
package org.apache.qpid.server.store;
-import org.apache.qpid.server.logging.LogSubject;
-import org.apache.qpid.AMQStoreException;
-import org.apache.commons.configuration.Configuration;
-
public interface TransactionLog
{
- public static interface Transaction
- {
- /**
- * Places a message onto a specified queue, in a given transactional context.
- *
- * @param queue The queue to place the message on.
- * @param messageId The message to enqueue.
- * @throws AMQStoreException If the operation fails for any reason.
- */
- void enqueueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException;
-
- /**
- * Extracts a message from a specified queue, in a given transactional context.
- *
- * @param queue The queue to place the message on.
- * @param messageId The message to dequeue.
- * @throws AMQStoreException If the operation fails for any reason, or if the specified message does not exist.
- */
- void dequeueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException;
-
-
- /**
- * Commits all operations performed within a given transactional context.
- *
- * @throws AMQStoreException If the operation fails for any reason.
- */
- void commitTran() throws AMQStoreException;
-
- /**
- * Commits all operations performed within a given transactional context.
- *
- * @throws AMQStoreException If the operation fails for any reason.
- */
- StoreFuture commitTranAsync() throws AMQStoreException;
-
- /**
- * Abandons all operations performed within a given transactional context.
- *
- * @throws AMQStoreException If the operation fails for any reason.
- */
- void abortTran() throws AMQStoreException;
-
-
-
- }
-
- public void configureTransactionLog(String name,
- TransactionLogRecoveryHandler recoveryHandler,
- Configuration storeConfiguration,
- LogSubject logSubject) throws Exception;
-
- Transaction newTransaction();
-
-
-
- public static interface StoreFuture
- {
- boolean isComplete();
-
- void waitForCompletion();
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/TransactionLogRecoveryHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/TransactionLogRecoveryHandler.java
index 7781c52df3..802596ed1e 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/TransactionLogRecoveryHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/TransactionLogRecoveryHandler.java
@@ -22,7 +22,7 @@ package org.apache.qpid.server.store;
public interface TransactionLogRecoveryHandler
{
- QueueEntryRecoveryHandler begin(TransactionLog log);
+ QueueEntryRecoveryHandler begin(MessageStore log);
public static interface QueueEntryRecoveryHandler
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java
new file mode 100644
index 0000000000..f511cc0dc9
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java
@@ -0,0 +1,150 @@
+/*
+ *
+ * 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.subscription;
+
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.QueueEntry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+public class AssignedSubscriptionMessageGroupManager implements MessageGroupManager
+{
+ private static final Logger _logger = LoggerFactory.getLogger(AssignedSubscriptionMessageGroupManager.class);
+
+
+ private final String _groupId;
+ private final ConcurrentHashMap<Integer, Subscription> _groupMap = new ConcurrentHashMap<Integer, Subscription>();
+ private final int _groupMask;
+
+ public AssignedSubscriptionMessageGroupManager(final String groupId, final int maxGroups)
+ {
+ _groupId = groupId;
+ _groupMask = pow2(maxGroups)-1;
+ }
+
+ private static int pow2(final int i)
+ {
+ int val = 1;
+ while(val < i) val<<=1;
+ return val;
+ }
+
+ public Subscription getAssignedSubscription(final QueueEntry entry)
+ {
+ Object groupVal = entry.getMessage().getMessageHeader().getHeader(_groupId);
+ return groupVal == null ? null : _groupMap.get(groupVal.hashCode() & _groupMask);
+ }
+
+ public boolean acceptMessage(Subscription sub, QueueEntry entry)
+ {
+ Object groupVal = entry.getMessage().getMessageHeader().getHeader(_groupId);
+ if(groupVal == null)
+ {
+ return true;
+ }
+ else
+ {
+ Integer group = groupVal.hashCode() & _groupMask;
+ Subscription assignedSub = _groupMap.get(group);
+ if(assignedSub == sub)
+ {
+ return true;
+ }
+ else
+ {
+ if(assignedSub == null)
+ {
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Assigning group " + groupVal + " to sub " + sub);
+ }
+ assignedSub = _groupMap.putIfAbsent(group, sub);
+ return assignedSub == null || assignedSub == sub;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+ }
+
+ public QueueEntry findEarliestAssignedAvailableEntry(Subscription sub)
+ {
+ EntryFinder visitor = new EntryFinder(sub);
+ sub.getQueue().visit(visitor);
+ return visitor.getEntry();
+ }
+
+ private class EntryFinder implements AMQQueue.Visitor
+ {
+ private QueueEntry _entry;
+ private Subscription _sub;
+
+ public EntryFinder(final Subscription sub)
+ {
+ _sub = sub;
+ }
+
+ public boolean visit(final QueueEntry entry)
+ {
+ if(!entry.isAvailable())
+ return false;
+
+ Object groupId = entry.getMessage().getMessageHeader().getHeader(_groupId);
+ if(groupId == null)
+ return false;
+
+ Integer group = groupId.hashCode() & _groupMask;
+ Subscription assignedSub = _groupMap.get(group);
+ if(assignedSub == _sub)
+ {
+ _entry = entry;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public QueueEntry getEntry()
+ {
+ return _entry;
+ }
+ }
+
+ public void clearAssignments(Subscription sub)
+ {
+ Iterator<Subscription> subIter = _groupMap.values().iterator();
+ while(subIter.hasNext())
+ {
+ if(subIter.next() == sub)
+ {
+ subIter.remove();
+ }
+ }
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java
new file mode 100644
index 0000000000..42818db214
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java
@@ -0,0 +1,270 @@
+/*
+ *
+ * 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.subscription;
+
+import org.apache.qpid.server.message.AMQMessageHeader;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.QueueEntry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class DefinedGroupMessageGroupManager implements MessageGroupManager
+{
+ private static final Logger _logger = LoggerFactory.getLogger(DefinedGroupMessageGroupManager.class);
+
+ private final String _groupId;
+ private final String _defaultGroup;
+ private final Map<Object, Group> _groupMap = new HashMap<Object, Group>();
+ private final SubscriptionResetHelper _resetHelper;
+
+ private final class Group
+ {
+ private final Object _group;
+ private Subscription _subscription;
+ private int _activeCount;
+
+ private Group(final Object key, final Subscription subscription)
+ {
+ _group = key;
+ _subscription = subscription;
+ }
+
+ public boolean add()
+ {
+ if(_subscription != null)
+ {
+ _activeCount++;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public void subtract()
+ {
+ if(--_activeCount == 0)
+ {
+ _resetHelper.resetSubPointersForGroups(_subscription, false);
+ _subscription = null;
+ _groupMap.remove(_group);
+ }
+ }
+
+ @Override
+ public boolean equals(final Object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass())
+ {
+ return false;
+ }
+
+ Group group = (Group) o;
+
+ return _group.equals(group._group);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return _group.hashCode();
+ }
+
+ public boolean isValid()
+ {
+ return !(_subscription == null || (_activeCount == 0 && _subscription.isClosed()));
+ }
+
+ public Subscription getSubscription()
+ {
+ return _subscription;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "Group{" +
+ "_group=" + _group +
+ ", _subscription=" + _subscription +
+ ", _activeCount=" + _activeCount +
+ '}';
+ }
+ }
+
+ public DefinedGroupMessageGroupManager(final String groupId, String defaultGroup, SubscriptionResetHelper resetHelper)
+ {
+ _groupId = groupId;
+ _defaultGroup = defaultGroup;
+ _resetHelper = resetHelper;
+ }
+
+ public synchronized Subscription getAssignedSubscription(final QueueEntry entry)
+ {
+ Object groupId = getKey(entry);
+
+ Group group = _groupMap.get(groupId);
+ return group == null || !group.isValid() ? null : group.getSubscription();
+ }
+
+ public synchronized boolean acceptMessage(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);
+
+ _groupMap.put(groupId, group);
+
+ // there's a small change that the group became empty between the point at which getNextAvailable() was
+ // called on the subscription, and when accept message is called... in that case we want to avoid delivering
+ // out of order
+ if(_resetHelper.isEntryAheadOfSubscription(entry, sub))
+ {
+ return false;
+ }
+
+ }
+
+ Subscription assignedSub = group.getSubscription();
+
+ if(assignedSub == sub)
+ {
+ entry.addStateChangeListener(new GroupStateChangeListener(group, entry));
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+ public synchronized QueueEntry findEarliestAssignedAvailableEntry(final Subscription sub)
+ {
+ EntryFinder visitor = new EntryFinder(sub);
+ sub.getQueue().visit(visitor);
+ _logger.debug("Earliest available entry for " + sub + " is " + visitor.getEntry() + (visitor.getEntry() == null ? "" : " : " + getKey(visitor.getEntry())));
+ return visitor.getEntry();
+ }
+
+ private class EntryFinder implements AMQQueue.Visitor
+ {
+ private QueueEntry _entry;
+ private Subscription _sub;
+
+ public EntryFinder(final Subscription sub)
+ {
+ _sub = sub;
+ }
+
+ public boolean visit(final QueueEntry entry)
+ {
+ if(!entry.isAvailable())
+ return false;
+
+ Object groupId = getKey(entry);
+
+ Group group = _groupMap.get(groupId);
+ if(group != null && group.getSubscription() == _sub)
+ {
+ _entry = entry;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public QueueEntry getEntry()
+ {
+ return _entry;
+ }
+ }
+
+
+ public void clearAssignments(final Subscription sub)
+ {
+ }
+
+ private Object getKey(QueueEntry entry)
+ {
+ ServerMessage message = entry.getMessage();
+ AMQMessageHeader messageHeader = message == null ? null : message.getMessageHeader();
+ Object groupVal = messageHeader == null ? _defaultGroup : messageHeader.getHeader(_groupId);
+ if(groupVal == null)
+ {
+ groupVal = _defaultGroup;
+ }
+ return groupVal;
+ }
+
+ private class GroupStateChangeListener implements QueueEntry.StateChangeListener
+ {
+ private final Group _group;
+
+ public GroupStateChangeListener(final Group group,
+ final QueueEntry entry)
+ {
+ _group = group;
+ }
+
+ public void stateChanged(final QueueEntry entry,
+ final QueueEntry.State oldState,
+ final QueueEntry.State newState)
+ {
+ synchronized (DefinedGroupMessageGroupManager.this)
+ {
+ if(_group.isValid())
+ {
+ if(oldState != newState)
+ {
+ if(newState == QueueEntry.State.ACQUIRED)
+ {
+ _logger.debug("Adding to " + _group);
+ _group.add();
+ }
+ else if(oldState == QueueEntry.State.ACQUIRED)
+ {
+ _logger.debug("Subtracting from " + _group);
+ _group.subtract();
+ }
+ }
+ }
+ else
+ {
+ entry.removeStateChangeListener(this);
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/filter/Expression.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/MessageGroupManager.java
index 8208f49688..8ce4ce3344 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/filter/Expression.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/MessageGroupManager.java
@@ -1,35 +1,41 @@
-/* Licensed to the Apache Software Foundation (ASF) under one
+/*
+ *
+ * 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.filter;
+package org.apache.qpid.server.subscription;
-import org.apache.qpid.AMQInternalException;
-import org.apache.qpid.client.message.AbstractJMSMessage;
+import org.apache.qpid.server.queue.QueueEntry;
-
-/**
- * Represents an expression
- */
-public interface Expression
+public interface MessageGroupManager
{
- /**
- * @param message The message to evaluate
- * @return the value of this expression
- * @throws AMQInternalException
- */
- public Object evaluate(AbstractJMSMessage message) throws AMQInternalException;
+ public interface SubscriptionResetHelper
+ {
+ public void resetSubPointersForGroups(Subscription subscription, boolean clearAssignments);
+
+ boolean isEntryAheadOfSubscription(QueueEntry entry, Subscription sub);
+ }
+
+ Subscription getAssignedSubscription(QueueEntry entry);
+
+ boolean acceptMessage(Subscription sub, QueueEntry entry);
+
+ QueueEntry findEarliestAssignedAvailableEntry(Subscription sub);
+
+ void clearAssignments(Subscription sub);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
index 6db58ce9c1..1e36119ce8 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
@@ -62,7 +62,6 @@ import org.apache.qpid.transport.MessageProperties;
import org.apache.qpid.transport.MessageTransfer;
import org.apache.qpid.transport.Method;
import org.apache.qpid.transport.Option;
-import org.apache.qpid.transport.Session;
import org.apache.qpid.transport.Struct;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicContentHeaderProperties;
@@ -70,10 +69,10 @@ import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.AMQException;
import java.text.MessageFormat;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.locks.Lock;
@@ -183,6 +182,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
throw new IllegalStateException("Attempt to set queue for subscription " + this + " to " + queue + "when already set to " + getQueue());
}
_queue = queue;
+
Map<String, Object> arguments = queue.getArguments() == null ? Collections.EMPTY_MAP : queue.getArguments();
_traceExclude = (String) arguments.get("qpid.trace.exclude");
_trace = (String) arguments.get("qpid.trace.id");
@@ -219,8 +219,8 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
if (_noLocal && entry.getMessage() instanceof MessageTransferMessage)
{
- Session messageSession= ((MessageTransferMessage)entry.getMessage()).getSession();
- if (messageSession != null && messageSession.getConnection() == _session.getConnection())
+ Object connectionRef = ((MessageTransferMessage)entry.getMessage()).getConnectionReference();
+ if (connectionRef != null && connectionRef == _session.getReference())
{
return false;
}
@@ -366,35 +366,8 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
{
MessageTransferMessage msg = (MessageTransferMessage) serverMsg;
-
-
- Struct[] headers;
- if(msg.getHeader() == null)
- {
- headers = EMPTY_STRUCT_ARRAY;
- }
- else
- {
- headers = msg.getHeader().getStructs();
- }
-
- ArrayList<Struct> newHeaders = new ArrayList<Struct>(headers.length);
- DeliveryProperties origDeliveryProps = null;
- for(Struct header : headers)
- {
- if(header instanceof DeliveryProperties)
- {
- origDeliveryProps = (DeliveryProperties) header;
- }
- else
- {
- if(header instanceof MessageProperties)
- {
- messageProps = (MessageProperties) header;
- }
- newHeaders.add(header);
- }
- }
+ DeliveryProperties origDeliveryProps = msg.getHeader() == null ? null : msg.getHeader().getDeliveryProperties();
+ messageProps = msg.getHeader() == null ? null : msg.getHeader().getMessageProperties();
deliveryProps = new DeliveryProperties();
if(origDeliveryProps != null)
@@ -429,17 +402,16 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
deliveryProps.setRedelivered(entry.isRedelivered());
- newHeaders.add(deliveryProps);
-
if(_trace != null && messageProps == null)
{
messageProps = new MessageProperties();
- newHeaders.add(messageProps);
}
- Header header = new Header(newHeaders);
+ Header header = new Header(deliveryProps, messageProps, msg.getHeader() == null ? null : msg.getHeader().getNonStandardProperties());
- xfr = new MessageTransfer(_destination,_acceptMode,_acquireMode,header,msg.getBody());
+
+ xfr = batch ? new MessageTransfer(_destination,_acceptMode,_acquireMode,header,msg.getBody(), BATCHED)
+ : new MessageTransfer(_destination,_acceptMode,_acquireMode,header,msg.getBody());
}
else if(serverMsg instanceof AMQMessage)
{
@@ -452,8 +424,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
message_0_8.getContent(body, 0);
body.flip();
- Struct[] headers = new Struct[] { deliveryProps, messageProps };
-
BasicContentHeaderProperties properties =
(BasicContentHeaderProperties) message_0_8.getContentHeaderBody().getProperties();
final AMQShortString exchange = message_0_8.getMessagePublishInfo().getExchange();
@@ -494,8 +464,9 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
messageProps.setApplicationHeaders(appHeaders);
- Header header = new Header(headers);
- xfr = new MessageTransfer(_destination,_acceptMode,_acquireMode,header, body);
+ Header header = new Header(deliveryProps, messageProps, null);
+ xfr = batch ? new MessageTransfer(_destination,_acceptMode,_acquireMode,header, body, BATCHED)
+ : new MessageTransfer(_destination,_acceptMode,_acquireMode,header, body);
}
else
{
@@ -508,8 +479,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
serverMsg.getContent(body, 0);
body.flip();
- Struct[] headers = new Struct[] { deliveryProps, messageProps };
-
deliveryProps.setExpiration(serverMsg.getExpiration());
deliveryProps.setImmediate(serverMsg.isImmediate());
@@ -556,8 +525,9 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
messageProps.setApplicationHeaders(appHeaders);
*/
- Header header = new Header(headers);
- xfr = new MessageTransfer(_destination,_acceptMode,_acquireMode,header, body);
+ Header header = new Header(deliveryProps, messageProps, null);
+ xfr = batch ? new MessageTransfer(_destination,_acceptMode,_acquireMode,header, body, BATCHED)
+ : new MessageTransfer(_destination,_acceptMode,_acquireMode,header, body);
}
boolean excludeDueToFederation = false;
@@ -633,28 +603,47 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
}
}
- private void forceDequeue(final QueueEntry entry, final boolean restoreCredit)
+ private void deferredAddCredit(final int deferredMessageCredit, final long deferredSizeCredit)
{
- ServerTransaction txn = new AutoCommitTransaction(getQueue().getVirtualHost().getTransactionLog());
- txn.dequeue(entry.getQueue(),entry.getMessage(),
- new ServerTransaction.Action()
- {
- public void postCommit()
- {
- if(restoreCredit)
- {
- restoreCredit(entry);
- }
- entry.discard();
- }
+ _deferredMessageCredit += deferredMessageCredit;
+ _deferredSizeCredit += deferredSizeCredit;
- public void onRollback()
- {
+ }
- }
- });
+ public void flushCreditState(boolean strict)
+ {
+ if(strict || !isSuspended() || _deferredMessageCredit >= 200
+ || !(_creditManager instanceof WindowCreditManager)
+ || ((WindowCreditManager)_creditManager).getMessageCreditLimit() < 400 )
+ {
+ _creditManager.restoreCredit(_deferredMessageCredit, _deferredSizeCredit);
+ _deferredMessageCredit = 0;
+ _deferredSizeCredit = 0l;
+ }
}
+ private void forceDequeue(final QueueEntry entry, final boolean restoreCredit)
+ {
+ AutoCommitTransaction dequeueTxn = new AutoCommitTransaction(getQueue().getVirtualHost().getMessageStore());
+ dequeueTxn.dequeue(entry.getQueue(), entry.getMessage(),
+ new ServerTransaction.Action()
+ {
+ public void postCommit()
+ {
+ if (restoreCredit)
+ {
+ restoreCredit(entry);
+ }
+ entry.discard();
+ }
+
+ public void onRollback()
+ {
+
+ }
+ });
+ }
+
void reject(final QueueEntry entry)
{
entry.setRedelivered();
@@ -693,7 +682,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
{
final InboundMessage m = new InboundMessageAdapter(entry);
- final ArrayList<? extends BaseQueue> destinationQueues = alternateExchange.route(m);
+ final List<? extends BaseQueue> destinationQueues = alternateExchange.route(m);
if (destinationQueues == null || destinationQueues.isEmpty())
{
@@ -740,6 +729,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
return _stateChangeLock.tryLock();
}
+
public void getSendLock()
{
_stateChangeLock.lock();
@@ -800,28 +790,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
return _properties.get(key);
}
- private void deferredAddCredit(final int deferredMessageCredit, final long deferredSizeCredit)
- {
- _deferredMessageCredit += deferredMessageCredit;
- _deferredSizeCredit += deferredSizeCredit;
-
- }
-
- public void flushCreditState()
- {
- flushCreditState(false);
- }
- public void flushCreditState(boolean strict)
- {
- if(strict || !isSuspended() || _deferredMessageCredit >= 200
- || !(_creditManager instanceof WindowCreditManager)
- || ((WindowCreditManager)_creditManager).getMessageCreditLimit() < 400 )
- {
- _creditManager.restoreCredit(_deferredMessageCredit, _deferredSizeCredit);
- _deferredMessageCredit = 0;
- _deferredSizeCredit = 0l;
- }
- }
public FlowCreditManager_0_10 getCreditManager()
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
index 00f0c9f0f1..ab07ed20f6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
@@ -75,7 +75,7 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
private boolean _statisticsEnabled = false;
private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
private final long _connectionId;
-
+ private final Object _reference = new Object();
private ServerConnectionMBean _mBean;
private VirtualHost _virtualHost;
private AtomicLong _lastIoTime = new AtomicLong();
@@ -90,6 +90,11 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
return _config.getId();
}
+ public Object getReference()
+ {
+ return _reference;
+ }
+
@Override
protected void invoke(Method method)
{
@@ -414,13 +419,11 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
return _connectionId;
}
- @Override
public boolean isSessionNameUnique(byte[] name)
{
return !super.hasSessionWithName(name);
}
- @Override
public String getUserName()
{
return _authorizedPrincipal.getName();
@@ -450,11 +453,11 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
{
for (Session ssn : getChannels())
{
- ((ServerSession)ssn).flushCreditState();
+ ((ServerSession)ssn).receivedComplete();
}
}
- @Override
+
public ManagedObject getManagedObject()
{
return _mBean;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
index 23b77b1fd9..2142b2f7c3 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
@@ -23,10 +23,8 @@ package org.apache.qpid.server.transport;
import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CHANNEL_FORMAT;
import static org.apache.qpid.util.Serial.gt;
-import java.lang.ref.WeakReference;
import java.security.Principal;
import java.text.MessageFormat;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -34,8 +32,11 @@ import java.util.Map;
import java.util.SortedMap;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import javax.security.auth.Subject;
import org.apache.qpid.AMQException;
@@ -51,6 +52,7 @@ import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.GenericActor;
import org.apache.qpid.server.logging.messages.ChannelMessages;
+import org.apache.qpid.server.logging.subjects.ChannelLogSubject;
import org.apache.qpid.server.message.MessageReference;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.protocol.AMQConnectionModel;
@@ -67,10 +69,16 @@ import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.transport.Binary;
import org.apache.qpid.transport.Connection;
+import org.apache.qpid.transport.MessageCreditUnit;
+import org.apache.qpid.transport.MessageFlow;
+import org.apache.qpid.transport.MessageFlowMode;
+import org.apache.qpid.transport.MessageSetFlowMode;
+import org.apache.qpid.transport.MessageStop;
import org.apache.qpid.transport.MessageTransfer;
import org.apache.qpid.transport.Method;
import org.apache.qpid.transport.Range;
import org.apache.qpid.transport.RangeSet;
+import org.apache.qpid.transport.RangeSetFactory;
import org.apache.qpid.transport.Session;
import org.apache.qpid.transport.SessionDelegate;
import org.slf4j.Logger;
@@ -81,11 +89,20 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
private static final Logger _logger = LoggerFactory.getLogger(ServerSession.class);
private static final String NULL_DESTINTATION = UUID.randomUUID().toString();
+ private static final int PRODUCER_CREDIT_TOPUP_THRESHOLD = 1 << 30;
private final UUID _id;
private ConnectionConfig _connectionConfig;
private long _createTime = System.currentTimeMillis();
private LogActor _actor = GenericActor.getInstance(this);
+ private PostEnqueueAction _postEnqueueAction = new PostEnqueueAction();
+
+ private final ConcurrentMap<AMQQueue, Boolean> _blockingQueues = new ConcurrentHashMap<AMQQueue, Boolean>();
+
+ private final AtomicBoolean _blocking = new AtomicBoolean(false);
+ private ChannelLogSubject _logSubject;
+ private final AtomicInteger _outstandingCredit = new AtomicInteger(UNLIMITED_CREDIT);
+
public static interface MessageDispositionChangeListener
{
@@ -121,8 +138,6 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
private final List<Task> _taskList = new CopyOnWriteArrayList<Task>();
- private final WeakReference<Session> _reference;
-
ServerSession(Connection connection, SessionDelegate delegate, Binary name, long expiry)
{
this(connection, delegate, name, expiry, ((ServerConnection)connection).getConfig());
@@ -133,8 +148,7 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
super(connection, delegate, name, expiry);
_connectionConfig = connConfig;
_transaction = new AutoCommitTransaction(this.getMessageStore());
-
- _reference = new WeakReference<Session>(this);
+ _logSubject = new ChannelLogSubject(this);
_id = getConfigStore().createId();
getConfigStore().addConfiguredObject(this);
}
@@ -161,40 +175,28 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
return isCommandsFull(id);
}
- public void enqueue(final ServerMessage message, final ArrayList<? extends BaseQueue> queues)
+ public void enqueue(final ServerMessage message, final List<? extends BaseQueue> queues)
{
+ if(_outstandingCredit.get() != UNLIMITED_CREDIT
+ && _outstandingCredit.decrementAndGet() == (Integer.MAX_VALUE - PRODUCER_CREDIT_TOPUP_THRESHOLD))
+ {
+ _outstandingCredit.addAndGet(PRODUCER_CREDIT_TOPUP_THRESHOLD);
+ invoke(new MessageFlow("",MessageCreditUnit.MESSAGE, PRODUCER_CREDIT_TOPUP_THRESHOLD));
+ }
getConnectionModel().registerMessageReceived(message.getSize(), message.getArrivalTime());
- _transaction.enqueue(queues,message, new ServerTransaction.Action()
- {
-
- BaseQueue[] _queues = queues.toArray(new BaseQueue[queues.size()]);
-
- public void postCommit()
- {
- MessageReference<?> ref = message.newReference();
- for(int i = 0; i < _queues.length; i++)
- {
- try
- {
- _queues[i].enqueue(message);
- }
- catch (AMQException e)
- {
- // TODO
- throw new RuntimeException(e);
- }
- }
- ref.release();
- }
-
- public void onRollback()
- {
- // NO-OP
- }
- });
-
- incrementOutstandingTxnsIfNecessary();
- updateTransactionalActivity();
+ PostEnqueueAction postTransactionAction;
+ if(isTransactional())
+ {
+ postTransactionAction = new PostEnqueueAction(queues, message) ;
+ }
+ else
+ {
+ postTransactionAction = _postEnqueueAction;
+ postTransactionAction.setState(queues, message);
+ }
+ _transaction.enqueue(queues,message, postTransactionAction, 0L);
+ incrementOutstandingTxnsIfNecessary();
+ updateTransactionalActivity();
}
@@ -252,7 +254,7 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
public RangeSet acquire(RangeSet transfers)
{
- RangeSet acquired = new RangeSet();
+ RangeSet acquired = RangeSetFactory.createRangeSet();
if(!_messageDispositionListenerMap.isEmpty())
{
@@ -300,41 +302,56 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
public void dispositionChange(RangeSet ranges, MessageDispositionAction action)
{
- if(ranges != null && !_messageDispositionListenerMap.isEmpty())
+ if(ranges != null)
{
- Iterator<Integer> unacceptedMessages = _messageDispositionListenerMap.keySet().iterator();
- Iterator<Range> rangeIter = ranges.iterator();
- if(rangeIter.hasNext())
+ if(ranges.size() == 1)
{
- Range range = rangeIter.next();
+ Range r = ranges.getFirst();
+ for(int i = r.getLower(); i <= r.getUpper(); i++)
+ {
+ MessageDispositionChangeListener changeListener = _messageDispositionListenerMap.remove(i);
+ if(changeListener != null)
+ {
+ action.performAction(changeListener);
+ }
+ }
+ }
+ else if(!_messageDispositionListenerMap.isEmpty())
+ {
+ Iterator<Integer> unacceptedMessages = _messageDispositionListenerMap.keySet().iterator();
+ Iterator<Range> rangeIter = ranges.iterator();
- while(range != null && unacceptedMessages.hasNext())
+ if(rangeIter.hasNext())
{
- int next = unacceptedMessages.next();
- while(gt(next, range.getUpper()))
+ Range range = rangeIter.next();
+
+ while(range != null && unacceptedMessages.hasNext())
{
- if(rangeIter.hasNext())
+ int next = unacceptedMessages.next();
+ while(gt(next, range.getUpper()))
{
- range = rangeIter.next();
+ if(rangeIter.hasNext())
+ {
+ range = rangeIter.next();
+ }
+ else
+ {
+ range = null;
+ break;
+ }
}
- else
+ if(range != null && range.includes(next))
{
- range = null;
- break;
+ MessageDispositionChangeListener changeListener = _messageDispositionListenerMap.remove(next);
+ action.performAction(changeListener);
}
- }
- if(range != null && range.includes(next))
- {
- MessageDispositionChangeListener changeListener = _messageDispositionListenerMap.remove(next);
- action.performAction(changeListener);
- }
- }
+ }
+ }
}
-
}
}
@@ -534,10 +551,10 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
_taskList.remove(task);
}
- public WeakReference<Session> getReference()
- {
- return _reference;
- }
+ public Object getReference()
+ {
+ return ((ServerConnection) getConnection()).getReference();
+ }
public MessageStore getMessageStore()
{
@@ -666,13 +683,57 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
}
}
+ public void block(AMQQueue queue)
+ {
+ if(_blockingQueues.putIfAbsent(queue, Boolean.TRUE) == null)
+ {
+
+ if(_blocking.compareAndSet(false,true))
+ {
+ invoke(new MessageSetFlowMode("", MessageFlowMode.CREDIT));
+ invoke(new MessageStop(""));
+ _actor.message(_logSubject, ChannelMessages.FLOW_ENFORCED(queue.getNameShortString().toString()));
+ }
+
+
+ }
+ }
+
+ public void unblock(AMQQueue queue)
+ {
+ if(_blockingQueues.remove(queue) && _blockingQueues.isEmpty())
+ {
+ if(_blocking.compareAndSet(true,false))
+ {
+
+ _actor.message(_logSubject, ChannelMessages.FLOW_REMOVED());
+ MessageFlow mf = new MessageFlow();
+ mf.setUnit(MessageCreditUnit.MESSAGE);
+ mf.setDestination("");
+ _outstandingCredit.set(Integer.MAX_VALUE);
+ mf.setValue(Integer.MAX_VALUE);
+ invoke(mf);
+
+
+ }
+ }
+ }
+
+
public String toLogString()
{
- return "[" +
+ long connectionId = getConnection() instanceof ServerConnection
+ ? ((ServerConnection) getConnection()).getConnectionId()
+ : -1;
+
+ String remoteAddress = _connectionConfig instanceof ProtocolEngine
+ ? ((ProtocolEngine) _connectionConfig).getRemoteAddress().toString()
+ : "";
+ return "[" +
MessageFormat.format(CHANNEL_FORMAT,
- ((ServerConnection) getConnection()).getConnectionId(),
+ connectionId,
getClientID(),
- ((ProtocolEngine) _connectionConfig).getRemoteAddress().toString(),
+ remoteAddress,
getVirtualHost().getName(),
getChannel())
+ "] ";
@@ -697,7 +758,7 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
}
}
- public void flushCreditState()
+ public void receivedComplete()
{
final Collection<Subscription_0_10> subscriptions = getSubscriptions();
for (Subscription_0_10 subscription_0_10 : subscriptions)
@@ -706,6 +767,60 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
}
}
+ private class PostEnqueueAction implements ServerTransaction.Action
+ {
+
+ private List<? extends BaseQueue> _queues;
+ private ServerMessage _message;
+ private final boolean _transactional;
+
+ public PostEnqueueAction(List<? extends BaseQueue> queues, ServerMessage message)
+ {
+ _transactional = true;
+ setState(queues, message);
+ }
+
+ public PostEnqueueAction()
+ {
+ _transactional = false;
+ }
+
+ public void setState(List<? extends BaseQueue> queues, ServerMessage message)
+ {
+ _message = message;
+ _queues = queues;
+ }
+
+ public void postCommit()
+ {
+ MessageReference<?> ref = _message.newReference();
+ for(int i = 0; i < _queues.size(); i++)
+ {
+ try
+ {
+ BaseQueue queue = _queues.get(i);
+ queue.enqueue(_message, _transactional, null);
+ if(queue instanceof AMQQueue)
+ {
+ ((AMQQueue)queue).checkCapacity(ServerSession.this);
+ }
+
+ }
+ catch (AMQException e)
+ {
+ // TODO
+ throw new RuntimeException(e);
+ }
+ }
+ ref.release();
+ }
+
+ public void onRollback()
+ {
+ // NO-OP
+ }
+ }
+
public int getUnacknowledgedMessageCount()
{
return _messageDispositionListenerMap.size();
@@ -713,6 +828,6 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
public boolean getBlocking()
{
- return false; //TODO: Blocking not implemented on 0-10 yet.
+ return _blocking.get();
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
index a0dca53ed0..b6e142a5fd 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server.transport;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
@@ -55,46 +56,7 @@ import org.apache.qpid.server.store.StoredMessage;
import org.apache.qpid.server.subscription.SubscriptionFactoryImpl;
import org.apache.qpid.server.subscription.Subscription_0_10;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.Acquired;
-import org.apache.qpid.transport.DeliveryProperties;
-import org.apache.qpid.transport.ExchangeBind;
-import org.apache.qpid.transport.ExchangeBound;
-import org.apache.qpid.transport.ExchangeBoundResult;
-import org.apache.qpid.transport.ExchangeDeclare;
-import org.apache.qpid.transport.ExchangeDelete;
-import org.apache.qpid.transport.ExchangeQuery;
-import org.apache.qpid.transport.ExchangeQueryResult;
-import org.apache.qpid.transport.ExchangeUnbind;
-import org.apache.qpid.transport.ExecutionErrorCode;
-import org.apache.qpid.transport.ExecutionException;
-import org.apache.qpid.transport.MessageAccept;
-import org.apache.qpid.transport.MessageAcceptMode;
-import org.apache.qpid.transport.MessageAcquire;
-import org.apache.qpid.transport.MessageAcquireMode;
-import org.apache.qpid.transport.MessageCancel;
-import org.apache.qpid.transport.MessageFlow;
-import org.apache.qpid.transport.MessageFlowMode;
-import org.apache.qpid.transport.MessageFlush;
-import org.apache.qpid.transport.MessageReject;
-import org.apache.qpid.transport.MessageRejectCode;
-import org.apache.qpid.transport.MessageRelease;
-import org.apache.qpid.transport.MessageResume;
-import org.apache.qpid.transport.MessageSetFlowMode;
-import org.apache.qpid.transport.MessageStop;
-import org.apache.qpid.transport.MessageSubscribe;
-import org.apache.qpid.transport.MessageTransfer;
-import org.apache.qpid.transport.Method;
-import org.apache.qpid.transport.QueueDeclare;
-import org.apache.qpid.transport.QueueDelete;
-import org.apache.qpid.transport.QueuePurge;
-import org.apache.qpid.transport.QueueQuery;
-import org.apache.qpid.transport.QueueQueryResult;
-import org.apache.qpid.transport.RangeSet;
-import org.apache.qpid.transport.Session;
-import org.apache.qpid.transport.SessionDelegate;
-import org.apache.qpid.transport.TxCommit;
-import org.apache.qpid.transport.TxRollback;
-import org.apache.qpid.transport.TxSelect;
+import org.apache.qpid.transport.*;
public class ServerSessionDelegate extends SessionDelegate
{
@@ -295,7 +257,8 @@ public class ServerSessionDelegate extends SessionDelegate
final Exchange exchange = getExchangeForMessage(ssn, xfr);
DeliveryProperties delvProps = null;
- if(xfr.getHeader() != null && (delvProps = xfr.getHeader().get(DeliveryProperties.class)) != null && delvProps.hasTtl() && !delvProps.hasExpiration())
+ if(xfr.getHeader() != null && (delvProps = xfr.getHeader().getDeliveryProperties()) != null && delvProps.hasTtl() && !delvProps
+ .hasExpiration())
{
delvProps.setExpiration(System.currentTimeMillis() + delvProps.getTtl());
}
@@ -312,7 +275,7 @@ public class ServerSessionDelegate extends SessionDelegate
}
final Exchange exchangeInUse;
- ArrayList<? extends BaseQueue> queues = exchange.route(messageMetaData);
+ List<? extends BaseQueue> queues = exchange.route(messageMetaData);
if(queues.isEmpty() && exchange.getAlternateExchange() != null)
{
final Exchange alternateExchange = exchange.getAlternateExchange();
@@ -334,15 +297,16 @@ public class ServerSessionDelegate extends SessionDelegate
if(!queues.isEmpty())
{
final MessageStore store = getVirtualHost(ssn).getMessageStore();
- final StoredMessage<MessageMetaData_0_10> storeMessage = createAndFlushStoreMessage(xfr, messageMetaData, store);
+ final StoredMessage<MessageMetaData_0_10> storeMessage = createStoreMessage(xfr, messageMetaData, store);
MessageTransferMessage message = new MessageTransferMessage(storeMessage, ((ServerSession)ssn).getReference());
((ServerSession) ssn).enqueue(message, queues);
+ storeMessage.flushToStore();
}
else
{
if((delvProps == null || !delvProps.getDiscardUnroutable()) && xfr.getAcceptMode() == MessageAcceptMode.EXPLICIT)
{
- RangeSet rejects = new RangeSet();
+ RangeSet rejects = RangeSetFactory.createRangeSet();
rejects.add(xfr.getId());
MessageReject reject = new MessageReject(rejects, MessageRejectCode.UNROUTABLE, "Unroutable");
ssn.invoke(reject);
@@ -353,11 +317,13 @@ public class ServerSessionDelegate extends SessionDelegate
}
}
+
+
ssn.processed(xfr);
}
- private StoredMessage<MessageMetaData_0_10> createAndFlushStoreMessage(final MessageTransfer xfr,
- final MessageMetaData_0_10 messageMetaData, final MessageStore store)
+ private StoredMessage<MessageMetaData_0_10> createStoreMessage(final MessageTransfer xfr,
+ final MessageMetaData_0_10 messageMetaData, final MessageStore store)
{
final StoredMessage<MessageMetaData_0_10> storeMessage = store.addMessage(messageMetaData);
ByteBuffer body = xfr.getBody();
@@ -365,7 +331,6 @@ public class ServerSessionDelegate extends SessionDelegate
{
storeMessage.addContent(0, body);
}
- storeMessage.flushToStore();
return storeMessage;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java
index 36e9d78440..a67d4badd1 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.txn;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -30,7 +31,7 @@ import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.queue.QueueEntry;
-import org.apache.qpid.server.store.TransactionLog;
+import org.apache.qpid.server.store.MessageStore;
/**
* An implementation of ServerTransaction where each enqueue/dequeue
@@ -43,11 +44,11 @@ public class AutoCommitTransaction implements ServerTransaction
{
protected static final Logger _logger = Logger.getLogger(AutoCommitTransaction.class);
- private final TransactionLog _transactionLog;
+ private final MessageStore _messageStore;
- public AutoCommitTransaction(TransactionLog transactionLog)
+ public AutoCommitTransaction(MessageStore transactionLog)
{
- _transactionLog = transactionLog;
+ _messageStore = transactionLog;
}
public long getTransactionStartTime()
@@ -59,14 +60,14 @@ public class AutoCommitTransaction implements ServerTransaction
* Since AutoCommitTransaction have no concept of a long lived transaction, any Actions registered
* by the caller are executed immediately.
*/
- public void addPostTransactionAction(Action immediateAction)
+ public void addPostTransactionAction(final Action immediateAction)
{
immediateAction.postCommit();
}
public void dequeue(BaseQueue queue, EnqueableMessage message, Action postTransactionAction)
{
- TransactionLog.Transaction txn = null;
+ MessageStore.Transaction txn = null;
try
{
if(message.isPersistent() && queue.isDurable())
@@ -76,8 +77,8 @@ public class AutoCommitTransaction implements ServerTransaction
_logger.debug("Dequeue of message number " + message.getMessageNumber() + " from transaction log. Queue : " + queue.getNameShortString());
}
- txn = _transactionLog.newTransaction();
- txn.dequeueMessage(queue, message.getMessageNumber());
+ txn = _messageStore.newTransaction();
+ txn.dequeueMessage(queue, message);
txn.commitTran();
txn = null;
}
@@ -98,7 +99,7 @@ public class AutoCommitTransaction implements ServerTransaction
public void dequeue(Collection<QueueEntry> queueEntries, Action postTransactionAction)
{
- TransactionLog.Transaction txn = null;
+ MessageStore.Transaction txn = null;
try
{
for(QueueEntry entry : queueEntries)
@@ -115,10 +116,10 @@ public class AutoCommitTransaction implements ServerTransaction
if(txn == null)
{
- txn = _transactionLog.newTransaction();
+ txn = _messageStore.newTransaction();
}
- txn.dequeueMessage(queue, message.getMessageNumber());
+ txn.dequeueMessage(queue, message);
}
}
@@ -145,7 +146,7 @@ public class AutoCommitTransaction implements ServerTransaction
public void enqueue(BaseQueue queue, EnqueableMessage message, Action postTransactionAction)
{
- TransactionLog.Transaction txn = null;
+ MessageStore.Transaction txn = null;
try
{
if(message.isPersistent() && queue.isDurable())
@@ -155,8 +156,8 @@ public class AutoCommitTransaction implements ServerTransaction
_logger.debug("Enqueue of message number " + message.getMessageNumber() + " to transaction log. Queue : " + queue.getNameShortString());
}
- txn = _transactionLog.newTransaction();
- txn.enqueueMessage(queue, message.getMessageNumber());
+ txn = _messageStore.newTransaction();
+ txn.enqueueMessage(queue, message);
txn.commitTran();
txn = null;
}
@@ -176,15 +177,14 @@ public class AutoCommitTransaction implements ServerTransaction
}
- public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction)
+ public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction, long currentTime)
{
- TransactionLog.Transaction txn = null;
+ MessageStore.Transaction txn = null;
try
{
if(message.isPersistent())
{
- Long id = message.getMessageNumber();
for(BaseQueue queue : queues)
{
if (queue.isDurable())
@@ -195,22 +195,26 @@ public class AutoCommitTransaction implements ServerTransaction
}
if (txn == null)
{
- txn = _transactionLog.newTransaction();
+ txn = _messageStore.newTransaction();
}
- txn.enqueueMessage(queue, id);
+ txn.enqueueMessage(queue, message);
+
+
}
}
- if (txn != null)
- {
- txn.commitTran();
- txn = null;
-
- }
}
+ if (txn != null)
+ {
+ txn.commitTran();
+ txn = null;
+ }
+
postTransactionAction.postCommit();
postTransactionAction = null;
+
+
}
catch (AMQException e)
{
@@ -225,6 +229,11 @@ public class AutoCommitTransaction implements ServerTransaction
}
+ public void commit(final Runnable immediatePostTransactionAction)
+ {
+ immediatePostTransactionAction.run();
+ }
+
public void commit()
{
}
@@ -233,7 +242,7 @@ public class AutoCommitTransaction implements ServerTransaction
{
}
- private void rollbackIfNecessary(Action postTransactionAction, TransactionLog.Transaction txn)
+ private void rollbackIfNecessary(Action postTransactionAction, MessageStore.Transaction txn)
{
if (txn != null)
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
index 946dbd7c28..7f5b5fb8b2 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
@@ -29,11 +29,7 @@ import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.queue.QueueEntry;
-import org.apache.qpid.server.store.TransactionLog;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.queue.BaseQueue;
-import org.apache.qpid.server.queue.QueueEntry;
-import org.apache.qpid.server.store.TransactionLog;
+import org.apache.qpid.server.store.MessageStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -50,11 +46,11 @@ public class LocalTransaction implements ServerTransaction
private final List<Action> _postTransactionActions = new ArrayList<Action>();
- private volatile TransactionLog.Transaction _transaction;
- private TransactionLog _transactionLog;
+ private volatile MessageStore.Transaction _transaction;
+ private MessageStore _transactionLog;
private long _txnStartTime = 0L;
- public LocalTransaction(TransactionLog transactionLog)
+ public LocalTransaction(MessageStore transactionLog)
{
_transactionLog = transactionLog;
}
@@ -63,7 +59,7 @@ public class LocalTransaction implements ServerTransaction
{
return _transaction != null;
}
-
+
public long getTransactionStartTime()
{
return _txnStartTime;
@@ -88,7 +84,7 @@ public class LocalTransaction implements ServerTransaction
}
beginTranIfNecessary();
- _transaction.dequeueMessage(queue, message.getMessageNumber());
+ _transaction.dequeueMessage(queue, message);
}
catch(AMQException e)
@@ -118,7 +114,7 @@ public class LocalTransaction implements ServerTransaction
}
beginTranIfNecessary();
- _transaction.dequeueMessage(queue, message.getMessageNumber());
+ _transaction.dequeueMessage(queue, message);
}
}
@@ -191,7 +187,7 @@ public class LocalTransaction implements ServerTransaction
}
beginTranIfNecessary();
- _transaction.enqueueMessage(queue, message.getMessageNumber());
+ _transaction.enqueueMessage(queue, message);
}
catch (Exception e)
{
@@ -202,13 +198,13 @@ public class LocalTransaction implements ServerTransaction
}
}
- public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction)
+ public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction, long currentTime)
{
_postTransactionActions.add(postTransactionAction);
if (_txnStartTime == 0L)
{
- _txnStartTime = System.currentTimeMillis();
+ _txnStartTime = currentTime == 0L ? System.currentTimeMillis() : currentTime;
}
if(message.isPersistent())
@@ -226,7 +222,7 @@ public class LocalTransaction implements ServerTransaction
beginTranIfNecessary();
- _transaction.enqueueMessage(queue, message.getMessageNumber());
+ _transaction.enqueueMessage(queue, message);
}
}
@@ -242,6 +238,11 @@ public class LocalTransaction implements ServerTransaction
public void commit()
{
+ commit(null);
+ }
+
+ public void commit(Runnable immediateAction)
+ {
try
{
if(_transaction != null)
@@ -249,9 +250,14 @@ public class LocalTransaction implements ServerTransaction
_transaction.commitTran();
}
- for(Action action : _postTransactionActions)
+ if(immediateAction != null)
+ {
+ immediateAction.run();
+ }
+
+ for(int i = 0; i < _postTransactionActions.size(); i++)
{
- action.postCommit();
+ _postTransactionActions.get(i).postCommit();
}
}
catch (Exception e)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java
index b3c6e1ac3a..acdf712de9 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java
@@ -20,13 +20,12 @@
*/
package org.apache.qpid.server.txn;
+import java.util.Collection;
+import java.util.List;
import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.queue.QueueEntry;
-import java.util.Collection;
-import java.util.List;
-
/**
* The ServerTransaction interface allows a set enqueue/dequeue operations to be
@@ -42,7 +41,7 @@ import java.util.List;
*/
public interface ServerTransaction
{
- /**
+ /**
* Represents an action to be performed on transaction commit or rollback
*/
public static interface Action
@@ -91,7 +90,7 @@ public interface ServerTransaction
*
* Store operations will result only for a persistent messages on durable queues.
*/
- void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction);
+ void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction, long currentTime);
/**
* Commit the transaction represented by this object.
@@ -101,6 +100,8 @@ public interface ServerTransaction
*/
void commit();
+ void commit(Runnable immediatePostTransactionAction);
+
/** Rollback the transaction represented by this object.
*
* If the caller has registered one or more Actions, the onRollback() method on each will
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
index e8042fcaaf..41a5471a64 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.virtualhost;
+import java.util.Map;
import java.util.UUID;
import org.apache.qpid.common.Closeable;
@@ -40,7 +41,6 @@ import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.stats.StatisticsGatherer;
import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.store.MessageStore;
-import org.apache.qpid.server.store.TransactionLog;
public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHostConfig, Closeable, StatisticsGatherer
{
@@ -58,8 +58,6 @@ public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHo
MessageStore getMessageStore();
- TransactionLog getTransactionLog();
-
DurableConfigurationStore getDurableConfigurationStore();
AuthenticationManager getAuthenticationManager();
@@ -95,6 +93,8 @@ public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHo
boolean durable,
String authMechanism, String username, String password);
+ public BrokerLink createBrokerConnection(UUID id, long createTime, Map<String,String> arguments);
+
ConfigStore getConfigStore();
void removeBrokerConnection(BrokerLink brokerLink);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java
index 0fd31973b2..51892d965a 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java
@@ -20,12 +20,13 @@
*/
package org.apache.qpid.server.virtualhost;
+import org.apache.qpid.server.federation.BrokerLink;
+import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.store.ConfigurationRecoveryHandler;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.MessageStoreRecoveryHandler;
import org.apache.qpid.server.store.StoredMessage;
import org.apache.qpid.server.store.TransactionLogRecoveryHandler;
-import org.apache.qpid.server.store.TransactionLog;
import org.apache.qpid.server.store.TransactionLogResource;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
@@ -43,7 +44,7 @@ import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.AMQException;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.util.ByteBufferInputStream;
+import org.apache.qpid.util.ByteBufferInputStream;
import java.io.DataInputStream;
import java.io.IOException;
@@ -54,11 +55,13 @@ import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.TreeMap;
+import java.util.UUID;
public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHandler,
ConfigurationRecoveryHandler.QueueRecoveryHandler,
ConfigurationRecoveryHandler.ExchangeRecoveryHandler,
ConfigurationRecoveryHandler.BindingRecoveryHandler,
+ ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler,
MessageStoreRecoveryHandler,
MessageStoreRecoveryHandler.StoredMessageRecoveryHandler,
TransactionLogRecoveryHandler,
@@ -73,7 +76,6 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
private List<ProcessAction> _actions;
private MessageStore _store;
- private TransactionLog _transactionLog;
private final Map<String, Integer> _queueRecoveries = new TreeMap<String, Integer>();
private Map<Long, ServerMessage> _recoveredMessages = new HashMap<Long, ServerMessage>();
@@ -86,7 +88,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
_virtualHost = virtualHost;
}
- public QueueRecoveryHandler begin(MessageStore store)
+ public VirtualHostConfigRecoveryHandler begin(MessageStore store)
{
_logSubject = new MessageStoreLogSubject(_virtualHost,store);
_store = store;
@@ -99,14 +101,12 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
{
try
{
- AMQShortString queueNameShortString = new AMQShortString(queueName);
-
- AMQQueue q = _virtualHost.getQueueRegistry().getQueue(queueNameShortString);
+ AMQQueue q = _virtualHost.getQueueRegistry().getQueue(queueName);
if (q == null)
{
- q = AMQQueueFactory.createAMQQueueImpl(queueNameShortString, true, owner == null ? null : new AMQShortString(owner), false, exclusive, _virtualHost,
- arguments);
+ q = AMQQueueFactory.createAMQQueueImpl(queueName, true, owner, false, exclusive, _virtualHost,
+ FieldTable.convertToMap(arguments));
_virtualHost.getQueueRegistry().registerQueue(q);
}
@@ -183,13 +183,19 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
public void completeMessageRecovery()
{
//TODO - log end
- //To change body of implemented methods use File | Settings | File Templates.
}
- public TransactionLogRecoveryHandler.QueueEntryRecoveryHandler begin(TransactionLog log)
+ public BridgeRecoveryHandler brokerLink(final UUID id,
+ final long createTime,
+ final Map<String, String> arguments)
+ {
+ BrokerLink blink = _virtualHost.createBrokerConnection(id, createTime, arguments);
+ return new BridgeRecoveryHandlerImpl(blink);
+
+ }
+
+ public void completeBrokerLinkRecovery()
{
- _transactionLog = log;
- return this;
}
private static final class ProcessAction
@@ -270,9 +276,9 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
}
- public void completeBindingRecovery()
+ public BrokerLinkRecoveryHandler completeBindingRecovery()
{
- //return this;
+ return this;
}
public void complete()
@@ -316,15 +322,15 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
else
{
_logger.warn("Message id " + messageId + " referenced in log as enqueued in queue " + queue.getNameShortString() + " is unknown, entry will be discarded");
- TransactionLog.Transaction txn = _transactionLog.newTransaction();
- txn.dequeueMessage(queue, messageId);
+ MessageStore.Transaction txn = _store.newTransaction();
+ txn.dequeueMessage(queue, new DummyMessage(messageId));
txn.commitTranAsync();
}
}
else
{
_logger.warn("Message id " + messageId + " in log references queue " + queueName + " which is not in the configuration, entry will be discarded");
- TransactionLog.Transaction txn = _transactionLog.newTransaction();
+ MessageStore.Transaction txn = _store.newTransaction();
TransactionLogResource mockQueue =
new TransactionLogResource()
{
@@ -334,7 +340,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
return queueName;
}
};
- txn.dequeueMessage(mockQueue, messageId);
+ txn.dequeueMessage(mockQueue, new DummyMessage(messageId));
txn.commitTranAsync();
}
@@ -367,4 +373,51 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
CurrentActor.get().message(_logSubject, TransactionLogMessages.RECOVERY_COMPLETE(null, false));
}
+ private static class DummyMessage implements EnqueableMessage
+ {
+
+
+ private final long _messageId;
+
+ public DummyMessage(long messageId)
+ {
+ _messageId = messageId;
+ }
+
+ public long getMessageNumber()
+ {
+ return _messageId;
+ }
+
+
+ public boolean isPersistent()
+ {
+ return true;
+ }
+
+
+ public StoredMessage getStoredMessage()
+ {
+ return null;
+ }
+ }
+
+ private class BridgeRecoveryHandlerImpl implements BridgeRecoveryHandler
+ {
+ private final BrokerLink _blink;
+
+ public BridgeRecoveryHandlerImpl(final BrokerLink blink)
+ {
+ _blink = blink;
+ }
+
+ public void bridge(final UUID id, final long createTime, final Map<String, String> arguments)
+ {
+ _blink.createBridge(id, createTime, arguments);
+ }
+
+ public void completeBridgeRecoveryForLink()
+ {
+ }
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
index fde758203b..a4a3633af7 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
@@ -55,6 +55,7 @@ import org.apache.qpid.server.exchange.DefaultExchangeRegistry;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.exchange.ExchangeFactory;
import org.apache.qpid.server.exchange.ExchangeRegistry;
+import org.apache.qpid.server.federation.Bridge;
import org.apache.qpid.server.federation.BrokerLink;
import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.logging.actors.CurrentActor;
@@ -77,7 +78,6 @@ import org.apache.qpid.server.stats.StatisticsCounter;
import org.apache.qpid.server.store.ConfigurationRecoveryHandler;
import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.store.MessageStore;
-import org.apache.qpid.server.store.TransactionLog;
import org.apache.qpid.server.virtualhost.plugins.VirtualHostPlugin;
import org.apache.qpid.server.virtualhost.plugins.VirtualHostPluginFactory;
@@ -231,7 +231,10 @@ public class VirtualHostImpl implements VirtualHost
if (store != null)
{
_messageStore = store;
- _durableConfigurationStore = store;
+ if(store instanceof DurableConfigurationStore)
+ {
+ _durableConfigurationStore = (DurableConfigurationStore) store;
+ }
}
else
{
@@ -383,6 +386,8 @@ public class VirtualHostImpl implements VirtualHost
Class clazz = Class.forName(messageStoreClass);
Object o = clazz.newInstance();
+
+
if (!(o instanceof MessageStore))
{
throw new ClassCastException("Message store class must implement " + MessageStore.class + ". Class " + clazz +
@@ -393,10 +398,18 @@ public class VirtualHostImpl implements VirtualHost
MessageStoreLogSubject storeLogSubject = new MessageStoreLogSubject(this, messageStore);
- messageStore.configureConfigStore(this.getName(),
- recoveryHandler,
- hostConfig.getStoreConfiguration(),
- storeLogSubject);
+
+ if(messageStore instanceof DurableConfigurationStore)
+ {
+ DurableConfigurationStore durableConfigurationStore = (DurableConfigurationStore) messageStore;
+
+ durableConfigurationStore.configureConfigStore(this.getName(),
+ recoveryHandler,
+ hostConfig.getStoreConfiguration(),
+ storeLogSubject);
+
+ _durableConfigurationStore = durableConfigurationStore;
+ }
messageStore.configureMessageStore(this.getName(),
recoveryHandler,
@@ -408,7 +421,8 @@ public class VirtualHostImpl implements VirtualHost
storeLogSubject);
_messageStore = messageStore;
- _durableConfigurationStore = messageStore;
+
+
}
private void initialiseModel(VirtualHostConfiguration config) throws ConfigurationException, AMQException
@@ -556,11 +570,6 @@ public class VirtualHostImpl implements VirtualHost
return _messageStore;
}
- public TransactionLog getTransactionLog()
- {
- return _messageStore;
- }
-
public DurableConfigurationStore getDurableConfigurationStore()
{
return _durableConfigurationStore;
@@ -725,6 +734,16 @@ public class VirtualHostImpl implements VirtualHost
_statisticsEnabled = enabled;
}
+ public BrokerLink createBrokerConnection(UUID id, long createTime, Map<String,String> arguments)
+ {
+ BrokerLink blink = new BrokerLink(this, id, createTime, arguments);
+ // TODO - cope with duplicate broker link creation requests
+ _links.putIfAbsent(blink,blink);
+ getConfigStore().addConfiguredObject(blink);
+ return blink;
+ }
+
+
public void createBrokerConnection(final String transport,
final String host,
final int port,
@@ -735,10 +754,11 @@ public class VirtualHostImpl implements VirtualHost
final String password)
{
BrokerLink blink = new BrokerLink(this, transport, host, port, vhost, durable, authMechanism, username, password);
- if(_links.putIfAbsent(blink,blink) != null)
- {
- getConfigStore().addConfiguredObject(blink);
- }
+
+ // TODO - cope with duplicate broker link creation requests
+ _links.putIfAbsent(blink,blink);
+ getConfigStore().addConfiguredObject(blink);
+
}
public void removeBrokerConnection(final String transport,
@@ -788,7 +808,9 @@ public class VirtualHostImpl implements VirtualHost
public List<Exchange> exchange = new LinkedList<Exchange>();
public List<CreateQueueTuple> queue = new LinkedList<CreateQueueTuple>();
public List<CreateBindingTuple> bindings = new LinkedList<CreateBindingTuple>();
-
+ public List<BrokerLink> links = new LinkedList<BrokerLink>();
+ public List<Bridge> bridges = new LinkedList<Bridge>();
+
public void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception
{
}
@@ -883,6 +905,30 @@ public class VirtualHostImpl implements VirtualHost
public void updateQueue(AMQQueue queue) throws AMQStoreException
{
}
+
+ public void createBrokerLink(final BrokerLink link) throws AMQStoreException
+ {
+ if(link.isDurable())
+ {
+ links.add(link);
+ }
+ }
+
+ public void deleteBrokerLink(final BrokerLink link) throws AMQStoreException
+ {
+ }
+
+ public void createBridge(final Bridge bridge) throws AMQStoreException
+ {
+ if(bridge.isDurable())
+ {
+ bridges.add(bridge);
+ }
+ }
+
+ public void deleteBridge(final Bridge bridge) throws AMQStoreException
+ {
+ }
}
@Override
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java b/qpid/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java
index bfcdbe7460..3d3c7b6cc6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java
@@ -20,15 +20,13 @@
*/
package org.apache.qpid.tools.security;
-import org.apache.commons.codec.binary.Base64;
-
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.security.DigestException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.security.DigestException;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintStream;
+import org.apache.commons.codec.binary.Base64;
public class Passwd
{
@@ -40,7 +38,14 @@ public class Passwd
System.exit(0);
}
- byte[] data = args[1].getBytes("utf-8");
+ Passwd passwd = new Passwd();
+ String output = passwd.getOutput(args[0], args[1]);
+ System.out.println(output);
+ }
+
+ public String getOutput(String userName, String password) throws UnsupportedEncodingException, NoSuchAlgorithmException
+ {
+ byte[] data = password.getBytes("utf-8");
MessageDigest md = MessageDigest.getInstance("MD5");
@@ -55,24 +60,8 @@ public class Passwd
byte[] encoded = b64.encode(digest);
- output(args[0], encoded);
+ String encodedStr = new String(encoded, Charset.forName("utf-8"));
+ return userName + ":" + encodedStr;
}
- private static void output(String user, byte[] encoded) throws IOException
- {
- PrintStream ps = new PrintStream(System.out);
-
- user += ":";
- ps.write(user.getBytes("utf-8"));
-
- for (byte b : encoded)
- {
- ps.write(b);
- }
-
- ps.println();
-
- ps.flush();
- ps.close();
- }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java
index eea8e173f4..3e4c30291c 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java
@@ -165,6 +165,11 @@ public class MainTest extends QpidTestCase
_options = options;
}
+ @Override
+ protected void setExceptionHandler()
+ {
+ }
+
public BrokerOptions getOptions()
{
return _options;
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
index 7739f9976e..eb4a90d9f3 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
@@ -600,19 +600,6 @@ public class ServerConfigurationTest extends QpidTestCase
assertEquals("a", _serverConfig.getConnectorCertType());
}
- public void testGetUseBiasedWrites() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getUseBiasedWrites());
-
- // Check value we set
- _config.setProperty("advanced.useWriteBiasedPool", true);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getUseBiasedWrites());
- }
-
public void testGetHousekeepingCheckPeriod() throws ConfigurationException
{
// Check default
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
index a0a29cf734..7bd711a19c 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
@@ -72,7 +72,7 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
/**
* Not used in this test, just there to stub out the routing calls
*/
- private MessageStore _store = new MemoryMessageStore();
+ private MemoryMessageStore _store = new MemoryMessageStore();
BindingFactory bindingFactory = new BindingFactory(new DurableConfigurationStore.Source()
@@ -310,7 +310,7 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
* @throws AMQException
*/
@Override
- public void enqueue(ServerMessage msg, PostEnqueueAction action) throws AMQException
+ public void enqueue(ServerMessage msg, boolean sync, PostEnqueueAction action) throws AMQException
{
messages.add( new HeadersExchangeTest.Message((AMQMessage) msg));
final QueueEntry queueEntry = new QueueEntry()
@@ -318,47 +318,47 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
public AMQQueue getQueue()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public AMQMessage getMessage()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public long getSize()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public boolean getDeliveredToConsumer()
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public boolean expired() throws AMQException
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public boolean isAvailable()
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public boolean isAcquired()
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public boolean acquire()
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public boolean acquire(Subscription sub)
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public boolean delete()
@@ -373,17 +373,17 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
public boolean acquiredBySubscription()
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public boolean isAcquiredBy(Subscription subscription)
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public void release()
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public boolean releaseButRetain()
@@ -393,42 +393,42 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
public boolean immediateAndNotDelivered()
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public void setRedelivered()
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public AMQMessageHeader getMessageHeader()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public boolean isPersistent()
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public boolean isRedelivered()
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public Subscription getDeliveredSubscription()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public void reject()
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public boolean isRejectedBy(long subscriptionId)
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public void requeue(Subscription subscription)
@@ -438,42 +438,42 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
public void dequeue()
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public void dispose()
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public void discard()
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public void routeToAlternate()
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public boolean isQueueDeleted()
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public void addStateChangeListener(StateChangeListener listener)
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public boolean removeStateChangeListener(StateChangeListener listener)
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public int compareTo(final QueueEntry o)
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public boolean isDequeued()
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/CurrentActorTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/CurrentActorTest.java
index 32ad1d110d..9a065ea2db 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/CurrentActorTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/CurrentActorTest.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server.logging.actors;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.qpid.AMQException;
import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.logging.NullRootMessageLogger;
/**
@@ -49,10 +50,7 @@ import org.apache.qpid.server.logging.NullRootMessageLogger;
public class CurrentActorTest extends BaseConnectionActorTestCase
{
//Set this to be a reasonably large number
- int THREADS = 10;
-
- // Record any exceptions that are thrown by the threads
- Exception[] _errors = new Exception[THREADS];
+ private static final int THREADS = 10;
/**
* Test that CurrentActor behaves as LIFO queue.
@@ -161,19 +159,11 @@ public class CurrentActorTest extends BaseConnectionActorTestCase
public void testThreadLocal()
{
- new Runnable(){
- public void run()
- {
- System.out.println(_errors[0]);
- }
- };
-
// Setup the threads
- Thread[] threads = new Thread[THREADS];
+ LogMessagesWithAConnectionActor[] threads = new LogMessagesWithAConnectionActor[THREADS];
for (int count = 0; count < THREADS; count++)
{
- Runnable test = new LogMessagesWithAConnectionActor(count);
- threads[count] = new Thread(test);
+ threads[count] = new LogMessagesWithAConnectionActor();
}
//Run the threads
@@ -198,10 +188,10 @@ public class CurrentActorTest extends BaseConnectionActorTestCase
// Verify that none of the tests threw an exception
for (int count = 0; count < THREADS; count++)
{
- if (_errors[count] != null)
+ if (threads[count].getException() != null)
{
- _errors[count].printStackTrace();
- fail("Error occured in thread:" + count);
+ threads[count].getException().printStackTrace();
+ fail("Error occured in thread:" + count + "("+threads[count].getException()+")");
}
}
}
@@ -210,13 +200,12 @@ public class CurrentActorTest extends BaseConnectionActorTestCase
* Creates a new ConnectionActor and logs the given number of messages
* before removing the actor and validating that there is no set actor.
*/
- public class LogMessagesWithAConnectionActor implements Runnable
+ public class LogMessagesWithAConnectionActor extends Thread
{
- int count;
+ Throwable _exception;
- LogMessagesWithAConnectionActor(int count)
+ public LogMessagesWithAConnectionActor()
{
- this.count = count;
}
public void run()
@@ -227,6 +216,7 @@ public class CurrentActorTest extends BaseConnectionActorTestCase
//fixme reminder that we need a better approach for broker testing.
try
{
+ LogActor defaultActor = CurrentActor.get();
AMQPConnectionActor actor = new AMQPConnectionActor(getSession(),
new NullRootMessageLogger());
@@ -237,20 +227,26 @@ public class CurrentActorTest extends BaseConnectionActorTestCase
sendTestLogMessage(CurrentActor.get());
// Verify it was the same actor as we set earlier
- assertEquals("Retrieved actor is not as expected ",
- actor, CurrentActor.get());
+ if(!actor.equals(CurrentActor.get()))
+ throw new IllegalArgumentException("Retrieved actor is not as expected ");
// Verify that removing the actor works for this thread
CurrentActor.remove();
- assertNull("CurrentActor should be null", CurrentActor.get());
+ if(CurrentActor.get() != defaultActor)
+ throw new IllegalArgumentException("CurrentActor ("+CurrentActor.get()+") should be default actor" + defaultActor);
}
- catch (Exception e)
+ catch (Throwable e)
{
- _errors[count] = e;
+ _exception = e;
}
}
+
+ public Throwable getException()
+ {
+ return _exception;
+ }
}
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java
index 2ce43052d9..d5f8ef3d54 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java
@@ -64,17 +64,17 @@ public class AMQPriorityQueueTest extends SimpleAMQQueueTest
ArrayList<QueueEntry> msgs = _subscription.getMessages();
try
{
- assertEquals(new Long(1L), msgs.get(0).getMessage().getMessageNumber());
- assertEquals(new Long(6L), msgs.get(1).getMessage().getMessageNumber());
- assertEquals(new Long(8L), msgs.get(2).getMessage().getMessageNumber());
+ assertEquals(1L, msgs.get(0).getMessage().getMessageNumber());
+ assertEquals(6L, msgs.get(1).getMessage().getMessageNumber());
+ assertEquals(8L, msgs.get(2).getMessage().getMessageNumber());
- assertEquals(new Long(2L), msgs.get(3).getMessage().getMessageNumber());
- assertEquals(new Long(5L), msgs.get(4).getMessage().getMessageNumber());
- assertEquals(new Long(7L), msgs.get(5).getMessage().getMessageNumber());
+ assertEquals(2L, msgs.get(3).getMessage().getMessageNumber());
+ assertEquals(5L, msgs.get(4).getMessage().getMessageNumber());
+ assertEquals(7L, msgs.get(5).getMessage().getMessageNumber());
- assertEquals(new Long(3L), msgs.get(6).getMessage().getMessageNumber());
- assertEquals(new Long(4L), msgs.get(7).getMessage().getMessageNumber());
- assertEquals(new Long(9L), msgs.get(8).getMessage().getMessageNumber());
+ assertEquals(3L, msgs.get(6).getMessage().getMessageNumber());
+ assertEquals(4L, msgs.get(7).getMessage().getMessageNumber());
+ assertEquals(9L, msgs.get(8).getMessage().getMessageNumber());
}
catch (AssertionFailedError afe)
{
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java
index 0daf79122c..f97ac5659e 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java
@@ -30,7 +30,6 @@ import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.security.AuthorizationHolder;
-import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.txn.ServerTransaction;
@@ -168,22 +167,22 @@ public class MockAMQQueue implements AMQQueue
public UUID getId()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public QueueConfigType getConfigType()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public ConfiguredObject getParent()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public boolean isDurable()
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public boolean isAutoDelete()
@@ -199,7 +198,7 @@ public class MockAMQQueue implements AMQQueue
public AMQShortString getOwner()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public void setVirtualHost(VirtualHost virtualhost)
@@ -219,22 +218,22 @@ public class MockAMQQueue implements AMQQueue
public void registerSubscription(Subscription subscription, boolean exclusive) throws AMQException
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public void unregisterSubscription(Subscription subscription) throws AMQException
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public int getConsumerCount()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public int getActiveConsumerCount()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public boolean hasExclusiveSubscriber()
@@ -244,37 +243,37 @@ public class MockAMQQueue implements AMQQueue
public boolean isUnused()
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public boolean isEmpty()
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public int getMessageCount()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public int getUndeliveredMessageCount()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public long getQueueDepth()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public long getReceivedMessageCount()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public long getOldestMessageArrivalTime()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public boolean isDeleted()
@@ -297,59 +296,58 @@ public class MockAMQQueue implements AMQQueue
}
+ public void enqueue(ServerMessage message, boolean sync, PostEnqueueAction action) throws AMQException
+ {
+ }
+
public void requeue(QueueEntry entry)
{
- //To change body of implemented methods use File | Settings | File Templates.
}
public void requeue(QueueEntryImpl storeContext, Subscription subscription)
{
- //To change body of implemented methods use File | Settings | File Templates.
}
public void dequeue(QueueEntry entry, Subscription sub)
{
- //To change body of implemented methods use File | Settings | File Templates.
}
public boolean resend(QueueEntry entry, Subscription subscription) throws AMQException
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public void addQueueDeleteTask(Task task)
{
- //To change body of implemented methods use File | Settings | File Templates.
}
public void removeQueueDeleteTask(final Task task)
{
- //To change body of implemented methods use File | Settings | File Templates.
}
public List<QueueEntry> getMessagesOnTheQueue()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public List<QueueEntry> getMessagesOnTheQueue(long fromMessageId, long toMessageId)
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public List<Long> getMessagesOnTheQueue(int num)
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public List<Long> getMessagesOnTheQueue(int num, int offest)
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public QueueEntry getMessageOnTheQueue(long messageId)
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public List<QueueEntry> getMessagesRangeOnTheQueue(long fromPosition, long toPosition)
@@ -359,146 +357,137 @@ public class MockAMQQueue implements AMQQueue
public void moveMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName, ServerTransaction storeContext)
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public void copyMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName, ServerTransaction storeContext)
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public void removeMessagesFromQueue(long fromMessageId, long toMessageId)
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public long getMaximumMessageSize()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public void setMaximumMessageSize(long value)
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public long getMaximumMessageCount()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public void setMaximumMessageCount(long value)
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public long getMaximumQueueDepth()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public void setMaximumQueueDepth(long value)
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public long getMaximumMessageAge()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public void setMaximumMessageAge(long maximumMessageAge)
{
- //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public boolean getBlockOnQueueFull()
- {
- return false;
- }
-
- public void setBlockOnQueueFull(boolean block)
- {
+
}
public long getMinimumAlertRepeatGap()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public void deleteMessageFromTop()
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public long clearQueue()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public void checkMessageStatus() throws AMQException
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public Set<NotificationCheck> getNotificationChecks()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public void flushSubscription(Subscription sub) throws AMQException
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public void deliverAsync(Subscription sub)
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public void deliverAsync()
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public void stop()
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public boolean isExclusive()
{
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
public Exchange getAlternateExchange()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public void setAlternateExchange(Exchange exchange)
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public Map<String, Object> getArguments()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
- public void checkCapacity(AMQChannel channel)
+ public void checkCapacity(AMQSessionModel channel)
{
}
public ManagedObject getManagedObject()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public int compareTo(AMQQueue o)
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public void setMinimumAlertRepeatGap(long value)
@@ -508,22 +497,22 @@ public class MockAMQQueue implements AMQQueue
public long getCapacity()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public void setCapacity(long capacity)
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public long getFlowResumeCapacity()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public void setFlowResumeCapacity(long flowResumeCapacity)
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public void configure(ConfigurationPlugin config)
@@ -533,7 +522,7 @@ public class MockAMQQueue implements AMQQueue
public ConfigurationPlugin getConfiguration()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public AuthorizationHolder getAuthorizationHolder()
@@ -612,20 +601,20 @@ public class MockAMQQueue implements AMQQueue
}
- @Override
public int getMaximumDeliveryCount()
{
return 0;
}
- @Override
public void setMaximumDeliveryCount(int maximumDeliveryCount)
{
}
- @Override
public void setAlternateExchange(String exchangeName)
{
}
+ public void visit(final Visitor visitor)
+ {
+ }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockStoredMessage.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockStoredMessage.java
index e2418a85be..b4f8c6d07a 100755
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockStoredMessage.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockStoredMessage.java
@@ -23,7 +23,6 @@ package org.apache.qpid.server.queue;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.store.MessageStore;
-import org.apache.qpid.server.store.TransactionLog;
import org.apache.qpid.server.store.StoredMessage;
import org.apache.qpid.server.message.MessageMetaData;
import org.apache.qpid.framing.ContentHeaderBody;
@@ -107,7 +106,17 @@ public class MockStoredMessage implements StoredMessage<MessageMetaData>
return src.limit();
}
- public TransactionLog.StoreFuture flushToStore()
+
+
+ public ByteBuffer getContent(int offsetInMessage, int size)
+ {
+ ByteBuffer buf = ByteBuffer.allocate(size);
+ getContent(offsetInMessage, buf);
+ buf.position(0);
+ return buf;
+ }
+
+ public MessageStore.StoreFuture flushToStore()
{
return MessageStore.IMMEDIATE_FUTURE;
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryListTestBase.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryListTestBase.java
index 7a3f6f701c..cf910208e7 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryListTestBase.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryListTestBase.java
@@ -164,7 +164,7 @@ public abstract class QueueEntryListTestBase extends TestCase
final QueueEntry head = getTestList().getHead();
assertNull("Head entry should not contain an actual message", head.getMessage());
assertEquals("Unexpected message id for first list entry", getExpectedFirstMsgId(), getTestList().next(head)
- .getMessage().getMessageNumber().longValue());
+ .getMessage().getMessageNumber());
}
/**
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
index 6c7094cac0..28d52f4fd1 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
@@ -649,9 +649,7 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
public void onRollback()
{
}
- });
-
-
+ }, 0L);
// Check that it is enqueued
AMQQueue data = _store.getMessages().get(1L);
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java
index f3ba6a5495..a873739ca7 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java
@@ -162,8 +162,8 @@ public class SimpleQueueEntryListTest extends QueueEntryListTestBase
while (entry != null)
{
assertFalse("Entry " + entry.getMessage().getMessageNumber() + " should not have been deleted", entry.isDeleted());
- assertNotNull("QueueEntry was not found in the list of remaining entries",
- remainingMessages.get(entry.getMessage().getMessageNumber().intValue()));
+ assertNotNull("QueueEntry "+entry.getMessage().getMessageNumber()+" was not found in the list of remaining entries " + remainingMessages,
+ remainingMessages.get((int)(entry.getMessage().getMessageNumber())));
count++;
entry = entry.getNextNode();
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SortedQueueEntryListTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SortedQueueEntryListTest.java
index eca845644e..34ad0e5668 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SortedQueueEntryListTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SortedQueueEntryListTest.java
@@ -317,7 +317,7 @@ public class SortedQueueEntryListTest extends QueueEntryListTestBase
assertEquals("Sorted queue entry value is not as expected",
expectedSortKey, entry.getMessage().getMessageHeader().getHeader("KEY"));
assertEquals("Sorted queue entry id is not as expected",
- Long.valueOf(expectedMessageId), entry.getMessage().getMessageNumber());
+ expectedMessageId, entry.getMessage().getMessageNumber());
}
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java
index 1d0a9d6316..90adaa1319 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java
@@ -558,7 +558,7 @@ public class MessageStoreTest extends InternalBrokerBaseCase
/**
* Delete the Store Environment path
*
- * @param configuration The configuration that contains the store environment path.
+ * @param environmentPath The configuration that contains the store environment path.
*/
private void cleanup(File environmentPath)
{
@@ -636,7 +636,7 @@ public class MessageStoreTest extends InternalBrokerBaseCase
{
//To change body of implemented methods use File | Settings | File Templates.
}
- });
+ }, 0L);
}
}
@@ -710,7 +710,7 @@ public class MessageStoreTest extends InternalBrokerBaseCase
if (queue.isDurable() && !queue.isAutoDelete())
{
- getVirtualHost().getMessageStore().createQueue(queue, queueArguments);
+ getVirtualHost().getDurableConfigurationStore().createQueue(queue, queueArguments);
}
}
catch (AMQException e)
@@ -754,7 +754,7 @@ public class MessageStoreTest extends InternalBrokerBaseCase
getVirtualHost().getExchangeRegistry().registerExchange(exchange);
if (durable)
{
- getVirtualHost().getMessageStore().createExchange(exchange);
+ getVirtualHost().getDurableConfigurationStore().createExchange(exchange);
}
}
catch (AMQException e)
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/SkeletonMessageStore.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/SkeletonMessageStore.java
index 5ff84557d8..44006df517 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/SkeletonMessageStore.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/SkeletonMessageStore.java
@@ -26,6 +26,7 @@ import org.apache.qpid.AMQStoreException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.framing.abstraction.ContentChunk;
+import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.message.MessageMetaData;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.exchange.Exchange;
@@ -42,18 +43,11 @@ import java.nio.ByteBuffer;
*/
public class SkeletonMessageStore implements MessageStore
{
- private final AtomicLong _messageId = new AtomicLong(1);
-
- public void configure(String base, Configuration config) throws Exception
- {
- }
-
public void configureConfigStore(String name,
ConfigurationRecoveryHandler recoveryHandler,
Configuration config,
LogSubject logSubject) throws Exception
{
- //To change body of implemented methods use File | Settings | File Templates.
}
public void configureMessageStore(String name,
@@ -61,7 +55,6 @@ public class SkeletonMessageStore implements MessageStore
Configuration config,
LogSubject logSubject) throws Exception
{
- //To change body of implemented methods use File | Settings | File Templates.
}
public void close() throws Exception
@@ -70,31 +63,28 @@ public class SkeletonMessageStore implements MessageStore
public <M extends StorableMessageMetaData> StoredMessage<M> addMessage(M metaData)
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
- public void removeMessage(Long messageId)
- {
- }
public void createExchange(Exchange exchange) throws AMQStoreException
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public void removeExchange(Exchange exchange) throws AMQStoreException
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public void bindQueue(Exchange exchange, AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQStoreException
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public void unbindQueue(Exchange exchange, AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQStoreException
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public void createQueue(AMQQueue queue) throws AMQStoreException
@@ -105,63 +95,11 @@ public class SkeletonMessageStore implements MessageStore
{
}
-
-
-
- public List<AMQQueue> createQueues() throws AMQException
- {
- return null;
- }
-
- public Long getNewMessageId()
- {
- return _messageId.getAndIncrement();
- }
-
- public void storeContentBodyChunk(
- Long messageId,
- int index,
- ContentChunk contentBody,
- boolean lastContentBody) throws AMQException
- {
-
- }
-
- public void storeMessageMetaData(Long messageId, MessageMetaData messageMetaData) throws AMQException
- {
-
- }
-
- public MessageMetaData getMessageMetaData(Long messageId) throws AMQException
- {
- return null;
- }
-
- public ContentChunk getContentBodyChunk(Long messageId, int index) throws AMQException
- {
- return null;
- }
-
public boolean isPersistent()
{
return false;
}
- public void storeMessageHeader(Long messageNumber, ServerMessage message)
- {
- //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void storeContent(Long messageNumber, long offset, ByteBuffer body)
- {
- //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public ServerMessage getMessage(Long messageNumber)
- {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
public void removeQueue(final AMQQueue queue) throws AMQStoreException
{
@@ -172,7 +110,7 @@ public class SkeletonMessageStore implements MessageStore
Configuration storeConfiguration,
LogSubject logSubject) throws Exception
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public Transaction newTransaction()
@@ -180,19 +118,19 @@ public class SkeletonMessageStore implements MessageStore
return new Transaction()
{
- public void enqueueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException
+ public void enqueueMessage(TransactionLogResource queue, EnqueableMessage message) throws AMQStoreException
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
- public void dequeueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException
+ public void dequeueMessage(TransactionLogResource queue, EnqueableMessage message) throws AMQStoreException
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public void commitTran() throws AMQStoreException
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
public StoreFuture commitTranAsync() throws AMQStoreException
@@ -213,7 +151,7 @@ public class SkeletonMessageStore implements MessageStore
public void abortTran() throws AMQStoreException
{
- //To change body of implemented methods use File | Settings | File Templates.
+
}
};
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestMemoryMessageStore.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestMemoryMessageStore.java
index 4dea13d391..fa698f4cf8 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestMemoryMessageStore.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestMemoryMessageStore.java
@@ -82,6 +82,12 @@ public class TestMemoryMessageStore extends MemoryMessageStore
return _storedMessage.getContent(offsetInMessage, dst);
}
+
+ public ByteBuffer getContent(int offsetInMessage, int size)
+ {
+ return _storedMessage.getContent(offsetInMessage, size);
+ }
+
public StoreFuture flushToStore()
{
return _storedMessage.flushToStore();
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestableMemoryMessageStore.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestableMemoryMessageStore.java
index 3593297a05..3804d0dc8e 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestableMemoryMessageStore.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestableMemoryMessageStore.java
@@ -25,6 +25,8 @@ import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.qpid.AMQStoreException;
+import org.apache.qpid.server.message.EnqueableMessage;
+import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.queue.AMQQueue;
/**
@@ -66,14 +68,14 @@ public class TestableMemoryMessageStore extends MemoryMessageStore
private class TestableTransaction implements Transaction
{
- public void enqueueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException
+ public void enqueueMessage(TransactionLogResource queue, EnqueableMessage message) throws AMQStoreException
{
- getMessages().put(messageId, (AMQQueue)queue);
+ getMessages().put(message.getMessageNumber(), (AMQQueue)queue);
}
- public void dequeueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException
+ public void dequeueMessage(TransactionLogResource queue, EnqueableMessage message) throws AMQStoreException
{
- getMessages().remove(messageId);
+ getMessages().remove(message.getMessageNumber());
}
public void commitTran() throws AMQStoreException
@@ -143,6 +145,12 @@ public class TestableMemoryMessageStore extends MemoryMessageStore
return _storedMessage.getContent(offsetInMessage, dst);
}
+
+ public ByteBuffer getContent(int offsetInMessage, int size)
+ {
+ return _storedMessage.getContent(offsetInMessage, size);
+ }
+
public StoreFuture flushToStore()
{
return _storedMessage.flushToStore();
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/AutoCommitTransactionTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/AutoCommitTransactionTest.java
index 9afed49922..98484db264 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/AutoCommitTransactionTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/AutoCommitTransactionTest.java
@@ -29,7 +29,7 @@ import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.MockAMQQueue;
import org.apache.qpid.server.queue.MockQueueEntry;
import org.apache.qpid.server.queue.QueueEntry;
-import org.apache.qpid.server.store.TransactionLog;
+import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.txn.MockStoreTransaction.TransactionState;
import org.apache.qpid.test.utils.QpidTestCase;
@@ -44,7 +44,7 @@ public class AutoCommitTransactionTest extends QpidTestCase
{
private ServerTransaction _transaction = null; // Class under test
- private TransactionLog _transactionLog;
+ private MessageStore _transactionLog;
private AMQQueue _queue;
private List<AMQQueue> _queues;
private Collection<QueueEntry> _queueEntries;
@@ -137,7 +137,7 @@ public class AutoCommitTransactionTest extends QpidTestCase
_message = createTestMessage(false);
_queues = createTestBaseQueues(new boolean[] {false, false, false});
- _transaction.enqueue(_queues, _message, _action);
+ _transaction.enqueue(_queues, _message, _action, 0L);
assertEquals("Enqueue of non-persistent message must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages());
assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
@@ -157,7 +157,7 @@ public class AutoCommitTransactionTest extends QpidTestCase
_message = createTestMessage(true);
_queues = createTestBaseQueues(new boolean[] {false, false, false});
- _transaction.enqueue(_queues, _message, _action);
+ _transaction.enqueue(_queues, _message, _action, 0L);
assertEquals("Enqueue of persistent message to non-durable queues must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages());
assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
@@ -175,7 +175,7 @@ public class AutoCommitTransactionTest extends QpidTestCase
_message = createTestMessage(true);
_queues = createTestBaseQueues(new boolean[] {false, true, false, true});
- _transaction.enqueue(_queues, _message, _action);
+ _transaction.enqueue(_queues, _message, _action, 0L);
assertEquals("Enqueue of persistent message to durable/non-durable queues must cause messages to be enqueued", 2, _storeTransaction.getNumberOfEnqueuedMessages());
assertEquals("Unexpected transaction state", TransactionState.COMMITTED, _storeTransaction.getState());
@@ -198,7 +198,7 @@ public class AutoCommitTransactionTest extends QpidTestCase
try
{
- _transaction.enqueue(_queues, _message, _action);
+ _transaction.enqueue(_queues, _message, _action, 0L);
fail("Exception not thrown");
}
catch (RuntimeException re)
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/LocalTransactionTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/LocalTransactionTest.java
index e81fd8e3f1..484beb8fb4 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/LocalTransactionTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/LocalTransactionTest.java
@@ -29,7 +29,7 @@ import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.MockAMQQueue;
import org.apache.qpid.server.queue.MockQueueEntry;
import org.apache.qpid.server.queue.QueueEntry;
-import org.apache.qpid.server.store.TransactionLog;
+import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.txn.MockStoreTransaction.TransactionState;
import org.apache.qpid.test.utils.QpidTestCase;
@@ -51,7 +51,7 @@ public class LocalTransactionTest extends QpidTestCase
private MockAction _action1;
private MockAction _action2;
private MockStoreTransaction _storeTransaction;
- private TransactionLog _transactionLog;
+ private MessageStore _transactionLog;
@Override
@@ -140,7 +140,7 @@ public class LocalTransactionTest extends QpidTestCase
_message = createTestMessage(false);
_queues = createTestBaseQueues(new boolean[] {false, false, false});
- _transaction.enqueue(_queues, _message, _action1);
+ _transaction.enqueue(_queues, _message, _action1, 0L);
assertEquals("Enqueue of non-persistent message must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages());
assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
@@ -156,7 +156,7 @@ public class LocalTransactionTest extends QpidTestCase
_message = createTestMessage(true);
_queues = createTestBaseQueues(new boolean[] {false, false, false});
- _transaction.enqueue(_queues, _message, _action1);
+ _transaction.enqueue(_queues, _message, _action1, 0L);
assertEquals("Enqueue of persistent message to non-durable queues must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages());
assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
@@ -173,7 +173,7 @@ public class LocalTransactionTest extends QpidTestCase
_message = createTestMessage(true);
_queues = createTestBaseQueues(new boolean[] {false, true, false, true});
- _transaction.enqueue(_queues, _message, _action1);
+ _transaction.enqueue(_queues, _message, _action1, 0L);
assertEquals("Enqueue of persistent message to durable/non-durable queues must cause messages to be enqueued", 2, _storeTransaction.getNumberOfEnqueuedMessages());
assertEquals("Unexpected transaction state", TransactionState.STARTED, _storeTransaction.getState());
@@ -196,7 +196,7 @@ public class LocalTransactionTest extends QpidTestCase
try
{
- _transaction.enqueue(_queues, _message, _action1);
+ _transaction.enqueue(_queues, _message, _action1, 0L);
fail("Exception not thrown");
}
catch (RuntimeException re)
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java
index 1941feb4ef..063023f5b3 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java
@@ -27,11 +27,12 @@ import org.apache.qpid.server.configuration.SessionConfig;
import org.apache.qpid.server.message.AMQMessageHeader;
import org.apache.qpid.server.message.MessageReference;
import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.store.StoredMessage;
/**
* Mock Server Message allowing its persistent flag to be controlled from test.
*/
-class MockServerMessage implements ServerMessage<MockServerMessage>
+class MockServerMessage implements ServerMessage
{
/**
*
@@ -83,6 +84,11 @@ class MockServerMessage implements ServerMessage<MockServerMessage>
throw new NotImplementedException();
}
+ public StoredMessage getStoredMessage()
+ {
+ throw new NotImplementedException();
+ }
+
public long getExpiration()
{
throw new NotImplementedException();
@@ -93,12 +99,18 @@ class MockServerMessage implements ServerMessage<MockServerMessage>
throw new NotImplementedException();
}
+
+ public ByteBuffer getContent(int offset, int size)
+ {
+ throw new NotImplementedException();
+ }
+
public long getArrivalTime()
{
throw new NotImplementedException();
}
- public Long getMessageNumber()
+ public long getMessageNumber()
{
return 0L;
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java
index ff372532ac..bf8fda307a 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java
@@ -24,11 +24,11 @@ import org.apache.commons.configuration.Configuration;
import org.apache.commons.lang.NotImplementedException;
import org.apache.qpid.AMQStoreException;
import org.apache.qpid.server.logging.LogSubject;
-import org.apache.qpid.server.store.TransactionLog;
-import org.apache.qpid.server.store.TransactionLogRecoveryHandler;
-import org.apache.qpid.server.store.TransactionLogResource;
-import org.apache.qpid.server.store.TransactionLog.StoreFuture;
-import org.apache.qpid.server.store.TransactionLog.Transaction;
+import org.apache.qpid.server.message.EnqueableMessage;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.store.*;
+import org.apache.qpid.server.store.MessageStore.StoreFuture;
+import org.apache.qpid.server.store.MessageStore.Transaction;
/**
* Mock implementation of a (Store) Transaction allow its state to be observed.
@@ -61,7 +61,7 @@ class MockStoreTransaction implements Transaction
return _state;
}
- public void enqueueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException
+ public void enqueueMessage(TransactionLogResource queue, EnqueableMessage message) throws AMQStoreException
{
if (_throwExceptionOnQueueOp)
{
@@ -82,7 +82,7 @@ class MockStoreTransaction implements Transaction
return _numberOfEnqueuedMessages;
}
- public void dequeueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException
+ public void dequeueMessage(TransactionLogResource queue, EnqueableMessage message) throws AMQStoreException
{
if (_throwExceptionOnQueueOp)
{
@@ -107,10 +107,33 @@ class MockStoreTransaction implements Transaction
_state = TransactionState.ABORTED;
}
- public static TransactionLog createTestTransactionLog(final MockStoreTransaction storeTransaction)
+ public static MessageStore createTestTransactionLog(final MockStoreTransaction storeTransaction)
{
- return new TransactionLog()
+ return new MessageStore()
{
+ public void configureMessageStore(final String name,
+ final MessageStoreRecoveryHandler recoveryHandler,
+ final Configuration config,
+ final LogSubject logSubject) throws Exception
+ {
+ //TODO.
+ }
+
+ public void close() throws Exception
+ {
+ //TODO.
+ }
+
+ public <T extends StorableMessageMetaData> StoredMessage<T> addMessage(final T metaData)
+ {
+ return null; //TODO.
+ }
+
+ public boolean isPersistent()
+ {
+ return false; //TODO.
+ }
+
public void configureTransactionLog(String name, TransactionLogRecoveryHandler recoveryHandler,
Configuration storeConfiguration, LogSubject logSubject) throws Exception
{
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java
index c0430665d6..b2cdff89ee 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.virtualhost;
+import java.util.Map;
import java.util.UUID;
import org.apache.qpid.server.binding.BindingFactory;
@@ -41,7 +42,6 @@ import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.stats.StatisticsCounter;
import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.store.MessageStore;
-import org.apache.qpid.server.store.TransactionLog;
import org.apache.qpid.server.protocol.v1_0.LinkRegistry;
@@ -66,6 +66,11 @@ public class MockVirtualHost implements VirtualHost
}
+ public BrokerLink createBrokerConnection(final UUID id, final long createTime, final Map<String, String> arguments)
+ {
+ return null;
+ }
+
public IApplicationRegistry getApplicationRegistry()
{
return null;
@@ -161,10 +166,6 @@ public class MockVirtualHost implements VirtualHost
return null;
}
- public TransactionLog getTransactionLog()
- {
- return null;
- }
public void removeBrokerConnection(BrokerLink brokerLink)
{
diff --git a/qpid/java/broker/src/xsl/qmf.xsl b/qpid/java/broker/src/xsl/qmf.xsl
index 3a7e10dac8..1e98c97466 100644
--- a/qpid/java/broker/src/xsl/qmf.xsl
+++ b/qpid/java/broker/src/xsl/qmf.xsl
@@ -288,6 +288,17 @@ public class <xsl:value-of select="$ClassName"/> extends QMFPackage
<xsl:apply-templates select="node()[name()='property' or name()='statistic']" mode="optionalPropertyPresence"/>
<xsl:apply-templates select="node()[name()='property' or name()='statistic']" mode="encodeProperty"/>
}
+
+ public String toString()
+ {
+ return "QMF<xsl:value-of select="@name"/>GetQueryResponseCommand{id=" + getObject().getId()
+<xsl:for-each select="node()[name()='property' or name()='statistic']">
+<xsl:if test="@type!='hilo32' and @type!='mmaTime' ">
+ + ", <xsl:value-of select="@name"/>=" + getObject().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>()
+</xsl:if>
+</xsl:for-each>
+ + "}";
+ }
}
@@ -530,6 +541,11 @@ public class <xsl:value-of select="$ClassName"/> extends QMFPackage
{
return obj.<xsl:value-of select="@name"/>( new <xsl:value-of select="$ClassName"/>ResponseCommandFactory(cmd)<xsl:if test="node()[name()='arg' and ( @dir='I' or @dir='IO' ) ]">, </xsl:if><xsl:apply-templates select="node()[name()='arg' and ( @dir='I' or @dir='IO' ) ]" mode="methodArgList"><xsl:with-param name="prefix">_</xsl:with-param></xsl:apply-templates> );
}
+
+ public String toString()
+ {
+ return "<xsl:value-of select="$ClassName"/>["<xsl:for-each select="node()[name()='arg' and ( @dir='I' or @dir='IO' ) ]"><xsl:if test="preceding-sibling::node()[name()='arg' and ( @dir='I' or @dir='IO' ) ]">+ ", "</xsl:if>+ "<xsl:value-of select="@name"/> = " + _<xsl:value-of select="@name"/> </xsl:for-each>+"]";
+ }
}
public final class <xsl:value-of select="$ClassName"/>ResponseCommandFactory
diff --git a/qpid/java/build.deps b/qpid/java/build.deps
index db28b33b21..c59b9ebaca 100644
--- a/qpid/java/build.deps
+++ b/qpid/java/build.deps
@@ -146,7 +146,7 @@ management-common.test.libs=${test.libs}
ra.libs=${geronimo-j2ee} ${geronimo-jta} ${geronimo-jms} ${slf4j-api} ${geronimo-kernel} ${geronimo-openejb}
# optional bdbstore module deps
-bdb-je=lib/bdbstore/je-4.0.117.jar
+bdb-je=lib/bdbstore/je-5.0.34.jar
bdbstore.libs=${bdb-je}
bdbstore.test.libs=${test.libs}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
index 399534e834..74a0956933 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
@@ -308,7 +308,7 @@ public class AMQConnectionDelegate_8_0 implements AMQConnectionDelegate
{
AMQSession s = (AMQSession) it.next();
// _protocolHandler.addSessionByChannel(s.getChannelId(), s);
- reopenChannel(s.getChannelId(), s.getDefaultPrefetchHigh(), s.getDefaultPrefetchLow(), s.getTransacted());
+ reopenChannel(s.getChannelId(), s.getDefaultPrefetchHigh(), s.getDefaultPrefetchLow(), s.isTransacted());
s.resubscribe();
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
index 1df809c67c..92602ac3a2 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
@@ -829,7 +829,7 @@ public abstract class AMQDestination implements Destination, Referenceable
dest.setSubject(_subject);
dest.setCreate(_create);
dest.setAssert(_assert);
- dest.setDelete(_create);
+ dest.setDelete(_delete);
dest.setBrowseOnly(_browseOnly);
dest.setAddressType(_addressType);
dest.setTargetNode(_targetNode);
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 8984b7ca8c..784b75af10 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
@@ -256,7 +256,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
protected AMQConnection _connection;
/** Used to indicate whether or not this is a transactional session. */
- protected boolean _transacted;
+ protected final boolean _transacted;
/** Holds the sessions acknowledgement mode. */
protected final int _acknowledgeMode;
@@ -371,7 +371,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
* Set when the dispatcher should direct incoming messages straight into the UnackedMessage list instead of
* to the syncRecieveQueue or MessageListener. Used during cleanup, e.g. in Session.recover().
*/
- private volatile boolean _usingDispatcherForCleanup;
+ protected volatile boolean _usingDispatcherForCleanup;
/** Used to indicates that the connection to which this session belongs, has been stopped. */
private boolean _connectionStopped;
@@ -1583,6 +1583,11 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
return _prefetchLowMark;
}
+ public int getPrefetch()
+ {
+ return _prefetchHighMark;
+ }
+
public AMQShortString getDefaultQueueExchangeName()
{
return _connection.getDefaultQueueExchangeName();
@@ -1614,7 +1619,24 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
return _ticket;
}
- public boolean getTransacted()
+ /**
+ * Indicates whether the session is in transacted mode.
+ *
+ * @return true if the session is in transacted mode
+ * @throws IllegalStateException - if session is closed.
+ */
+ public boolean getTransacted() throws JMSException
+ {
+ // Sun TCK checks that javax.jms.IllegalStateException is thrown for closed session
+ // nowhere else this behavior is documented
+ checkNotClosed();
+ return _transacted;
+ }
+
+ /**
+ * Indicates whether the session is in transacted mode.
+ */
+ public boolean isTransacted()
{
return _transacted;
}
@@ -3047,7 +3069,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
*/
public boolean prefetch()
{
- return getAMQConnection().getMaxPrefetch() > 0;
+ return _prefetchHighMark > 0;
}
/** Signifies that the session has pending sends to commit. */
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java
index 756b5cacb0..49b77dcc7b 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java
@@ -30,7 +30,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Queue;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
@@ -60,23 +59,7 @@ import org.apache.qpid.filter.MessageFilter;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.transport.ExchangeBoundResult;
-import org.apache.qpid.transport.ExchangeQueryResult;
-import org.apache.qpid.transport.ExecutionErrorCode;
-import org.apache.qpid.transport.ExecutionException;
-import org.apache.qpid.transport.MessageAcceptMode;
-import org.apache.qpid.transport.MessageAcquireMode;
-import org.apache.qpid.transport.MessageCreditUnit;
-import org.apache.qpid.transport.MessageFlowMode;
-import org.apache.qpid.transport.MessageTransfer;
-import org.apache.qpid.transport.Option;
-import org.apache.qpid.transport.QueueQueryResult;
-import org.apache.qpid.transport.Range;
-import org.apache.qpid.transport.RangeSet;
-import org.apache.qpid.transport.Session;
-import org.apache.qpid.transport.SessionException;
-import org.apache.qpid.transport.SessionListener;
-import org.apache.qpid.transport.TransportException;
+import org.apache.qpid.transport.*;
import org.apache.qpid.util.Serial;
import org.apache.qpid.util.Strings;
import org.slf4j.Logger;
@@ -141,13 +124,13 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
private long maxAckDelay = Long.getLong("qpid.session.max_ack_delay", 1000);
private TimerTask flushTask = null;
- private RangeSet unacked = new RangeSet();
+ private RangeSet unacked = RangeSetFactory.createRangeSet();
private int unackedCount = 0;
/**
* Used to store the range of in tx messages
*/
- private final RangeSet _txRangeSet = new RangeSet();
+ private final RangeSet _txRangeSet = RangeSetFactory.createRangeSet();
private int _txSize = 0;
//--- constructors
@@ -460,7 +443,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
public void sendRecover() throws AMQException, FailoverException
{
// release all unacked messages
- RangeSet all = new RangeSet();
+ RangeSet all = RangeSetFactory.createRangeSet();
RangeSet delivered = gatherRangeSet(_unacknowledgedMessageTags);
RangeSet prefetched = gatherRangeSet(_prefetchedMessageTags);
for (Iterator<Range> deliveredIter = delivered.iterator(); deliveredIter.hasNext();)
@@ -483,7 +466,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
private RangeSet gatherRangeSet(ConcurrentLinkedQueue<Long> messageTags)
{
- RangeSet ranges = new RangeSet();
+ RangeSet ranges = RangeSetFactory.createRangeSet();
while (true)
{
Long tag = messageTags.poll();
@@ -518,7 +501,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
public void rejectMessage(long deliveryTag, boolean requeue)
{
// The value of requeue is always true
- RangeSet ranges = new RangeSet();
+ RangeSet ranges = RangeSetFactory.createRangeSet();
ranges.add((int) deliveryTag);
flushProcessed(ranges, false);
if (requeue)
@@ -812,11 +795,43 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
{
if (suspend)
{
- for (BasicMessageConsumer consumer : _consumers.values())
- {
- getQpidSession().messageStop(String.valueOf(consumer.getConsumerTag()),
- Option.UNRELIABLE);
- }
+ synchronized (getMessageDeliveryLock())
+ {
+ for (BasicMessageConsumer consumer : _consumers.values())
+ {
+ getQpidSession().messageStop(String.valueOf(consumer.getConsumerTag()),
+ Option.UNRELIABLE);
+ sync();
+ List<Long> tags = consumer.drainReceiverQueueAndRetrieveDeliveryTags();
+ _prefetchedMessageTags.addAll(tags);
+ }
+ }
+
+ _usingDispatcherForCleanup = true;
+ syncDispatchQueue();
+ _usingDispatcherForCleanup = false;
+
+ RangeSet delivered = gatherRangeSet(_unacknowledgedMessageTags);
+ RangeSet prefetched = gatherRangeSet(_prefetchedMessageTags);
+ RangeSet all = RangeSetFactory.createRangeSet(delivered.size()
+ + prefetched.size());
+
+ for (Iterator<Range> deliveredIter = delivered.iterator(); deliveredIter.hasNext();)
+ {
+ Range range = deliveredIter.next();
+ all.add(range);
+ }
+
+ for (Iterator<Range> prefetchedIter = prefetched.iterator(); prefetchedIter.hasNext();)
+ {
+ Range range = prefetchedIter.next();
+ all.add(range);
+ }
+
+ flushProcessed(all, false);
+ getQpidSession().messageRelease(delivered,Option.SET_REDELIVERED);
+ getQpidSession().messageRelease(prefetched);
+ sync();
}
else
{
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java
index 96df463481..7daebbff04 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java
@@ -21,6 +21,8 @@
package org.apache.qpid.client;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.ArrayList;
import java.util.Map;
@@ -80,7 +82,7 @@ import org.apache.qpid.transport.TransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, BasicMessageProducer_0_8>
+public class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, BasicMessageProducer_0_8>
{
/** Used for debugging. */
private static final Logger _logger = LoggerFactory.getLogger(AMQSession.class);
@@ -96,8 +98,8 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
* @param defaultPrefetchHighMark The maximum number of messages to prefetched before suspending the session.
* @param defaultPrefetchLowMark The number of prefetched messages at which to resume the session.
*/
- AMQSession_0_8(AMQConnection con, int channelId, boolean transacted, int acknowledgeMode,
- MessageFactoryRegistry messageFactoryRegistry, int defaultPrefetchHighMark, int defaultPrefetchLowMark)
+ protected AMQSession_0_8(AMQConnection con, int channelId, boolean transacted, int acknowledgeMode,
+ MessageFactoryRegistry messageFactoryRegistry, int defaultPrefetchHighMark, int defaultPrefetchLowMark)
{
super(con,channelId,transacted,acknowledgeMode,messageFactoryRegistry,defaultPrefetchHighMark,defaultPrefetchLowMark);
@@ -150,7 +152,7 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
_logger.debug("Sending ack for delivery tag " + deliveryTag + " on channel " + _channelId);
}
- getProtocolHandler().writeFrame(ackFrame);
+ getProtocolHandler().writeFrame(ackFrame, !isTransacted());
_unacknowledgedMessageTags.remove(deliveryTag);
}
@@ -512,7 +514,7 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
// Bounced message is processed here, away from the mina thread
AbstractJMSMessage bouncedMessage =
_messageFactoryRegistry.createMessage(0, false, msg.getExchange(),
- msg.getRoutingKey(), msg.getContentHeader(), msg.getBodies());
+ msg.getRoutingKey(), msg.getContentHeader(), msg.getBodies(),_queueDestinationCache,_topicDestinationCache);
AMQConstant errorCode = AMQConstant.getConstant(msg.getReplyCode());
AMQShortString reason = msg.getReplyText();
_logger.debug("Message returned with error code " + errorCode + " (" + reason + ")");
@@ -572,6 +574,16 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
}, _connection).execute();
}
+ public DestinationCache<AMQQueue> getQueueDestinationCache()
+ {
+ return _queueDestinationCache;
+ }
+
+ public DestinationCache<AMQTopic> getTopicDestinationCache()
+ {
+ return _topicDestinationCache;
+ }
+
class QueueDeclareOkHandler extends SpecificMethodFrameListener
{
@@ -613,12 +625,12 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
return okHandler._messageCount;
}
- protected final boolean tagLE(long tag1, long tag2)
+ protected boolean tagLE(long tag1, long tag2)
{
return tag1 <= tag2;
}
- protected final boolean updateRollbackMark(long currentMark, long deliveryTag)
+ protected boolean updateRollbackMark(long currentMark, long deliveryTag)
{
return false;
}
@@ -695,4 +707,55 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
return null;
}
}
+
+ public abstract static class DestinationCache<T extends AMQDestination>
+ {
+ private final Map<AMQShortString, Map<AMQShortString, T>> cache = new HashMap<AMQShortString, Map<AMQShortString, T>>();
+
+ public T getDestination(AMQShortString exchangeName, AMQShortString routingKey)
+ {
+ Map<AMQShortString, T> routingMap = cache.get(exchangeName);
+ if(routingMap == null)
+ {
+ routingMap = new LinkedHashMap<AMQShortString, T>()
+ {
+
+ protected boolean removeEldestEntry(Map.Entry<AMQShortString, T> eldest)
+ {
+ return size() >= 200;
+ }
+ };
+ cache.put(exchangeName,routingMap);
+ }
+ T destination = routingMap.get(routingKey);
+ if(destination == null)
+ {
+ destination = newDestination(exchangeName, routingKey);
+ routingMap.put(routingKey,destination);
+ }
+ return destination;
+ }
+
+ protected abstract T newDestination(AMQShortString exchangeName, AMQShortString routingKey);
+ }
+
+ private static class TopicDestinationCache extends DestinationCache<AMQTopic>
+ {
+ protected AMQTopic newDestination(AMQShortString exchangeName, AMQShortString routingKey)
+ {
+ return new AMQTopic(exchangeName, routingKey, null);
+ }
+ }
+
+ private static class QueueDestinationCache extends DestinationCache<AMQQueue>
+ {
+ protected AMQQueue newDestination(AMQShortString exchangeName, AMQShortString routingKey)
+ {
+ return new AMQQueue(exchangeName, routingKey, routingKey);
+ }
+ }
+
+ private final TopicDestinationCache _topicDestinationCache = new TopicDestinationCache();
+ private final QueueDestinationCache _queueDestinationCache = new QueueDestinationCache();
+
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java
index bb277887aa..3b6179dd07 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java
@@ -272,10 +272,8 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
*/
private void acknowledgeMessage(final AbstractJMSMessage message) throws AMQException
{
- final RangeSet ranges = new RangeSet();
- ranges.add((int) message.getDeliveryTag());
_0_10session.messageAcknowledge
- (ranges,
+ (Range.newInstance((int) message.getDeliveryTag()),
_acknowledgeMode != org.apache.qpid.jms.Session.NO_ACKNOWLEDGE);
final AMQException amqe = _0_10session.getCurrentException();
@@ -294,9 +292,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
*/
private void flushUnwantedMessage(final AbstractJMSMessage message) throws AMQException
{
- final RangeSet ranges = new RangeSet();
- ranges.add((int) message.getDeliveryTag());
- _0_10session.flushProcessed(ranges,false);
+ _0_10session.flushProcessed(Range.newInstance((int) message.getDeliveryTag()),false);
final AMQException amqe = _0_10session.getCurrentException();
if (amqe != null)
@@ -315,10 +311,8 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
private boolean acquireMessage(final AbstractJMSMessage message) throws AMQException
{
boolean result = false;
- final RangeSet ranges = new RangeSet();
- ranges.add((int) message.getDeliveryTag());
- final Acquired acq = _0_10session.getQpidSession().messageAcquire(ranges).get();
+ final Acquired acq = _0_10session.getQpidSession().messageAcquire(Range.newInstance((int)message.getDeliveryTag())).get();
final RangeSet acquired = acq.getTransfers();
if (acquired != null && acquired.size() > 0)
@@ -451,7 +445,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
{
if (_synchronousQueue.size() > 0)
{
- RangeSet ranges = new RangeSet();
+ RangeSet ranges = RangeSetFactory.createRangeSet();
Iterator iterator = _synchronousQueue.iterator();
while (iterator.hasNext())
{
@@ -551,7 +545,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
}
else if (getSession().prefetch())
{
- capacity = _0_10session.getAMQConnection().getMaxPrefetch();
+ capacity = getSession().getPrefetch();
}
return capacity;
}
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 efcbfd5532..b2f4fcef84 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
@@ -38,11 +38,13 @@ import org.slf4j.LoggerFactory;
public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<UnprocessedMessage_0_8>
{
protected final Logger _logger = LoggerFactory.getLogger(getClass());
+ private AMQSession_0_8.DestinationCache<AMQTopic> _topicDestinationCache;
+ private AMQSession_0_8.DestinationCache<AMQQueue> _queueDestinationCache;
private final RejectBehaviour _rejectBehaviour;
protected BasicMessageConsumer_0_8(int channelId, AMQConnection connection, AMQDestination destination,
- String messageSelector, boolean noLocal, MessageFactoryRegistry messageFactory, AMQSession session,
+ String messageSelector, boolean noLocal, MessageFactoryRegistry messageFactory, AMQSession_0_8 session,
AMQProtocolHandler protocolHandler, FieldTable rawSelector, int prefetchHigh, int prefetchLow,
boolean exclusive, int acknowledgeMode, boolean browseOnly, boolean autoClose) throws JMSException
{
@@ -60,6 +62,9 @@ public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<UnprocessedMe
consumerArguments.put(AMQPFilterTypes.NO_CONSUME.getValue(), Boolean.TRUE);
}
+ _topicDestinationCache = session.getTopicDestinationCache();
+ _queueDestinationCache = session.getQueueDestinationCache();
+
if (destination.getRejectBehaviour() != null)
{
_rejectBehaviour = destination.getRejectBehaviour();
@@ -100,7 +105,8 @@ public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<UnprocessedMe
return _messageFactory.createMessage(messageFrame.getDeliveryTag(),
messageFrame.isRedelivered(), messageFrame.getExchange(),
- messageFrame.getRoutingKey(), messageFrame.getContentHeader(), messageFrame.getBodies());
+ messageFrame.getRoutingKey(), messageFrame.getContentHeader(), messageFrame.getBodies(),
+ _queueDestinationCache, _topicDestinationCache);
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java
index 34d2ade723..b2f998cb2c 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java
@@ -40,6 +40,7 @@ import org.apache.qpid.framing.CompositeAMQDataBlock;
import org.apache.qpid.framing.ContentBody;
import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.framing.ExchangeDeclareBody;
+import org.apache.qpid.framing.MethodRegistry;
public class BasicMessageProducer_0_8 extends BasicMessageProducer
{
@@ -53,15 +54,17 @@ public class BasicMessageProducer_0_8 extends BasicMessageProducer
void declareDestination(AMQDestination destination)
{
- ExchangeDeclareBody body = getSession().getMethodRegistry().createExchangeDeclareBody(_session.getTicket(),
- destination.getExchangeName(),
- destination.getExchangeClass(),
- false,
- false,
- false,
- false,
- true,
- null);
+ final MethodRegistry methodRegistry = getSession().getMethodRegistry();
+ ExchangeDeclareBody body =
+ methodRegistry.createExchangeDeclareBody(_session.getTicket(),
+ destination.getExchangeName(),
+ destination.getExchangeClass(),
+ destination.getExchangeName().toString().startsWith("amq."),
+ false,
+ false,
+ false,
+ true,
+ null);
// Declare the exchange
// Note that the durable and internal arguments are ignored since passive is set to false
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/filter/JMSSelectorFilter.java b/qpid/java/client/src/main/java/org/apache/qpid/client/filter/JMSSelectorFilter.java
new file mode 100644
index 0000000000..14cce0aa59
--- /dev/null
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/filter/JMSSelectorFilter.java
@@ -0,0 +1,209 @@
+/* Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.client.filter;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.qpid.AMQInternalException;
+import org.apache.qpid.client.message.AbstractJMSMessage;
+import org.apache.qpid.filter.FilterableMessage;
+import org.apache.qpid.filter.SelectorParsingException;
+import org.apache.qpid.filter.selector.ParseException;
+import org.apache.qpid.filter.selector.SelectorParser;
+import org.apache.qpid.filter.BooleanExpression;
+import org.apache.qpid.filter.selector.TokenMgrError;
+
+import javax.jms.DeliveryMode;
+import javax.jms.JMSException;
+
+
+public class JMSSelectorFilter implements MessageFilter
+{
+ private static final Logger _logger = LoggerFactory.getLogger(JMSSelectorFilter.class);
+
+ private final String _selector;
+ private final BooleanExpression _matcher;
+
+ public JMSSelectorFilter(String selector) throws AMQInternalException
+ {
+ if (selector == null || "".equals(selector))
+ {
+ throw new IllegalArgumentException("Cannot create a JMSSelectorFilter with a null or empty selector string");
+ }
+ _selector = selector;
+ if (_logger.isDebugEnabled())
+ {
+ _logger.debug("Created JMSSelectorFilter with selector:" + _selector);
+ }
+ try
+ {
+ _matcher = new SelectorParser().parse(selector);
+ }
+ catch (SelectorParsingException e)
+ {
+ throw new AMQInternalException("Unable to parse selector \""+selector+"\"", e);
+ }
+ catch (TokenMgrError e)
+ {
+ throw new AMQInternalException("Unable to parse selector \""+selector+"\"", e);
+ }
+ }
+
+ public boolean matches(AbstractJMSMessage message)
+ {
+ try
+ {
+ boolean match = _matcher.matches(wrap(message));
+ if (_logger.isDebugEnabled())
+ {
+ _logger.debug(message + " match(" + match + ") selector(" + _selector + "): " + _selector);
+ }
+ return match;
+ }
+ catch (SelectorParsingException e)
+ {
+ _logger.warn("Caught exception when evaluating message selector for message " + message, e);
+ }
+ return false;
+ }
+
+ private FilterableMessage wrap(final AbstractJMSMessage message)
+ {
+ return new FilterableMessage()
+ {
+ public boolean isPersistent()
+ {
+ try
+ {
+ return message.getJMSDeliveryMode() == DeliveryMode.PERSISTENT;
+ }
+ catch (JMSException e)
+ {
+ throw new SelectorParsingException(e);
+ }
+ }
+
+ public boolean isRedelivered()
+ {
+ try
+ {
+ return message.getJMSRedelivered();
+ }
+ catch (JMSException e)
+ {
+ throw new SelectorParsingException(e);
+ }
+ }
+
+ public Object getHeader(String name)
+ {
+ try
+ {
+ return message.getObjectProperty(name);
+ }
+ catch (JMSException e)
+ {
+ throw new SelectorParsingException(e);
+ }
+ }
+
+ public String getReplyTo()
+ {
+ return message.getReplyToString();
+ }
+
+ public String getType()
+ {
+ try
+ {
+ return message.getJMSType();
+ }
+ catch (JMSException e)
+ {
+ throw new SelectorParsingException(e);
+ }
+ }
+
+ public byte getPriority()
+ {
+ try
+ {
+ return (byte) message.getJMSPriority();
+ }
+ catch (JMSException e)
+ {
+ throw new SelectorParsingException(e);
+ }
+ }
+
+ public String getMessageId()
+ {
+ try
+ {
+ return message.getJMSMessageID();
+ }
+ catch (JMSException e)
+ {
+ throw new SelectorParsingException(e);
+ }
+ }
+
+ public long getTimestamp()
+ {
+ try
+ {
+ return message.getJMSTimestamp();
+ }
+ catch (JMSException e)
+ {
+ throw new SelectorParsingException(e);
+ }
+ }
+
+ public String getCorrelationId()
+ {
+ try
+ {
+ return message.getJMSCorrelationID();
+ }
+ catch (JMSException e)
+ {
+ throw new SelectorParsingException(e);
+ }
+ }
+
+ public long getExpiration()
+ {
+ try
+ {
+ return message.getJMSExpiration();
+ }
+ catch (JMSException e)
+ {
+ throw new SelectorParsingException(e);
+ }
+ }
+ };
+ }
+
+ public String getSelector()
+ {
+ return _selector;
+ }
+}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/filter/MessageFilter.java b/qpid/java/client/src/main/java/org/apache/qpid/client/filter/MessageFilter.java
index ec0e8ea4c0..fec78d6ba5 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/filter/MessageFilter.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/filter/MessageFilter.java
@@ -15,7 +15,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.qpid.filter;
+package org.apache.qpid.client.filter;
import org.apache.qpid.client.message.AbstractJMSMessage;
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java
index 6237234c4d..33ca584b34 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java
@@ -48,7 +48,10 @@ public class BasicDeliverMethodHandler implements StateAwareMethodListener<Basic
body.getExchange(),
body.getRoutingKey(),
body.getRedelivered());
- _logger.debug("New JmsDeliver method received:" + session);
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("New JmsDeliver method received:" + session);
+ }
session.unprocessedMessageReceived(channelId, msg);
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java
index f360b546b2..179ebd66d1 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java
@@ -124,7 +124,7 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
*/
public static void updateExchangeTypeMapping(Header header, org.apache.qpid.transport.Session session)
{
- DeliveryProperties deliveryProps = header.get(DeliveryProperties.class);
+ DeliveryProperties deliveryProps = header.getDeliveryProperties();
if (deliveryProps != null)
{
String exchange = deliveryProps.getExchange();
@@ -132,7 +132,7 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
}
- MessageProperties msgProps = header.get(MessageProperties.class);
+ MessageProperties msgProps = header.getMessageProperties();
if (msgProps != null && msgProps.getReplyTo() != null)
{
String exchange = msgProps.getReplyTo().getExchange();
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_8.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_8.java
index 9ab03412fe..ab7061c382 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_8.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_8.java
@@ -31,12 +31,7 @@ import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageNotWriteableException;
-import org.apache.qpid.client.AMQDestination;
-import org.apache.qpid.client.AMQQueue;
-import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.client.AMQTopic;
-import org.apache.qpid.client.CustomJMSXProperty;
-import org.apache.qpid.client.JMSAMQException;
+import org.apache.qpid.client.*;
import org.apache.qpid.collections.ReferenceMap;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicContentHeaderProperties;
@@ -81,7 +76,8 @@ public class AMQMessageDelegate_0_8 extends AbstractAMQMessageDelegate
// Used when generating a received message object
protected AMQMessageDelegate_0_8(long deliveryTag, BasicContentHeaderProperties contentHeader, AMQShortString exchange,
- AMQShortString routingKey)
+ AMQShortString routingKey, AMQSession_0_8.DestinationCache<AMQQueue> queueDestinationCache,
+ AMQSession_0_8.DestinationCache<AMQTopic> topicDestinationCache)
{
this(contentHeader, deliveryTag);
@@ -95,10 +91,10 @@ public class AMQMessageDelegate_0_8 extends AbstractAMQMessageDelegate
switch (type.intValue())
{
case AMQDestination.QUEUE_TYPE:
- dest = new AMQQueue(exchange, routingKey, routingKey);
+ dest = queueDestinationCache.getDestination(exchange, routingKey);
break;
case AMQDestination.TOPIC_TYPE:
- dest = new AMQTopic(exchange, routingKey, null);
+ dest = topicDestinationCache.getDestination(exchange, routingKey);
break;
default:
// Use the generateDestination method
@@ -133,10 +129,66 @@ public class AMQMessageDelegate_0_8 extends AbstractAMQMessageDelegate
{
if (messageId != null)
{
- getContentHeaderProperties().setMessageId("ID:" + messageId);
+ getContentHeaderProperties().setMessageId(asShortStringMsgId(messageId));
}
}
+ private static final byte[] HEX_DIGITS = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
+ 0x61,0x62,0x63,0x64,0x65,0x66};
+
+ private static AMQShortString asShortStringMsgId(UUID messageId)
+ {
+ long msb = messageId.getMostSignificantBits();
+ long lsb = messageId.getLeastSignificantBits();
+
+ byte[] messageIdBytes = new byte[39];
+ messageIdBytes[0] = (byte) 'I';
+ messageIdBytes[1] = (byte) 'D';
+ messageIdBytes[2] = (byte) ':';
+
+ messageIdBytes[3] = HEX_DIGITS[(int)((msb >> 60) & 0xFl)];
+ messageIdBytes[4] = HEX_DIGITS[(int)((msb >> 56) & 0xFl)];
+ messageIdBytes[5] = HEX_DIGITS[(int)((msb >> 52) & 0xFl)];
+ messageIdBytes[6] = HEX_DIGITS[(int)((msb >> 48) & 0xFl)];
+ messageIdBytes[7] = HEX_DIGITS[(int)((msb >> 44) & 0xFl)];
+ messageIdBytes[8] = HEX_DIGITS[(int)((msb >> 40) & 0xFl)];
+ messageIdBytes[9] = HEX_DIGITS[(int)((msb >> 36) & 0xFl)];
+ messageIdBytes[10] = HEX_DIGITS[(int)((msb >> 32) & 0xFl)];
+
+ messageIdBytes[11] = (byte) '-';
+ messageIdBytes[12] = HEX_DIGITS[(int)((msb >> 28) & 0xFl)];
+ messageIdBytes[13] = HEX_DIGITS[(int)((msb >> 24) & 0xFl)];
+ messageIdBytes[14] = HEX_DIGITS[(int)((msb >> 20) & 0xFl)];
+ messageIdBytes[15] = HEX_DIGITS[(int)((msb >> 16) & 0xFl)];
+ messageIdBytes[16] = (byte) '-';
+ messageIdBytes[17] = HEX_DIGITS[(int)((msb >> 12) & 0xFl)];
+ messageIdBytes[18] = HEX_DIGITS[(int)((msb >> 8) & 0xFl)];
+ messageIdBytes[19] = HEX_DIGITS[(int)((msb >> 4) & 0xFl)];
+ messageIdBytes[20] = HEX_DIGITS[(int)(msb & 0xFl)];
+ messageIdBytes[21] = (byte) '-';
+
+ messageIdBytes[22] = HEX_DIGITS[(int)((lsb >> 60) & 0xFl)];
+ messageIdBytes[23] = HEX_DIGITS[(int)((lsb >> 56) & 0xFl)];
+ messageIdBytes[24] = HEX_DIGITS[(int)((lsb >> 52) & 0xFl)];
+ messageIdBytes[25] = HEX_DIGITS[(int)((lsb >> 48) & 0xFl)];
+
+ messageIdBytes[26] = (byte) '-';
+
+ messageIdBytes[27] = HEX_DIGITS[(int)((lsb >> 44) & 0xFl)];
+ messageIdBytes[28] = HEX_DIGITS[(int)((lsb >> 40) & 0xFl)];
+ messageIdBytes[29] = HEX_DIGITS[(int)((lsb >> 36) & 0xFl)];
+ messageIdBytes[30] = HEX_DIGITS[(int)((lsb >> 32) & 0xFl)];
+ messageIdBytes[31] = HEX_DIGITS[(int)((lsb >> 28) & 0xFl)];
+ messageIdBytes[32] = HEX_DIGITS[(int)((lsb >> 24) & 0xFl)];
+ messageIdBytes[33] = HEX_DIGITS[(int)((lsb >> 20) & 0xFl)];
+ messageIdBytes[34] = HEX_DIGITS[(int)((lsb >> 16) & 0xFl)];
+ messageIdBytes[35] = HEX_DIGITS[(int)((lsb >> 12) & 0xFl)];
+ messageIdBytes[36] = HEX_DIGITS[(int)((lsb >> 8) & 0xFl)];
+ messageIdBytes[37] = HEX_DIGITS[(int)((lsb >> 4) & 0xFl)];
+ messageIdBytes[38] = HEX_DIGITS[(int)(lsb & 0xFl)];
+
+ return new AMQShortString(messageIdBytes,0,39);
+ }
public long getJMSTimestamp() throws JMSException
{
@@ -413,7 +465,7 @@ public class AMQMessageDelegate_0_8 extends AbstractAMQMessageDelegate
}
checkWritableProperties();
- getJmsHeaders().setByte(propertyName, new Byte(b));
+ getJmsHeaders().setByte(propertyName, b);
}
public void setShortProperty(String propertyName, short i) throws JMSException
@@ -424,13 +476,13 @@ public class AMQMessageDelegate_0_8 extends AbstractAMQMessageDelegate
}
checkWritableProperties();
- getJmsHeaders().setShort(propertyName, new Short(i));
+ getJmsHeaders().setShort(propertyName, i);
}
public void setIntProperty(String propertyName, int i) throws JMSException
{
checkWritableProperties();
- getJmsHeaders().setInteger(propertyName, new Integer(i));
+ getJmsHeaders().setInteger(propertyName, i);
}
public void setLongProperty(String propertyName, long l) throws JMSException
@@ -441,7 +493,7 @@ public class AMQMessageDelegate_0_8 extends AbstractAMQMessageDelegate
}
checkWritableProperties();
- getJmsHeaders().setLong(propertyName, new Long(l));
+ getJmsHeaders().setLong(propertyName, l);
}
public void setFloatProperty(String propertyName, float f) throws JMSException
@@ -452,7 +504,7 @@ public class AMQMessageDelegate_0_8 extends AbstractAMQMessageDelegate
}
checkWritableProperties();
- getJmsHeaders().setFloat(propertyName, new Float(f));
+ getJmsHeaders().setFloat(propertyName, f);
}
public void setDoubleProperty(String propertyName, double v) throws JMSException
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java
index 967a1fb49f..16b71db77e 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java
@@ -21,6 +21,9 @@
package org.apache.qpid.client.message;
import org.apache.qpid.AMQException;
+import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.client.AMQSession_0_8;
+import org.apache.qpid.client.AMQTopic;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.ContentBody;
import org.apache.qpid.framing.ContentHeaderBody;
@@ -44,7 +47,9 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory
protected AbstractJMSMessage create08MessageWithBody(long messageNbr, ContentHeaderBody contentHeader,
AMQShortString exchange, AMQShortString routingKey,
- List bodies) throws AMQException
+ List bodies,
+ AMQSession_0_8.DestinationCache<AMQQueue> queueDestinationCache,
+ AMQSession_0_8.DestinationCache<AMQTopic> topicDestinationCache) throws AMQException
{
ByteBuffer data;
final boolean debug = _logger.isDebugEnabled();
@@ -99,7 +104,7 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory
AMQMessageDelegate delegate = new AMQMessageDelegate_0_8(messageNbr,
(BasicContentHeaderProperties) contentHeader.getProperties(),
- exchange, routingKey);
+ exchange, routingKey, queueDestinationCache, topicDestinationCache);
return createMessage(delegate, data);
}
@@ -149,10 +154,12 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory
public AbstractJMSMessage createMessage(long messageNbr, boolean redelivered, ContentHeaderBody contentHeader,
- AMQShortString exchange, AMQShortString routingKey, List bodies)
+ AMQShortString exchange, AMQShortString routingKey, List bodies,
+ AMQSession_0_8.DestinationCache<AMQQueue> queueDestinationCache,
+ AMQSession_0_8.DestinationCache<AMQTopic> topicDestinationCache)
throws JMSException, AMQException
{
- final AbstractJMSMessage msg = create08MessageWithBody(messageNbr, contentHeader, exchange, routingKey, bodies);
+ final AbstractJMSMessage msg = create08MessageWithBody(messageNbr, contentHeader, exchange, routingKey, bodies, queueDestinationCache, topicDestinationCache);
msg.setJMSRedelivered(redelivered);
msg.setReceivedFromServer();
return msg;
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java
index c981c951c3..7f733b9644 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java
@@ -29,6 +29,7 @@ import javax.jms.ObjectMessage;
import org.apache.qpid.AMQException;
import org.apache.qpid.client.util.ClassLoadingAwareObjectInputStream;
+import org.apache.qpid.util.ByteBufferInputStream;
public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessage
{
@@ -62,26 +63,7 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
try
{
- ClassLoadingAwareObjectInputStream in = new ClassLoadingAwareObjectInputStream(new InputStream()
- {
-
-
- @Override
- public int read() throws IOException
- {
- return data.get();
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException
- {
- len = data.remaining() < len ? data.remaining() : len;
- data.get(b, off, len);
- return len;
- }
- });
-
- _readData = (Serializable) in.readObject();
+ _readData = read(data);
}
catch (IOException e)
{
@@ -93,7 +75,6 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
}
}
-
public void clearBody() throws JMSException
{
super.clearBody();
@@ -189,24 +170,7 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
final ByteBuffer data = _data.duplicate();
try
{
- ClassLoadingAwareObjectInputStream in = new ClassLoadingAwareObjectInputStream(new InputStream()
- {
- @Override
- public int read() throws IOException
- {
- return data.get();
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException
- {
- len = data.remaining() < len ? data.remaining() : len;
- data.get(b, off, len);
- return len;
- }
- });
-
- return (Serializable) in.readObject();
+ return read(data);
}
catch (ClassNotFoundException e)
{
@@ -224,4 +188,14 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
}
+ private Serializable read(final ByteBuffer data) throws IOException, ClassNotFoundException
+ {
+ Serializable result = null;
+ if (data != null && data.hasRemaining())
+ {
+ ClassLoadingAwareObjectInputStream in = new ClassLoadingAwareObjectInputStream(new ByteBufferInputStream(data));
+ result = (Serializable) in.readObject();
+ }
+ return result;
+ }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactory.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactory.java
index f3d96cd855..93c2872b2e 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactory.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactory.java
@@ -25,6 +25,9 @@ import java.util.List;
import javax.jms.JMSException;
import org.apache.qpid.AMQException;
+import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.client.AMQSession_0_8;
+import org.apache.qpid.client.AMQTopic;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.transport.DeliveryProperties;
@@ -36,7 +39,7 @@ public interface MessageFactory
AbstractJMSMessage createMessage(long deliveryTag, boolean redelivered,
ContentHeaderBody contentHeader,
AMQShortString exchange, AMQShortString routingKey,
- List bodies)
+ List bodies, AMQSession_0_8.DestinationCache<AMQQueue> queueDestinationCache, AMQSession_0_8.DestinationCache<AMQTopic> topicDestinationCache)
throws JMSException, AMQException;
AbstractJMSMessage createMessage(long deliveryTag, boolean redelivered,
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java
index cdb75fc9a9..15ad3ed89f 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java
@@ -28,6 +28,9 @@ import java.nio.ByteBuffer;
import javax.jms.JMSException;
import org.apache.qpid.AMQException;
+import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.client.AMQSession_0_8;
+import org.apache.qpid.client.AMQTopic;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicContentHeaderProperties;
import org.apache.qpid.framing.ContentHeaderBody;
@@ -93,15 +96,19 @@ public class MessageFactoryRegistry
* Create a message. This looks up the MIME type from the content header and instantiates the appropriate
* concrete message type.
*
+ *
* @param deliveryTag the AMQ message id
* @param redelivered true if redelivered
* @param contentHeader the content header that was received
* @param bodies a list of ContentBody instances @return the message.
- * @throws AMQException
+ * @param queueDestinationCache
+ *@param topicDestinationCache @throws AMQException
* @throws JMSException
*/
public AbstractJMSMessage createMessage(long deliveryTag, boolean redelivered, AMQShortString exchange,
- AMQShortString routingKey, ContentHeaderBody contentHeader, List bodies)
+ AMQShortString routingKey, ContentHeaderBody contentHeader, List bodies,
+ AMQSession_0_8.DestinationCache<AMQQueue> queueDestinationCache,
+ AMQSession_0_8.DestinationCache<AMQTopic> topicDestinationCache)
throws AMQException, JMSException
{
BasicContentHeaderProperties properties = (BasicContentHeaderProperties) contentHeader.getProperties();
@@ -118,13 +125,13 @@ public class MessageFactoryRegistry
mf = _default;
}
- return mf.createMessage(deliveryTag, redelivered, contentHeader, exchange, routingKey, bodies);
+ return mf.createMessage(deliveryTag, redelivered, contentHeader, exchange, routingKey, bodies, queueDestinationCache, topicDestinationCache);
}
public AbstractJMSMessage createMessage(MessageTransfer transfer) throws AMQException, JMSException
{
- MessageProperties mprop = transfer.getHeader().get(MessageProperties.class);
+ MessageProperties mprop = transfer.getHeader().getMessageProperties();
String messageType = "";
if ( mprop == null || mprop.getContentType() == null)
{
@@ -143,7 +150,7 @@ public class MessageFactoryRegistry
boolean redelivered = false;
DeliveryProperties deliverProps;
- if((deliverProps = transfer.getHeader().get(DeliveryProperties.class)) != null)
+ if((deliverProps = transfer.getHeader().getDeliveryProperties()) != null)
{
redelivered = deliverProps.getRedelivered();
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java
index 284954edba..8911d4ee3e 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.client.protocol;
+import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -409,10 +410,10 @@ public class AMQProtocolHandler implements ProtocolEngine
final ArrayList<AMQDataBlock> dataBlocks = _codecFactory.getDecoder().decodeBuffer(msg);
// Decode buffer
-
- for (AMQDataBlock message : dataBlocks)
+ int size = dataBlocks.size();
+ for (int i = 0; i < size; i++)
{
-
+ AMQDataBlock message = dataBlocks.get(i);
if (PROTOCOL_DEBUG)
{
_protocolLogger.info(String.format("RECV: [%s] %s", this, message));
@@ -420,10 +421,10 @@ public class AMQProtocolHandler implements ProtocolEngine
if(message instanceof AMQFrame)
{
- final boolean debug = _logger.isDebugEnabled();
+
final long msgNumber = ++_messageReceivedCount;
- if (debug && ((msgNumber % 1000) == 0))
+ if (((msgNumber % 1000) == 0) && _logger.isDebugEnabled())
{
_logger.debug("Received " + _messageReceivedCount + " protocol messages");
}
@@ -514,12 +515,20 @@ public class AMQProtocolHandler implements ProtocolEngine
return getStateManager().createWaiter(states);
}
- public synchronized void writeFrame(AMQDataBlock frame)
+ public void writeFrame(AMQDataBlock frame)
+ {
+ writeFrame(frame, true);
+ }
+
+ public synchronized void writeFrame(AMQDataBlock frame, boolean flush)
{
final ByteBuffer buf = asByteBuffer(frame);
_writtenBytes += buf.remaining();
_sender.send(buf);
- _sender.flush();
+ if(flush)
+ {
+ _sender.flush();
+ }
if (PROTOCOL_DEBUG)
{
@@ -539,35 +548,51 @@ public class AMQProtocolHandler implements ProtocolEngine
}
+ private static final int REUSABLE_BYTE_BUFFER_CAPACITY = 65 * 1024;
+ private final byte[] _reusableBytes = new byte[REUSABLE_BYTE_BUFFER_CAPACITY];
+ private final ByteBuffer _reusableByteBuffer = ByteBuffer.wrap(_reusableBytes);
+ private final BytesDataOutput _reusableDataOutput = new BytesDataOutput(_reusableBytes);
+
private ByteBuffer asByteBuffer(AMQDataBlock block)
{
- final ByteBuffer buf = ByteBuffer.allocate((int) block.getSize());
+ final int size = (int) block.getSize();
- try
- {
- block.writePayload(new DataOutputStream(new OutputStream()
- {
+ final byte[] data;
- @Override
- public void write(int b) throws IOException
- {
- buf.put((byte) b);
- }
+ if(size > REUSABLE_BYTE_BUFFER_CAPACITY)
+ {
+ data= new byte[size];
+ }
+ else
+ {
- @Override
- public void write(byte[] b, int off, int len) throws IOException
- {
- buf.put(b, off, len);
- }
- }));
+ data = _reusableBytes;
+ }
+ _reusableDataOutput.setBuffer(data);
+
+ try
+ {
+ block.writePayload(_reusableDataOutput);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
- buf.flip();
+ final ByteBuffer buf;
+
+ if(size < REUSABLE_BYTE_BUFFER_CAPACITY)
+ {
+ buf = _reusableByteBuffer;
+ buf.position(0);
+ }
+ else
+ {
+ buf = ByteBuffer.wrap(data);
+ }
+ buf.limit(_reusableDataOutput.length());
+
return buf;
}
@@ -840,4 +865,160 @@ public class AMQProtocolHandler implements ProtocolEngine
return _suggestedProtocolVersion;
}
+ private static class BytesDataOutput implements DataOutput
+ {
+ int _pos = 0;
+ byte[] _buf;
+
+ public BytesDataOutput(byte[] buf)
+ {
+ _buf = buf;
+ }
+
+ public void setBuffer(byte[] buf)
+ {
+ _buf = buf;
+ _pos = 0;
+ }
+
+ public void reset()
+ {
+ _pos = 0;
+ }
+
+ public int length()
+ {
+ return _pos;
+ }
+
+ public void write(int b)
+ {
+ _buf[_pos++] = (byte) b;
+ }
+
+ public void write(byte[] b)
+ {
+ System.arraycopy(b, 0, _buf, _pos, b.length);
+ _pos+=b.length;
+ }
+
+
+ public void write(byte[] b, int off, int len)
+ {
+ System.arraycopy(b, off, _buf, _pos, len);
+ _pos+=len;
+
+ }
+
+ public void writeBoolean(boolean v)
+ {
+ _buf[_pos++] = v ? (byte) 1 : (byte) 0;
+ }
+
+ public void writeByte(int v)
+ {
+ _buf[_pos++] = (byte) v;
+ }
+
+ public void writeShort(int v)
+ {
+ _buf[_pos++] = (byte) (v >>> 8);
+ _buf[_pos++] = (byte) v;
+ }
+
+ public void writeChar(int v)
+ {
+ _buf[_pos++] = (byte) (v >>> 8);
+ _buf[_pos++] = (byte) v;
+ }
+
+ public void writeInt(int v)
+ {
+ _buf[_pos++] = (byte) (v >>> 24);
+ _buf[_pos++] = (byte) (v >>> 16);
+ _buf[_pos++] = (byte) (v >>> 8);
+ _buf[_pos++] = (byte) v;
+ }
+
+ public void writeLong(long v)
+ {
+ _buf[_pos++] = (byte) (v >>> 56);
+ _buf[_pos++] = (byte) (v >>> 48);
+ _buf[_pos++] = (byte) (v >>> 40);
+ _buf[_pos++] = (byte) (v >>> 32);
+ _buf[_pos++] = (byte) (v >>> 24);
+ _buf[_pos++] = (byte) (v >>> 16);
+ _buf[_pos++] = (byte) (v >>> 8);
+ _buf[_pos++] = (byte)v;
+ }
+
+ public void writeFloat(float v)
+ {
+ writeInt(Float.floatToIntBits(v));
+ }
+
+ public void writeDouble(double v)
+ {
+ writeLong(Double.doubleToLongBits(v));
+ }
+
+ public void writeBytes(String s)
+ {
+ int len = s.length();
+ for (int i = 0 ; i < len ; i++)
+ {
+ _buf[_pos++] = ((byte)s.charAt(i));
+ }
+ }
+
+ public void writeChars(String s)
+ {
+ int len = s.length();
+ for (int i = 0 ; i < len ; i++)
+ {
+ int v = s.charAt(i);
+ _buf[_pos++] = (byte) (v >>> 8);
+ _buf[_pos++] = (byte) v;
+ }
+ }
+
+ public void writeUTF(String s)
+ {
+ int strlen = s.length();
+
+ int pos = _pos;
+ _pos+=2;
+
+
+ for (int i = 0; i < strlen; i++)
+ {
+ int c = s.charAt(i);
+ if ((c >= 0x0001) && (c <= 0x007F))
+ {
+ c = s.charAt(i);
+ _buf[_pos++] = (byte) c;
+
+ }
+ else if (c > 0x07FF)
+ {
+ _buf[_pos++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
+ _buf[_pos++] = (byte) (0x80 | ((c >> 6) & 0x3F));
+ _buf[_pos++] = (byte) (0x80 | (c & 0x3F));
+ }
+ else
+ {
+ _buf[_pos++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
+ _buf[_pos++] = (byte) (0x80 | (c & 0x3F));
+ }
+ }
+
+ int len = _pos - (pos + 2);
+
+ _buf[pos++] = (byte) (len >>> 8);
+ _buf[pos] = (byte) len;
+ }
+
+ }
+
+
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/filter/ArithmeticExpression.java b/qpid/java/client/src/main/java/org/apache/qpid/filter/ArithmeticExpression.java
deleted file mode 100644
index a86613f10c..0000000000
--- a/qpid/java/client/src/main/java/org/apache/qpid/filter/ArithmeticExpression.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.filter;
-
-import org.apache.qpid.AMQInternalException;
-import org.apache.qpid.client.message.AbstractJMSMessage;
-
-
-/**
- * An expression which performs an operation on two expression values
- */
-public abstract class ArithmeticExpression extends BinaryExpression
-{
-
- protected static final int INTEGER = 1;
- protected static final int LONG = 2;
- protected static final int DOUBLE = 3;
-
-
- public ArithmeticExpression(Expression left, Expression right)
- {
- super(left, right);
- }
-
- public static Expression createPlus(Expression left, Expression right)
- {
- return new ArithmeticExpression(left, right)
- {
- protected Object evaluate(Object lvalue, Object rvalue)
- {
- if (lvalue instanceof String)
- {
- String text = (String) lvalue;
- return text + rvalue;
- }
- else if (lvalue instanceof Number)
- {
- return plus((Number) lvalue, asNumber(rvalue));
- }
-
- throw new RuntimeException("Cannot call plus operation on: " + lvalue + " and: " + rvalue);
- }
-
- public String getExpressionSymbol()
- {
- return "+";
- }
- };
- }
-
- public static Expression createMinus(Expression left, Expression right)
- {
- return new ArithmeticExpression(left, right)
- {
- protected Object evaluate(Object lvalue, Object rvalue)
- {
- if (lvalue instanceof Number)
- {
- return minus((Number) lvalue, asNumber(rvalue));
- }
-
- throw new RuntimeException("Cannot call minus operation on: " + lvalue + " and: " + rvalue);
- }
-
- public String getExpressionSymbol()
- {
- return "-";
- }
- };
- }
-
- public static Expression createMultiply(Expression left, Expression right)
- {
- return new ArithmeticExpression(left, right)
- {
-
- protected Object evaluate(Object lvalue, Object rvalue)
- {
- if (lvalue instanceof Number)
- {
- return multiply((Number) lvalue, asNumber(rvalue));
- }
-
- throw new RuntimeException("Cannot call multiply operation on: " + lvalue + " and: " + rvalue);
- }
-
- public String getExpressionSymbol()
- {
- return "*";
- }
- };
- }
-
- public static Expression createDivide(Expression left, Expression right)
- {
- return new ArithmeticExpression(left, right)
- {
-
- protected Object evaluate(Object lvalue, Object rvalue)
- {
- if (lvalue instanceof Number)
- {
- return divide((Number) lvalue, asNumber(rvalue));
- }
-
- throw new RuntimeException("Cannot call divide operation on: " + lvalue + " and: " + rvalue);
- }
-
- public String getExpressionSymbol()
- {
- return "/";
- }
- };
- }
-
- public static Expression createMod(Expression left, Expression right)
- {
- return new ArithmeticExpression(left, right)
- {
-
- protected Object evaluate(Object lvalue, Object rvalue)
- {
- if (lvalue instanceof Number)
- {
- return mod((Number) lvalue, asNumber(rvalue));
- }
-
- throw new RuntimeException("Cannot call mod operation on: " + lvalue + " and: " + rvalue);
- }
-
- public String getExpressionSymbol()
- {
- return "%";
- }
- };
- }
-
- protected Number plus(Number left, Number right)
- {
- switch (numberType(left, right))
- {
-
- case ArithmeticExpression.INTEGER:
- return new Integer(left.intValue() + right.intValue());
-
- case ArithmeticExpression.LONG:
- return new Long(left.longValue() + right.longValue());
-
- default:
- return new Double(left.doubleValue() + right.doubleValue());
- }
- }
-
- protected Number minus(Number left, Number right)
- {
- switch (numberType(left, right))
- {
-
- case ArithmeticExpression.INTEGER:
- return new Integer(left.intValue() - right.intValue());
-
- case ArithmeticExpression.LONG:
- return new Long(left.longValue() - right.longValue());
-
- default:
- return new Double(left.doubleValue() - right.doubleValue());
- }
- }
-
- protected Number multiply(Number left, Number right)
- {
- switch (numberType(left, right))
- {
-
- case ArithmeticExpression.INTEGER:
- return new Integer(left.intValue() * right.intValue());
-
- case ArithmeticExpression.LONG:
- return new Long(left.longValue() * right.longValue());
-
- default:
- return new Double(left.doubleValue() * right.doubleValue());
- }
- }
-
- protected Number divide(Number left, Number right)
- {
- return new Double(left.doubleValue() / right.doubleValue());
- }
-
- protected Number mod(Number left, Number right)
- {
- return new Double(left.doubleValue() % right.doubleValue());
- }
-
- private int numberType(Number left, Number right)
- {
- if (isDouble(left) || isDouble(right))
- {
- return ArithmeticExpression.DOUBLE;
- }
- else if ((left instanceof Long) || (right instanceof Long))
- {
- return ArithmeticExpression.LONG;
- }
- else
- {
- return ArithmeticExpression.INTEGER;
- }
- }
-
- private boolean isDouble(Number n)
- {
- return (n instanceof Float) || (n instanceof Double);
- }
-
- protected Number asNumber(Object value)
- {
- if (value instanceof Number)
- {
- return (Number) value;
- }
- else
- {
- throw new RuntimeException("Cannot convert value: " + value + " into a number");
- }
- }
-
- public Object evaluate(AbstractJMSMessage message) throws AMQInternalException
- {
- Object lvalue = left.evaluate(message);
- if (lvalue == null)
- {
- return null;
- }
-
- Object rvalue = right.evaluate(message);
- if (rvalue == null)
- {
- return null;
- }
-
- return evaluate(lvalue, rvalue);
- }
-
- /**
- * @param lvalue
- * @param rvalue
- * @return
- */
- protected abstract Object evaluate(Object lvalue, Object rvalue);
-
-}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/filter/BinaryExpression.java b/qpid/java/client/src/main/java/org/apache/qpid/filter/BinaryExpression.java
deleted file mode 100644
index f97f858fad..0000000000
--- a/qpid/java/client/src/main/java/org/apache/qpid/filter/BinaryExpression.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.filter;
-
-/**
- * An expression which performs an operation on two expression values.
- */
-public abstract class BinaryExpression implements Expression
-{
- protected Expression left;
- protected Expression right;
-
- public BinaryExpression(Expression left, Expression right)
- {
- this.left = left;
- this.right = right;
- }
-
- public Expression getLeft()
- {
- return left;
- }
-
- public Expression getRight()
- {
- return right;
- }
-
- /**
- * @see Object#toString()
- */
- public String toString()
- {
- return "(" + left.toString() + " " + getExpressionSymbol() + " " + right.toString() + ")";
- }
-
- /**
- * TODO: more efficient hashCode()
- *
- * @see Object#hashCode()
- */
- public int hashCode()
- {
- return toString().hashCode();
- }
-
- /**
- * TODO: more efficient hashCode()
- *
- * @see Object#equals(Object)
- */
- public boolean equals(Object o)
- {
-
- if ((o == null) || !this.getClass().equals(o.getClass()))
- {
- return false;
- }
-
- return toString().equals(o.toString());
-
- }
-
- /**
- * Returns the symbol that represents this binary expression. For example, addition is
- * represented by "+"
- *
- * @return
- */
- public abstract String getExpressionSymbol();
-
- /**
- * @param expression
- */
- public void setRight(Expression expression)
- {
- right = expression;
- }
-
- /**
- * @param expression
- */
- public void setLeft(Expression expression)
- {
- left = expression;
- }
-
-}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/filter/ComparisonExpression.java b/qpid/java/client/src/main/java/org/apache/qpid/filter/ComparisonExpression.java
deleted file mode 100644
index 55fca853ef..0000000000
--- a/qpid/java/client/src/main/java/org/apache/qpid/filter/ComparisonExpression.java
+++ /dev/null
@@ -1,589 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.filter;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.regex.Pattern;
-
-import org.apache.qpid.AMQInternalException;
-import org.apache.qpid.client.message.AbstractJMSMessage;
-
-/**
- * A filter performing a comparison of two objects
- */
-public abstract class ComparisonExpression extends BinaryExpression implements BooleanExpression
-{
-
- public static BooleanExpression createBetween(Expression value, Expression left, Expression right)
- {
- return LogicExpression.createAND(ComparisonExpression.createGreaterThanEqual(value, left), ComparisonExpression.createLessThanEqual(value, right));
- }
-
- public static BooleanExpression createNotBetween(Expression value, Expression left, Expression right)
- {
- return LogicExpression.createOR(ComparisonExpression.createLessThan(value, left), ComparisonExpression.createGreaterThan(value, right));
- }
-
- private static final HashSet REGEXP_CONTROL_CHARS = new HashSet();
-
- static
- {
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('.'));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('\\'));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('['));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character(']'));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('^'));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('$'));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('?'));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('*'));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('+'));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('{'));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('}'));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('|'));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('('));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character(')'));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character(':'));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('&'));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('<'));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('>'));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('='));
- ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('!'));
- }
-
- static class LikeExpression extends UnaryExpression implements BooleanExpression
- {
-
- Pattern likePattern;
-
- /**
- * @param right
- */
- public LikeExpression(Expression right, String like, int escape)
- {
- super(right);
-
- StringBuffer regexp = new StringBuffer(like.length() * 2);
- regexp.append("\\A"); // The beginning of the input
- for (int i = 0; i < like.length(); i++)
- {
- char c = like.charAt(i);
- if (escape == (0xFFFF & c))
- {
- i++;
- if (i >= like.length())
- {
- // nothing left to escape...
- break;
- }
-
- char t = like.charAt(i);
- regexp.append("\\x");
- regexp.append(Integer.toHexString(0xFFFF & t));
- }
- else if (c == '%')
- {
- regexp.append(".*?"); // Do a non-greedy match
- }
- else if (c == '_')
- {
- regexp.append("."); // match one
- }
- else if (ComparisonExpression.REGEXP_CONTROL_CHARS.contains(new Character(c)))
- {
- regexp.append("\\x");
- regexp.append(Integer.toHexString(0xFFFF & c));
- }
- else
- {
- regexp.append(c);
- }
- }
-
- regexp.append("\\z"); // The end of the input
-
- likePattern = Pattern.compile(regexp.toString(), Pattern.DOTALL);
- }
-
- /**
- * org.apache.activemq.filter.UnaryExpression#getExpressionSymbol()
- */
- public String getExpressionSymbol()
- {
- return "LIKE";
- }
-
- /**
- * org.apache.activemq.filter.Expression#evaluate(MessageEvaluationContext)
- */
- public Object evaluate(AbstractJMSMessage message) throws AMQInternalException
- {
-
- Object rv = this.getRight().evaluate(message);
-
- if (rv == null)
- {
- return null;
- }
-
- if (!(rv instanceof String))
- {
- return
- Boolean.FALSE;
- // throw new RuntimeException("LIKE can only operate on String identifiers. LIKE attemped on: '" + rv.getClass());
- }
-
- return likePattern.matcher((String) rv).matches() ? Boolean.TRUE : Boolean.FALSE;
- }
-
- public boolean matches(AbstractJMSMessage message) throws AMQInternalException
- {
- Object object = evaluate(message);
-
- return (object != null) && (object == Boolean.TRUE);
- }
- }
-
- public static BooleanExpression createLike(Expression left, String right, String escape)
- {
- if ((escape != null) && (escape.length() != 1))
- {
- throw new RuntimeException(
- "The ESCAPE string litteral is invalid. It can only be one character. Litteral used: " + escape);
- }
-
- int c = -1;
- if (escape != null)
- {
- c = 0xFFFF & escape.charAt(0);
- }
-
- return new LikeExpression(left, right, c);
- }
-
- public static BooleanExpression createNotLike(Expression left, String right, String escape)
- {
- return UnaryExpression.createNOT(ComparisonExpression.createLike(left, right, escape));
- }
-
- public static BooleanExpression createInFilter(Expression left, List elements)
- {
-
- if (!(left instanceof PropertyExpression))
- {
- throw new RuntimeException("Expected a property for In expression, got: " + left);
- }
-
- return UnaryExpression.createInExpression((PropertyExpression) left, elements, false);
-
- }
-
- public static BooleanExpression createNotInFilter(Expression left, List elements)
- {
-
- if (!(left instanceof PropertyExpression))
- {
- throw new RuntimeException("Expected a property for In expression, got: " + left);
- }
-
- return UnaryExpression.createInExpression((PropertyExpression) left, elements, true);
-
- }
-
- public static BooleanExpression createIsNull(Expression left)
- {
- return ComparisonExpression.doCreateEqual(left, ConstantExpression.NULL);
- }
-
- public static BooleanExpression createIsNotNull(Expression left)
- {
- return UnaryExpression.createNOT(ComparisonExpression.doCreateEqual(left, ConstantExpression.NULL));
- }
-
- public static BooleanExpression createNotEqual(Expression left, Expression right)
- {
- return UnaryExpression.createNOT(ComparisonExpression.createEqual(left, right));
- }
-
- public static BooleanExpression createEqual(Expression left, Expression right)
- {
- ComparisonExpression.checkEqualOperand(left);
- ComparisonExpression.checkEqualOperand(right);
- ComparisonExpression.checkEqualOperandCompatability(left, right);
-
- return ComparisonExpression.doCreateEqual(left, right);
- }
-
- private static BooleanExpression doCreateEqual(Expression left, Expression right)
- {
- return new ComparisonExpression(left, right)
- {
-
- public Object evaluate(AbstractJMSMessage message) throws AMQInternalException
- {
- Object lv = left.evaluate(message);
- Object rv = right.evaluate(message);
-
- // Iff one of the values is null
- if ((lv == null) ^ (rv == null))
- {
- return Boolean.FALSE;
- }
-
- if ((lv == rv) || lv.equals(rv))
- {
- return Boolean.TRUE;
- }
-
- if ((lv instanceof Comparable) && (rv instanceof Comparable))
- {
- return compare((Comparable) lv, (Comparable) rv);
- }
-
- return Boolean.FALSE;
- }
-
- protected boolean asBoolean(int answer)
- {
- return answer == 0;
- }
-
- public String getExpressionSymbol()
- {
- return "=";
- }
- };
- }
-
- public static BooleanExpression createGreaterThan(final Expression left, final Expression right)
- {
- ComparisonExpression.checkLessThanOperand(left);
- ComparisonExpression.checkLessThanOperand(right);
-
- return new ComparisonExpression(left, right)
- {
- protected boolean asBoolean(int answer)
- {
- return answer > 0;
- }
-
- public String getExpressionSymbol()
- {
- return ">";
- }
- };
- }
-
- public static BooleanExpression createGreaterThanEqual(final Expression left, final Expression right)
- {
- ComparisonExpression.checkLessThanOperand(left);
- ComparisonExpression.checkLessThanOperand(right);
-
- return new ComparisonExpression(left, right)
- {
- protected boolean asBoolean(int answer)
- {
- return answer >= 0;
- }
-
- public String getExpressionSymbol()
- {
- return ">=";
- }
- };
- }
-
- public static BooleanExpression createLessThan(final Expression left, final Expression right)
- {
- ComparisonExpression.checkLessThanOperand(left);
- ComparisonExpression.checkLessThanOperand(right);
-
- return new ComparisonExpression(left, right)
- {
-
- protected boolean asBoolean(int answer)
- {
- return answer < 0;
- }
-
- public String getExpressionSymbol()
- {
- return "<";
- }
-
- };
- }
-
- public static BooleanExpression createLessThanEqual(final Expression left, final Expression right)
- {
- ComparisonExpression.checkLessThanOperand(left);
- ComparisonExpression.checkLessThanOperand(right);
-
- return new ComparisonExpression(left, right)
- {
-
- protected boolean asBoolean(int answer)
- {
- return answer <= 0;
- }
-
- public String getExpressionSymbol()
- {
- return "<=";
- }
- };
- }
-
- /**
- * Only Numeric expressions can be used in >, >=, < or <= expressions.s
- *
- * @param expr
- */
- public static void checkLessThanOperand(Expression expr)
- {
- if (expr instanceof ConstantExpression)
- {
- Object value = ((ConstantExpression) expr).getValue();
- if (value instanceof Number)
- {
- return;
- }
-
- // Else it's boolean or a String..
- throw new RuntimeException("Value '" + expr + "' cannot be compared.");
- }
-
- if (expr instanceof BooleanExpression)
- {
- throw new RuntimeException("Value '" + expr + "' cannot be compared.");
- }
- }
-
- /**
- * Validates that the expression can be used in == or <> expression.
- * Cannot not be NULL TRUE or FALSE litterals.
- *
- * @param expr
- */
- public static void checkEqualOperand(Expression expr)
- {
- if (expr instanceof ConstantExpression)
- {
- Object value = ((ConstantExpression) expr).getValue();
- if (value == null)
- {
- throw new RuntimeException("'" + expr + "' cannot be compared.");
- }
- }
- }
-
- /**
- *
- * @param left
- * @param right
- */
- private static void checkEqualOperandCompatability(Expression left, Expression right)
- {
- if ((left instanceof ConstantExpression) && (right instanceof ConstantExpression))
- {
- if ((left instanceof BooleanExpression) && !(right instanceof BooleanExpression))
- {
- throw new RuntimeException("'" + left + "' cannot be compared with '" + right + "'");
- }
- }
- }
-
- /**
- * @param left
- * @param right
- */
- public ComparisonExpression(Expression left, Expression right)
- {
- super(left, right);
- }
-
- public Object evaluate(AbstractJMSMessage message) throws AMQInternalException
- {
- Comparable lv = (Comparable) left.evaluate(message);
- if (lv == null)
- {
- return null;
- }
-
- Comparable rv = (Comparable) right.evaluate(message);
- if (rv == null)
- {
- return null;
- }
-
- return compare(lv, rv);
- }
-
- protected Boolean compare(Comparable lv, Comparable rv)
- {
- Class lc = lv.getClass();
- Class rc = rv.getClass();
- // If the the objects are not of the same type,
- // try to convert up to allow the comparison.
- if (lc != rc)
- {
- if (lc == Byte.class)
- {
- if (rc == Short.class)
- {
- lv = new Short(((Number) lv).shortValue());
- }
- else if (rc == Integer.class)
- {
- lv = new Integer(((Number) lv).intValue());
- }
- else if (rc == Long.class)
- {
- lv = new Long(((Number) lv).longValue());
- }
- else if (rc == Float.class)
- {
- lv = new Float(((Number) lv).floatValue());
- }
- else if (rc == Double.class)
- {
- lv = new Double(((Number) lv).doubleValue());
- }
- else
- {
- return Boolean.FALSE;
- }
- }
- else if (lc == Short.class)
- {
- if (rc == Integer.class)
- {
- lv = new Integer(((Number) lv).intValue());
- }
- else if (rc == Long.class)
- {
- lv = new Long(((Number) lv).longValue());
- }
- else if (rc == Float.class)
- {
- lv = new Float(((Number) lv).floatValue());
- }
- else if (rc == Double.class)
- {
- lv = new Double(((Number) lv).doubleValue());
- }
- else
- {
- return Boolean.FALSE;
- }
- }
- else if (lc == Integer.class)
- {
- if (rc == Long.class)
- {
- lv = new Long(((Number) lv).longValue());
- }
- else if (rc == Float.class)
- {
- lv = new Float(((Number) lv).floatValue());
- }
- else if (rc == Double.class)
- {
- lv = new Double(((Number) lv).doubleValue());
- }
- else
- {
- return Boolean.FALSE;
- }
- }
- else if (lc == Long.class)
- {
- if (rc == Integer.class)
- {
- rv = new Long(((Number) rv).longValue());
- }
- else if (rc == Float.class)
- {
- lv = new Float(((Number) lv).floatValue());
- }
- else if (rc == Double.class)
- {
- lv = new Double(((Number) lv).doubleValue());
- }
- else
- {
- return Boolean.FALSE;
- }
- }
- else if (lc == Float.class)
- {
- if (rc == Integer.class)
- {
- rv = new Float(((Number) rv).floatValue());
- }
- else if (rc == Long.class)
- {
- rv = new Float(((Number) rv).floatValue());
- }
- else if (rc == Double.class)
- {
- lv = new Double(((Number) lv).doubleValue());
- }
- else
- {
- return Boolean.FALSE;
- }
- }
- else if (lc == Double.class)
- {
- if (rc == Integer.class)
- {
- rv = new Double(((Number) rv).doubleValue());
- }
- else if (rc == Long.class)
- {
- rv = new Double(((Number) rv).doubleValue());
- }
- else if (rc == Float.class)
- {
- rv = new Float(((Number) rv).doubleValue());
- }
- else
- {
- return Boolean.FALSE;
- }
- }
- else
- {
- return Boolean.FALSE;
- }
- }
-
- return asBoolean(lv.compareTo(rv)) ? Boolean.TRUE : Boolean.FALSE;
- }
-
- protected abstract boolean asBoolean(int answer);
-
- public boolean matches(AbstractJMSMessage message) throws AMQInternalException
- {
- Object object = evaluate(message);
-
- return (object != null) && (object == Boolean.TRUE);
- }
-
-}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/filter/ConstantExpression.java b/qpid/java/client/src/main/java/org/apache/qpid/filter/ConstantExpression.java
deleted file mode 100644
index 3874d13431..0000000000
--- a/qpid/java/client/src/main/java/org/apache/qpid/filter/ConstantExpression.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.filter;
-
-import java.math.BigDecimal;
-
-import org.apache.qpid.AMQInternalException;
-import org.apache.qpid.client.message.AbstractJMSMessage;
-
-/**
- * Represents a constant expression
- */
-public class ConstantExpression implements Expression
-{
-
- static class BooleanConstantExpression extends ConstantExpression implements BooleanExpression
- {
- public BooleanConstantExpression(Object value)
- {
- super(value);
- }
-
- public boolean matches(AbstractJMSMessage message) throws AMQInternalException
- {
- Object object = evaluate(message);
-
- return (object != null) && (object == Boolean.TRUE);
- }
- }
-
- public static final BooleanConstantExpression NULL = new BooleanConstantExpression(null);
- public static final BooleanConstantExpression TRUE = new BooleanConstantExpression(Boolean.TRUE);
- public static final BooleanConstantExpression FALSE = new BooleanConstantExpression(Boolean.FALSE);
-
- private Object value;
-
- public static ConstantExpression createFromDecimal(String text)
- {
-
- // Strip off the 'l' or 'L' if needed.
- if (text.endsWith("l") || text.endsWith("L"))
- {
- text = text.substring(0, text.length() - 1);
- }
-
- Number value;
- try
- {
- value = new Long(text);
- }
- catch (NumberFormatException e)
- {
- // The number may be too big to fit in a long.
- value = new BigDecimal(text);
- }
-
- long l = value.longValue();
- if ((Integer.MIN_VALUE <= l) && (l <= Integer.MAX_VALUE))
- {
- value = new Integer(value.intValue());
- }
-
- return new ConstantExpression(value);
- }
-
- public static ConstantExpression createFromHex(String text)
- {
- Number value = new Long(Long.parseLong(text.substring(2), 16));
- long l = value.longValue();
- if ((Integer.MIN_VALUE <= l) && (l <= Integer.MAX_VALUE))
- {
- value = new Integer(value.intValue());
- }
-
- return new ConstantExpression(value);
- }
-
- public static ConstantExpression createFromOctal(String text)
- {
- Number value = new Long(Long.parseLong(text, 8));
- long l = value.longValue();
- if ((Integer.MIN_VALUE <= l) && (l <= Integer.MAX_VALUE))
- {
- value = new Integer(value.intValue());
- }
-
- return new ConstantExpression(value);
- }
-
- public static ConstantExpression createFloat(String text)
- {
- Number value = new Double(text);
-
- return new ConstantExpression(value);
- }
-
- public ConstantExpression(Object value)
- {
- this.value = value;
- }
-
- public Object evaluate(AbstractJMSMessage message) throws AMQInternalException
- {
- return value;
- }
-
- public Object getValue()
- {
- return value;
- }
-
- /**
- * @see Object#toString()
- */
- public String toString()
- {
- if (value == null)
- {
- return "NULL";
- }
-
- if (value instanceof Boolean)
- {
- return ((Boolean) value).booleanValue() ? "TRUE" : "FALSE";
- }
-
- if (value instanceof String)
- {
- return ConstantExpression.encodeString((String) value);
- }
-
- return value.toString();
- }
-
- /**
- * TODO: more efficient hashCode()
- *
- * @see Object#hashCode()
- */
- public int hashCode()
- {
- return toString().hashCode();
- }
-
- /**
- * TODO: more efficient hashCode()
- *
- * @see Object#equals(Object)
- */
- public boolean equals(Object o)
- {
-
- if ((o == null) || !this.getClass().equals(o.getClass()))
- {
- return false;
- }
-
- return toString().equals(o.toString());
-
- }
-
- /**
- * Encodes the value of string so that it looks like it would look like
- * when it was provided in a selector.
- *
- * @param s
- * @return
- */
- public static String encodeString(String s)
- {
- StringBuffer b = new StringBuffer();
- b.append('\'');
- for (int i = 0; i < s.length(); i++)
- {
- char c = s.charAt(i);
- if (c == '\'')
- {
- b.append(c);
- }
-
- b.append(c);
- }
-
- b.append('\'');
-
- return b.toString();
- }
-
-}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/filter/JMSSelectorFilter.java b/qpid/java/client/src/main/java/org/apache/qpid/filter/JMSSelectorFilter.java
deleted file mode 100644
index a1b4aff659..0000000000
--- a/qpid/java/client/src/main/java/org/apache/qpid/filter/JMSSelectorFilter.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.filter;
-
-import org.apache.qpid.AMQInternalException;
-import org.apache.qpid.client.message.AbstractJMSMessage;
-import org.apache.qpid.filter.selector.SelectorParser;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-public class JMSSelectorFilter implements MessageFilter
-{
- private static final Logger _logger = LoggerFactory.getLogger(JMSSelectorFilter.class);
-
- private final String _selector;
- private final BooleanExpression _matcher;
-
- public JMSSelectorFilter(String selector) throws AMQInternalException
- {
- if (selector == null || "".equals(selector))
- {
- throw new IllegalArgumentException("Cannot create a JMSSelectorFilter with a null or empty selector string");
- }
- _selector = selector;
- if (_logger.isDebugEnabled())
- {
- _logger.debug("Created JMSSelectorFilter with selector:" + _selector);
- }
- _matcher = new SelectorParser().parse(selector);
- }
-
- public boolean matches(AbstractJMSMessage message)
- {
- try
- {
- boolean match = _matcher.matches(message);
- if (_logger.isDebugEnabled())
- {
- _logger.debug(message + " match(" + match + ") selector(" + _selector + "): " + _selector);
- }
- return match;
- }
- catch (AMQInternalException e)
- {
- _logger.warn("Caught exception when evaluating message selector for message " + message, e);
- }
- return false;
- }
-
- public String getSelector()
- {
- return _selector;
- }
-}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/filter/LogicExpression.java b/qpid/java/client/src/main/java/org/apache/qpid/filter/LogicExpression.java
deleted file mode 100644
index 7ef85cbacb..0000000000
--- a/qpid/java/client/src/main/java/org/apache/qpid/filter/LogicExpression.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.filter;
-
-import org.apache.qpid.AMQInternalException;
-import org.apache.qpid.client.message.AbstractJMSMessage;
-
-
-/**
- * A filter performing a comparison of two objects
- */
-public abstract class LogicExpression extends BinaryExpression implements BooleanExpression
-{
-
- public static BooleanExpression createOR(BooleanExpression lvalue, BooleanExpression rvalue)
- {
- return new LogicExpression(lvalue, rvalue)
- {
-
- public Object evaluate(AbstractJMSMessage message) throws AMQInternalException
- {
-
- Boolean lv = (Boolean) left.evaluate(message);
- // Can we do an OR shortcut??
- if ((lv != null) && lv.booleanValue())
- {
- return Boolean.TRUE;
- }
-
- Boolean rv = (Boolean) right.evaluate(message);
-
- return (rv == null) ? null : rv;
- }
-
- public String getExpressionSymbol()
- {
- return "OR";
- }
- };
- }
-
- public static BooleanExpression createAND(BooleanExpression lvalue, BooleanExpression rvalue)
- {
- return new LogicExpression(lvalue, rvalue)
- {
-
- public Object evaluate(AbstractJMSMessage message) throws AMQInternalException
- {
-
- Boolean lv = (Boolean) left.evaluate(message);
-
- // Can we do an AND shortcut??
- if (lv == null)
- {
- return null;
- }
-
- if (!lv.booleanValue())
- {
- return Boolean.FALSE;
- }
-
- Boolean rv = (Boolean) right.evaluate(message);
-
- return (rv == null) ? null : rv;
- }
-
- public String getExpressionSymbol()
- {
- return "AND";
- }
- };
- }
-
- /**
- * @param left
- * @param right
- */
- public LogicExpression(BooleanExpression left, BooleanExpression right)
- {
- super(left, right);
- }
-
- public abstract Object evaluate(AbstractJMSMessage message) throws AMQInternalException;
-
- public boolean matches(AbstractJMSMessage message) throws AMQInternalException
- {
- Object object = evaluate(message);
-
- return (object != null) && (object == Boolean.TRUE);
- }
-
-}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java b/qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java
deleted file mode 100644
index 574a1b3888..0000000000
--- a/qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.filter;
-
-import java.util.HashMap;
-
-import javax.jms.DeliveryMode;
-import javax.jms.JMSException;
-
-import org.apache.qpid.AMQInternalException;
-import org.apache.qpid.client.message.AbstractJMSMessage;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Represents a property expression
- */
-public class PropertyExpression implements Expression
-{
- // Constants - defined the same as JMS
- private static enum JMSDeliveryMode { NON_PERSISTENT, PERSISTENT }
- private static final int DEFAULT_PRIORITY = 4;
-
- private static final Logger _logger = LoggerFactory.getLogger(PropertyExpression.class);
-
- private static final HashMap<String, Expression> JMS_PROPERTY_EXPRESSIONS = new HashMap<String, Expression>();
-
- static
- {
- JMS_PROPERTY_EXPRESSIONS.put("JMSDestination", new Expression()
- {
- public Object evaluate(AbstractJMSMessage message)
- {
- //TODO
- return null;
- }
- });
- JMS_PROPERTY_EXPRESSIONS.put("JMSReplyTo", new Expression()
- {
- public Object evaluate(AbstractJMSMessage message)
- {
- return message.getReplyToString();
- }
- });
-
- JMS_PROPERTY_EXPRESSIONS.put("JMSType", new Expression()
- {
- public Object evaluate(AbstractJMSMessage message)
- {
- try
- {
- return message.getJMSType();
- }
- catch (JMSException e)
- {
- _logger.warn("Error evaluating property", e);
-
- return null;
- }
-
- }
- });
-
- JMS_PROPERTY_EXPRESSIONS.put("JMSDeliveryMode", new Expression()
- {
- public Object evaluate(AbstractJMSMessage message)
- {
-
- JMSDeliveryMode mode = JMSDeliveryMode.NON_PERSISTENT;
- try
- {
- mode = message.getJMSDeliveryMode() == DeliveryMode.PERSISTENT ?
- JMSDeliveryMode.PERSISTENT : JMSDeliveryMode.NON_PERSISTENT;
-
- if (_logger.isDebugEnabled())
- {
- _logger.debug("JMSDeliveryMode is :" + mode);
- }
- }
- catch (JMSException e)
- {
- _logger.warn("Error evaluating property",e);
- }
-
- return mode.toString();
- }
- });
-
- JMS_PROPERTY_EXPRESSIONS.put("JMSPriority", new Expression()
- {
- public Object evaluate(AbstractJMSMessage message)
- {
- try
- {
- return message.getJMSPriority();
- }
- catch (Exception e)
- {
- _logger.warn("Error evaluating property",e);
- }
-
- return DEFAULT_PRIORITY;
- }
- });
-
- JMS_PROPERTY_EXPRESSIONS.put("AMQMessageID", new Expression()
- {
- public Object evaluate(AbstractJMSMessage message)
- {
-
- try
- {
- return message.getJMSMessageID();
- }
- catch (JMSException e)
- {
- _logger.warn("Error evaluating property",e);
-
- return null;
- }
-
- }
- });
-
- JMS_PROPERTY_EXPRESSIONS.put("JMSTimestamp", new Expression()
- {
- public Object evaluate(AbstractJMSMessage message)
- {
- try
- {
- return message.getJMSTimestamp();
- }
- catch (Exception e)
- {
- _logger.warn("Error evaluating property",e);
-
- return null;
- }
-
- }
- });
-
- JMS_PROPERTY_EXPRESSIONS.put("JMSCorrelationID", new Expression()
- {
- public Object evaluate(AbstractJMSMessage message)
- {
-
- try
- {
- return message.getJMSCorrelationID();
- }
- catch (JMSException e)
- {
- _logger.warn("Error evaluating property",e);
-
- return null;
- }
-
- }
- });
-
- JMS_PROPERTY_EXPRESSIONS.put("JMSExpiration", new Expression()
- {
- public Object evaluate(AbstractJMSMessage message)
- {
-
- try
- {
- return message.getJMSExpiration();
- }
- catch (JMSException e)
- {
- _logger.warn("Error evaluating property",e);
- return null;
- }
-
- }
- });
-
- JMS_PROPERTY_EXPRESSIONS.put("JMSRedelivered", new Expression()
- {
- public Object evaluate(AbstractJMSMessage message)
- {
- try
- {
- return message.getJMSRedelivered();
- }
- catch (JMSException e)
- {
- _logger.warn("Error evaluating property",e);
- return null;
- }
- }
- });
-
- JMS_PROPERTY_EXPRESSIONS.put("JMSMessageID", new Expression()
- {
- public Object evaluate(AbstractJMSMessage message)
- {
- try
- {
- return message.getJMSMessageID();
- }
- catch (Exception e)
- {
- _logger.warn("Error evaluating property",e);
-
- return null;
- }
-
- }
- });
-
- }
-
- private final String name;
- private final Expression jmsPropertyExpression;
-
- public PropertyExpression(String name)
- {
- this.name = name;
- jmsPropertyExpression = JMS_PROPERTY_EXPRESSIONS.get(name);
- }
-
- public Object evaluate(AbstractJMSMessage message) throws AMQInternalException
- {
-
- if (jmsPropertyExpression != null)
- {
- return jmsPropertyExpression.evaluate(message);
- }
- else
- {
-
- try
- {
-
- if (_logger.isDebugEnabled())
- {
- _logger.debug("Looking up property:" + name);
- _logger.debug("Properties are:" + message.getPropertyNames());
- }
- return message.getObjectProperty(name);
- }
- catch(JMSException e)
- {
- throw new AMQInternalException("Exception evaluating properties for filter", e);
- }
- }
- }
-
- public String getName()
- {
- return name;
- }
-
- /**
- * @see java.lang.Object#toString()
- */
- public String toString()
- {
- return name;
- }
-
- /**
- * @see java.lang.Object#hashCode()
- */
- public int hashCode()
- {
- return name.hashCode();
- }
-
- /**
- * @see java.lang.Object#equals(java.lang.Object)
- */
- public boolean equals(Object o)
- {
- if ((o == null) || !this.getClass().equals(o.getClass()))
- {
- return false;
- }
- return name.equals(((PropertyExpression) o).name);
- }
-
-}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/filter/UnaryExpression.java b/qpid/java/client/src/main/java/org/apache/qpid/filter/UnaryExpression.java
deleted file mode 100644
index 0fc3382b7e..0000000000
--- a/qpid/java/client/src/main/java/org/apache/qpid/filter/UnaryExpression.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.filter;
-
-import java.math.BigDecimal;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.qpid.AMQInternalException;
-import org.apache.qpid.client.message.AbstractJMSMessage;
-
-/**
- * An expression which performs an operation on two expression values
- */
-public abstract class UnaryExpression implements Expression
-{
-
- private static final BigDecimal BD_LONG_MIN_VALUE = BigDecimal.valueOf(Long.MIN_VALUE);
- protected Expression right;
-
- public static Expression createNegate(Expression left)
- {
- return new UnaryExpression(left)
- {
- public Object evaluate(AbstractJMSMessage message) throws AMQInternalException
- {
- Object rvalue = right.evaluate(message);
- if (rvalue == null)
- {
- return null;
- }
-
- if (rvalue instanceof Number)
- {
- return UnaryExpression.negate((Number) rvalue);
- }
-
- return null;
- }
-
- public String getExpressionSymbol()
- {
- return "-";
- }
- };
- }
-
- public static BooleanExpression createInExpression(PropertyExpression right, List elements, final boolean not)
- {
-
- // Use a HashSet if there are many elements.
- Collection t;
- if (elements.size() == 0)
- {
- t = null;
- }
- else if (elements.size() < 5)
- {
- t = elements;
- }
- else
- {
- t = new HashSet(elements);
- }
-
- final Collection inList = t;
-
- return new BooleanUnaryExpression(right)
- {
- public Object evaluate(AbstractJMSMessage message) throws AMQInternalException
- {
-
- Object rvalue = right.evaluate(message);
- if (rvalue == null)
- {
- return null;
- }
-
- if (rvalue.getClass() != String.class)
- {
- return null;
- }
-
- if (((inList != null) && inList.contains(rvalue)) ^ not)
- {
- return Boolean.TRUE;
- }
- else
- {
- return Boolean.FALSE;
- }
-
- }
-
- public String toString()
- {
- StringBuffer answer = new StringBuffer();
- answer.append(right);
- answer.append(" ");
- answer.append(getExpressionSymbol());
- answer.append(" ( ");
-
- int count = 0;
- for (Iterator i = inList.iterator(); i.hasNext();)
- {
- Object o = (Object) i.next();
- if (count != 0)
- {
- answer.append(", ");
- }
-
- answer.append(o);
- count++;
- }
-
- answer.append(" )");
-
- return answer.toString();
- }
-
- public String getExpressionSymbol()
- {
- if (not)
- {
- return "NOT IN";
- }
- else
- {
- return "IN";
- }
- }
- };
- }
-
- abstract static class BooleanUnaryExpression extends UnaryExpression implements BooleanExpression
- {
- public BooleanUnaryExpression(Expression left)
- {
- super(left);
- }
-
- public boolean matches(AbstractJMSMessage message) throws AMQInternalException
- {
- Object object = evaluate(message);
-
- return (object != null) && (object == Boolean.TRUE);
- }
- }
-
- ;
-
- public static BooleanExpression createNOT(BooleanExpression left)
- {
- return new BooleanUnaryExpression(left)
- {
- public Object evaluate(AbstractJMSMessage message) throws AMQInternalException
- {
- Boolean lvalue = (Boolean) right.evaluate(message);
- if (lvalue == null)
- {
- return null;
- }
-
- return lvalue.booleanValue() ? Boolean.FALSE : Boolean.TRUE;
- }
-
- public String getExpressionSymbol()
- {
- return "NOT";
- }
- };
- }
- public static BooleanExpression createBooleanCast(Expression left)
- {
- return new BooleanUnaryExpression(left)
- {
- public Object evaluate(AbstractJMSMessage message) throws AMQInternalException
- {
- Object rvalue = right.evaluate(message);
- if (rvalue == null)
- {
- return null;
- }
-
- if (!rvalue.getClass().equals(Boolean.class))
- {
- return Boolean.FALSE;
- }
-
- return ((Boolean) rvalue).booleanValue() ? Boolean.TRUE : Boolean.FALSE;
- }
-
- public String toString()
- {
- return right.toString();
- }
-
- public String getExpressionSymbol()
- {
- return "";
- }
- };
- }
-
- private static Number negate(Number left)
- {
- Class clazz = left.getClass();
- if (clazz == Integer.class)
- {
- return new Integer(-left.intValue());
- }
- else if (clazz == Long.class)
- {
- return new Long(-left.longValue());
- }
- else if (clazz == Float.class)
- {
- return new Float(-left.floatValue());
- }
- else if (clazz == Double.class)
- {
- return new Double(-left.doubleValue());
- }
- else if (clazz == BigDecimal.class)
- {
- // We ussually get a big deciamal when we have Long.MIN_VALUE constant in the
- // Selector. Long.MIN_VALUE is too big to store in a Long as a positive so we store it
- // as a Big decimal. But it gets Negated right away.. to here we try to covert it back
- // to a Long.
- BigDecimal bd = (BigDecimal) left;
- bd = bd.negate();
-
- if (UnaryExpression.BD_LONG_MIN_VALUE.compareTo(bd) == 0)
- {
- return new Long(Long.MIN_VALUE);
- }
-
- return bd;
- }
- else
- {
- throw new RuntimeException("Don't know how to negate: " + left);
- }
- }
-
- public UnaryExpression(Expression left)
- {
- this.right = left;
- }
-
- public Expression getRight()
- {
- return right;
- }
-
- public void setRight(Expression expression)
- {
- right = expression;
- }
-
- /**
- * @see Object#toString()
- */
- public String toString()
- {
- return "(" + getExpressionSymbol() + " " + right.toString() + ")";
- }
-
- /**
- * TODO: more efficient hashCode()
- *
- * @see Object#hashCode()
- */
- public int hashCode()
- {
- return toString().hashCode();
- }
-
- /**
- * TODO: more efficient hashCode()
- *
- * @see Object#equals(Object)
- */
- public boolean equals(Object o)
- {
-
- if ((o == null) || !this.getClass().equals(o.getClass()))
- {
- return false;
- }
-
- return toString().equals(o.toString());
-
- }
-
- /**
- * Returns the symbol that represents this binary expression. For example, addition is
- * represented by "+"
- *
- * @return
- */
- public abstract String getExpressionSymbol();
-
-}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/nclient/util/MessagePartListenerAdapter.java b/qpid/java/client/src/main/java/org/apache/qpid/nclient/util/MessagePartListenerAdapter.java
index 10fd8d2a80..2f1eda6ef2 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/nclient/util/MessagePartListenerAdapter.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/nclient/util/MessagePartListenerAdapter.java
@@ -49,19 +49,9 @@ public class MessagePartListenerAdapter implements MessagePartListener
{
_currentMsg = new ByteBufferMessage(xfr.getId());
- for (Struct st : xfr.getHeader().getStructs())
- {
- if(st instanceof DeliveryProperties)
- {
- _currentMsg.setDeliveryProperties((DeliveryProperties)st);
-
- }
- else if(st instanceof MessageProperties)
- {
- _currentMsg.setMessageProperties((MessageProperties)st);
- }
-
- }
+ Header header = xfr.getHeader();
+ _currentMsg.setDeliveryProperties(header.getDeliveryProperties());
+ _currentMsg.setMessageProperties(header.getMessageProperties());
ByteBuffer body = xfr.getBody();
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/AMQSession_0_10Test.java b/qpid/java/client/src/test/java/org/apache/qpid/client/AMQSession_0_10Test.java
index f53fa8d83c..1889577773 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/client/AMQSession_0_10Test.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/client/AMQSession_0_10Test.java
@@ -588,7 +588,7 @@ public class AMQSession_0_10Test extends TestCase
}
boolean isTransacted = acknowledgeMode == javax.jms.Session.SESSION_TRANSACTED ? true : false;
AMQSession_0_10 session = new AMQSession_0_10(createConnection(throwException), amqConnection, 1, isTransacted, acknowledgeMode,
- 1, 1, "test");
+ 0, 0, "test");
return session;
}
@@ -600,7 +600,6 @@ public class AMQSession_0_10Test extends TestCase
connection.setSessionFactory(new SessionFactory()
{
- @Override
public Session newSession(Connection conn, Binary name, long expiry)
{
return new MockSession(conn, new SessionDelegate(), name, expiry, throwException);
@@ -611,7 +610,6 @@ public class AMQSession_0_10Test extends TestCase
private final class MockMessageListener implements MessageListener
{
- @Override
public void onMessage(Message arg0)
{
}
@@ -710,23 +708,19 @@ public class AMQSession_0_10Test extends TestCase
{
private List<ProtocolEvent> _sendEvents = new ArrayList<ProtocolEvent>();
- @Override
public void setIdleTimeout(int i)
{
}
- @Override
public void send(ProtocolEvent msg)
{
_sendEvents.add(msg);
}
- @Override
public void flush()
{
}
- @Override
public void close()
{
}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/BasicMessageConsumer_0_8_Test.java b/qpid/java/client/src/test/java/org/apache/qpid/client/BasicMessageConsumer_0_8_Test.java
index d8d94ba40e..02089cc382 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/client/BasicMessageConsumer_0_8_Test.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/client/BasicMessageConsumer_0_8_Test.java
@@ -46,8 +46,9 @@ public class BasicMessageConsumer_0_8_Test extends TestCase
AMQBindingURL burl = new AMQBindingURL(url);
AMQDestination queue = new AMQQueue(burl);
- AMQSession<BasicMessageConsumer_0_8, BasicMessageProducer_0_8> testSession = new TestAMQSession(conn);
- BasicMessageConsumer_0_8 consumer = new BasicMessageConsumer_0_8(0, conn, queue, "", false, null, testSession, null, null, 10, 5, false, Session.SESSION_TRANSACTED, false, false);
+ TestAMQSession testSession = new TestAMQSession(conn);
+ BasicMessageConsumer_0_8 consumer =
+ new BasicMessageConsumer_0_8(0, conn, queue, "", false, null, testSession, null, null, 10, 5, false, Session.SESSION_TRANSACTED, false, false);
assertEquals("Reject behaviour was was not as expected", RejectBehaviour.SERVER, consumer.getRejectBehaviour());
}
@@ -65,8 +66,9 @@ public class BasicMessageConsumer_0_8_Test extends TestCase
final AMQBindingURL burl = new AMQBindingURL(url);
final AMQDestination queue = new AMQQueue(burl);
- final AMQSession<BasicMessageConsumer_0_8, BasicMessageProducer_0_8> testSession = new TestAMQSession(conn);
- final BasicMessageConsumer_0_8 consumer = new BasicMessageConsumer_0_8(0, conn, queue, "", false, null, testSession, null, null, 10, 5, false, Session.SESSION_TRANSACTED, false, false);
+ final TestAMQSession testSession = new TestAMQSession(conn);
+ final BasicMessageConsumer_0_8 consumer =
+ new BasicMessageConsumer_0_8(0, conn, queue, "", false, null, testSession, null, null, 10, 5, false, Session.SESSION_TRANSACTED, false, false);
assertEquals("Reject behaviour was was not as expected", RejectBehaviour.NORMAL, consumer.getRejectBehaviour());
}
@@ -90,8 +92,9 @@ public class BasicMessageConsumer_0_8_Test extends TestCase
assertNull("Reject behaviour should have been null", queue.getRejectBehaviour());
- AMQSession<BasicMessageConsumer_0_8, BasicMessageProducer_0_8> testSession = new TestAMQSession(conn);
- BasicMessageConsumer_0_8 consumer = new BasicMessageConsumer_0_8(0, conn, queue, "", false, null, testSession, null, null, 10, 5, false, Session.SESSION_TRANSACTED, false, false);
+ TestAMQSession testSession = new TestAMQSession(conn);
+ BasicMessageConsumer_0_8 consumer =
+ new BasicMessageConsumer_0_8(0, conn, queue, "", false, null, testSession, null, null, 10, 5, false, Session.SESSION_TRANSACTED, false, false);
assertEquals("Reject behaviour was was not as expected", RejectBehaviour.NORMAL, consumer.getRejectBehaviour());
}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/filter/JMSSelectorFilterTest.java b/qpid/java/client/src/test/java/org/apache/qpid/filter/JMSSelectorFilterTest.java
deleted file mode 100644
index d4d8ea4350..0000000000
--- a/qpid/java/client/src/test/java/org/apache/qpid/filter/JMSSelectorFilterTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.filter;
-
-import junit.framework.TestCase;
-
-import org.apache.qpid.AMQInternalException;
-import org.apache.qpid.client.message.JMSTextMessage;
-import org.apache.qpid.client.message.TestMessageHelper;
-
-public class JMSSelectorFilterTest extends TestCase
-{
-
- public void testEmptySelectorFilter() throws Exception
- {
- try
- {
- new JMSSelectorFilter("");
- fail("Should not be able to create a JMSSelectorFilter with an empty selector");
- }
- catch (IllegalArgumentException iae)
- {
- // pass
- }
- }
-
- public void testNullSelectorFilter() throws Exception
- {
- try
- {
- new JMSSelectorFilter(null);
- fail("Should not be able to create a JMSSelectorFilter with a null selector");
- }
- catch (IllegalArgumentException iae)
- {
- // pass
- }
- }
-
- public void testInvalidSelectorFilter() throws Exception
- {
- try
- {
- new JMSSelectorFilter("$%^");
- fail("Unparsable selector so expected AMQInternalException to be thrown");
- }
- catch (AMQInternalException amqie)
- {
- // pass
- }
- }
-
- public void testSimpleSelectorFilter() throws Exception
- {
- MessageFilter simpleSelectorFilter = new JMSSelectorFilter("select=5");
-
- assertNotNull("Filter object is null", simpleSelectorFilter);
- assertNotNull("Selector string is null", simpleSelectorFilter.getSelector());
- assertEquals("Unexpected selector", "select=5", simpleSelectorFilter.getSelector());
- assertTrue("Filter object is invalid", simpleSelectorFilter != null);
-
- final JMSTextMessage message = TestMessageHelper.newJMSTextMessage();
-
- message.setIntProperty("select", 4);
- assertFalse("Selector did match when not expected", simpleSelectorFilter.matches(message));
- message.setIntProperty("select", 5);
- assertTrue("Selector didnt match when expected", simpleSelectorFilter.matches(message));
- message.setIntProperty("select", 6);
- assertFalse("Selector did match when not expected", simpleSelectorFilter.matches(message));
- }
-
- public void testFailedMatchingFilter() throws Exception
- {
- MessageFilter simpleSelectorFilter = new JMSSelectorFilter("select>4");
-
- assertNotNull("Filter object is null", simpleSelectorFilter);
- assertNotNull("Selector string is null", simpleSelectorFilter.getSelector());
- assertEquals("Unexpected selector", "select>4", simpleSelectorFilter.getSelector());
- assertTrue("Filter object is invalid", simpleSelectorFilter != null);
-
- final JMSTextMessage message = TestMessageHelper.newJMSTextMessage();
-
- message.setStringProperty("select", "5");
- assertFalse("Selector matched when not expected", simpleSelectorFilter.matches(message));
- message.setStringProperty("select", "elephant");
- assertFalse("Selector matched when not expected", simpleSelectorFilter.matches(message));
- message.setBooleanProperty("select", false);
- assertFalse("Selector matched when not expected", simpleSelectorFilter.matches(message));
- }
-}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java
index 06d0f4a3f9..4c3e9c2390 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java
@@ -29,12 +29,7 @@ import javax.jms.Topic;
import javax.jms.TopicSubscriber;
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.client.BasicMessageConsumer_0_8;
-import org.apache.qpid.client.BasicMessageProducer_0_8;
-import org.apache.qpid.client.MockAMQConnection;
+import org.apache.qpid.client.*;
import org.apache.qpid.client.failover.FailoverException;
import org.apache.qpid.client.message.AMQMessageDelegateFactory;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
@@ -42,7 +37,7 @@ import org.apache.qpid.filter.MessageFilter;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
-public class TestAMQSession extends AMQSession<BasicMessageConsumer_0_8, BasicMessageProducer_0_8>
+public class TestAMQSession extends AMQSession_0_8
{
public TestAMQSession(AMQConnection connection)
@@ -92,7 +87,7 @@ public class TestAMQSession extends AMQSession<BasicMessageConsumer_0_8, BasicMe
return null;
}
- protected void sendRecover() throws AMQException, FailoverException
+ public void sendRecover() throws AMQException, FailoverException
{
}
diff --git a/qpid/java/common.xml b/qpid/java/common.xml
index 26537e7dfc..4e9e2d1598 100644
--- a/qpid/java/common.xml
+++ b/qpid/java/common.xml
@@ -61,6 +61,12 @@
<property name="javac.compiler.args" value=""/>
<property name="cobertura.dir" value="${project.root}/lib/cobertura" />
+ <property name="cobertura.version" value="1.9.4.1" />
+ <property name="cobertura.download.url"
+ value="http://downloads.sourceforge.net/project/cobertura/cobertura/${cobertura.version}/cobertura-${cobertura.version}-bin.zip" />
+ <property name="cobertura.zip.filename" value="cobertura-${cobertura.version}-bin.zip" />
+ <property name="cobertura.temp.dir" value="${cobertura.dir}"/>
+
<property name="mllib.dir" value="${project.root}/../python" />
<property name="findbugs.dir" value="${project.root}/lib/findbugs" />
@@ -71,8 +77,8 @@
<path id="cobertura.classpath">
<fileset dir="${cobertura.dir}">
- <include name="cobertura.jar" />
- <include name="lib/**/*.jar" />
+ <include name="cobertura-${cobertura.version}/*.jar" />
+ <include name="cobertura-${cobertura.version}/**/lib/*.jar" />
</fileset>
</path>
@@ -192,6 +198,22 @@
<taskdef classpathref="cobertura.classpath" resource="tasks.properties" />
</target>
+ <!--download Cobertura jar and expand-->
+ <target name="download-cobertura" description="download Cobertura if not already present" depends="cobertura-check" unless="cobertura.already.exists">
+ <mkdir dir="${cobertura.dir}"/>
+ <echo>Downloading Cobertura ${cobertura.version}</echo>
+ <get src="${cobertura.download.url}" dest="${cobertura.temp.dir}/${cobertura.zip.filename}" usetimestamp="false" />
+ <echo>Extracting Cobertura JAR and dependencies</echo>
+ <unzip src="${cobertura.temp.dir}/${cobertura.zip.filename}" dest="${cobertura.dir}"/>
+ <echo>Cleanup Cobertura Download</echo>
+ <delete file="${cobertura.temp.dir}/${cobertura.zip.filename}"/>
+ <echo>Done</echo>
+ </target>
+
+ <target name="cobertura-check">
+ <available property="cobertura.already.exists" file="${cobertura.dir}/cobertura-${cobertura.version}" type="dir"/>
+ </target>
+
<target name="findbugs-init">
<available file="${findbugs.dir}/findbugs-ant.jar" property="findbugs-ant.jar.present"/>
<fail unless="findbugs-ant.jar.present" message="Please follow the instructions at ${findbugs.dir}/README.txt to configure FindBugs"/>
diff --git a/qpid/java/common/Composite.tpl b/qpid/java/common/Composite.tpl
index 350dd893c8..2cbd6830f6 100644
--- a/qpid/java/common/Composite.tpl
+++ b/qpid/java/common/Composite.tpl
@@ -245,6 +245,11 @@ if segments:
return this;
}
+ public int getBodySize()
+ {
+ return this.body == null ? 0 : this.body.remaining();
+ }
+
public final ByteBuffer getBody() {
if (this.body == null)
{
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/codec/AMQDecoder.java b/qpid/java/common/src/main/java/org/apache/qpid/codec/AMQDecoder.java
index 69bf73bb49..1d196534b2 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/codec/AMQDecoder.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/codec/AMQDecoder.java
@@ -24,12 +24,7 @@ import java.io.*;
import java.nio.ByteBuffer;
import java.util.*;
-import org.apache.qpid.framing.AMQDataBlock;
-import org.apache.qpid.framing.AMQDataBlockDecoder;
-import org.apache.qpid.framing.AMQFrameDecodingException;
-import org.apache.qpid.framing.AMQMethodBodyFactory;
-import org.apache.qpid.framing.AMQProtocolVersionException;
-import org.apache.qpid.framing.ProtocolInitiation;
+import org.apache.qpid.framing.*;
import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
/**
@@ -193,24 +188,41 @@ public class AMQDecoder
}
}
+ private static class SimpleDataInputStream extends DataInputStream implements MarkableDataInput
+ {
+ public SimpleDataInputStream(InputStream in)
+ {
+ super(in);
+ }
+
+ public AMQShortString readAMQShortString() throws IOException
+ {
+ return EncodingUtils.readAMQShortString(this);
+ }
+
+ }
+
public ArrayList<AMQDataBlock> decodeBuffer(ByteBuffer buf) throws AMQFrameDecodingException, AMQProtocolVersionException, IOException
{
// get prior remaining data from accumulator
ArrayList<AMQDataBlock> dataBlocks = new ArrayList<AMQDataBlock>();
- DataInputStream msg;
+ MarkableDataInput msg;
- ByteArrayInputStream bais = new ByteArrayInputStream(buf.array(),buf.arrayOffset()+buf.position(), buf.remaining());
+ ByteArrayInputStream bais;
+ DataInput di;
if(!_remainingBufs.isEmpty())
{
+ bais = new ByteArrayInputStream(buf.array(),buf.arrayOffset()+buf.position(), buf.remaining());
_remainingBufs.add(bais);
- msg = new DataInputStream(new RemainingByteArrayInputStream());
+ msg = new SimpleDataInputStream(new RemainingByteArrayInputStream());
}
else
{
- msg = new DataInputStream(bais);
+ bais = null;
+ msg = new ByteArrayDataInput(buf.array(),buf.arrayOffset()+buf.position(), buf.remaining());
}
boolean enoughData = true;
@@ -245,11 +257,24 @@ public class AMQDecoder
iterator.remove();
}
}
- if(bais.available()!=0)
+
+ if(bais == null)
+ {
+ if(msg.available()!=0)
+ {
+ byte[] remaining = new byte[msg.available()];
+ msg.read(remaining);
+ _remainingBufs.add(new ByteArrayInputStream(remaining));
+ }
+ }
+ else
{
- byte[] remaining = new byte[bais.available()];
- bais.read(remaining);
- _remainingBufs.add(new ByteArrayInputStream(remaining));
+ if(bais.available()!=0)
+ {
+ byte[] remaining = new byte[bais.available()];
+ bais.read(remaining);
+ _remainingBufs.add(new ByteArrayInputStream(remaining));
+ }
}
}
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/codec/MarkableDataInput.java b/qpid/java/common/src/main/java/org/apache/qpid/codec/MarkableDataInput.java
new file mode 100644
index 0000000000..2a243a810d
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/codec/MarkableDataInput.java
@@ -0,0 +1,21 @@
+package org.apache.qpid.codec;
+
+import org.apache.qpid.framing.AMQShortString;
+
+import java.io.DataInput;
+import java.io.IOException;
+
+public interface MarkableDataInput extends DataInput
+{
+ public void mark(int pos);
+ public void reset() throws IOException;
+
+ int available() throws IOException;
+
+ long skip(long i) throws IOException;
+
+ int read(byte[] b) throws IOException;
+
+ public AMQShortString readAMQShortString() throws IOException;
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQBody.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQBody.java
index ebdad12178..363d9f1ccc 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQBody.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQBody.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.framing;
+import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
@@ -36,7 +37,7 @@ public interface AMQBody
*/
public abstract int getSize();
- public void writePayload(DataOutputStream buffer) throws IOException;
+ public void writePayload(DataOutput buffer) throws IOException;
void handle(final int channelId, final AMQVersionAwareProtocolSession amqProtocolSession) throws AMQException;
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlock.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlock.java
index 00c1f5aae5..e77e5942e3 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlock.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlock.java
@@ -21,6 +21,7 @@
package org.apache.qpid.framing;
import java.io.DataInputStream;
+import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
@@ -42,6 +43,6 @@ public abstract class AMQDataBlock implements EncodableAMQDataBlock
* Writes the datablock to the specified buffer.
* @param buffer
*/
- public abstract void writePayload(DataOutputStream buffer) throws IOException;
+ public abstract void writePayload(DataOutput buffer) throws IOException;
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlockDecoder.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlockDecoder.java
index 2165cadd14..b6f2fb18ea 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlockDecoder.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlockDecoder.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.framing;
+import org.apache.qpid.codec.MarkableDataInput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,7 +44,7 @@ public class AMQDataBlockDecoder
public AMQDataBlockDecoder()
{ }
- public boolean decodable(DataInputStream in) throws AMQFrameDecodingException, IOException
+ public boolean decodable(MarkableDataInput in) throws AMQFrameDecodingException, IOException
{
final int remainingAfterAttributes = in.available() - (1 + 2 + 4 + 1);
// type, channel, body length and end byte
@@ -65,7 +66,7 @@ public class AMQDataBlockDecoder
}
- public AMQFrame createAndPopulateFrame(AMQMethodBodyFactory methodBodyFactory, DataInputStream in)
+ public AMQFrame createAndPopulateFrame(AMQMethodBodyFactory methodBodyFactory, MarkableDataInput in)
throws AMQFrameDecodingException, AMQProtocolVersionException, IOException
{
final byte type = in.readByte();
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQFrame.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQFrame.java
index 6acf60a5b3..9b5699e8ff 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQFrame.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQFrame.java
@@ -20,9 +20,10 @@
*/
package org.apache.qpid.framing;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
+import org.apache.qpid.codec.MarkableDataInput;
+
+import java.io.*;
+import java.io.DataOutput;
public class AMQFrame extends AMQDataBlock implements EncodableAMQDataBlock
{
@@ -38,7 +39,7 @@ public class AMQFrame extends AMQDataBlock implements EncodableAMQDataBlock
_bodyFrame = bodyFrame;
}
- public AMQFrame(final DataInputStream in, final int channel, final long bodySize, final BodyFactory bodyFactory) throws AMQFrameDecodingException, IOException
+ public AMQFrame(final MarkableDataInput in, final int channel, final long bodySize, final BodyFactory bodyFactory) throws AMQFrameDecodingException, IOException
{
this._channel = channel;
this._bodyFrame = bodyFactory.createBody(in,bodySize);
@@ -55,7 +56,7 @@ public class AMQFrame extends AMQDataBlock implements EncodableAMQDataBlock
}
- public void writePayload(DataOutputStream buffer) throws IOException
+ public void writePayload(DataOutput buffer) throws IOException
{
buffer.writeByte(_bodyFrame.getFrameType());
EncodingUtils.writeUnsignedShort(buffer, _channel);
@@ -79,7 +80,7 @@ public class AMQFrame extends AMQDataBlock implements EncodableAMQDataBlock
return "Frame channelId: " + _channel + ", bodyFrame: " + String.valueOf(_bodyFrame);
}
- public static void writeFrame(DataOutputStream buffer, final int channel, AMQBody body) throws IOException
+ public static void writeFrame(DataOutput buffer, final int channel, AMQBody body) throws IOException
{
buffer.writeByte(body.getFrameType());
EncodingUtils.writeUnsignedShort(buffer, channel);
@@ -89,7 +90,7 @@ public class AMQFrame extends AMQDataBlock implements EncodableAMQDataBlock
}
- public static void writeFrames(DataOutputStream buffer, final int channel, AMQBody body1, AMQBody body2) throws IOException
+ public static void writeFrames(DataOutput buffer, final int channel, AMQBody body1, AMQBody body2) throws IOException
{
buffer.writeByte(body1.getFrameType());
EncodingUtils.writeUnsignedShort(buffer, channel);
@@ -104,7 +105,7 @@ public class AMQFrame extends AMQDataBlock implements EncodableAMQDataBlock
}
- public static void writeFrames(DataOutputStream buffer, final int channel, AMQBody body1, AMQBody body2, AMQBody body3) throws IOException
+ public static void writeFrames(DataOutput buffer, final int channel, AMQBody body1, AMQBody body2, AMQBody body3) throws IOException
{
buffer.writeByte(body1.getFrameType());
EncodingUtils.writeUnsignedShort(buffer, channel);
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBody.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBody.java
index a076d0e5a1..2170ebf992 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBody.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBody.java
@@ -25,6 +25,7 @@ import org.apache.qpid.AMQConnectionException;
import org.apache.qpid.AMQException;
import org.apache.qpid.protocol.AMQConstant;
+import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
@@ -45,12 +46,12 @@ public interface AMQMethodBody extends AMQBody
/** @return unsigned short */
public int getMethod();
- public void writeMethodPayload(DataOutputStream buffer) throws IOException;
+ public void writeMethodPayload(DataOutput buffer) throws IOException;
public int getSize();
- public void writePayload(DataOutputStream buffer) throws IOException;
+ public void writePayload(DataOutput buffer) throws IOException;
//public abstract void populateMethodBodyFromBuffer(ByteBuffer buffer) throws AMQFrameDecodingException;
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyFactory.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyFactory.java
index 7fceb082ee..ec6d662726 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyFactory.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyFactory.java
@@ -20,11 +20,13 @@
*/
package org.apache.qpid.framing;
+import org.apache.qpid.codec.MarkableDataInput;
import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.DataInput;
import java.io.DataInputStream;
import java.io.IOException;
@@ -39,7 +41,7 @@ public class AMQMethodBodyFactory implements BodyFactory
_protocolSession = protocolSession;
}
- public AMQBody createBody(DataInputStream in, long bodySize) throws AMQFrameDecodingException, IOException
+ public AMQBody createBody(MarkableDataInput in, long bodySize) throws AMQFrameDecodingException, IOException
{
return _protocolSession.getMethodRegistry().convertToBody(in, bodySize);
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyImpl.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyImpl.java
index c73c1df701..d6f518b123 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyImpl.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyImpl.java
@@ -24,11 +24,12 @@ package org.apache.qpid.framing;
import org.apache.qpid.AMQChannelException;
import org.apache.qpid.AMQConnectionException;
import org.apache.qpid.AMQException;
+import org.apache.qpid.codec.MarkableDataInput;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
+import java.io.DataInput;
+import java.io.DataOutput;
import java.io.IOException;
public abstract class AMQMethodBodyImpl implements AMQMethodBody
@@ -101,7 +102,7 @@ public abstract class AMQMethodBodyImpl implements AMQMethodBody
return 2 + 2 + getBodySize();
}
- public void writePayload(DataOutputStream buffer) throws IOException
+ public void writePayload(DataOutput buffer) throws IOException
{
EncodingUtils.writeUnsignedShort(buffer, getClazz());
EncodingUtils.writeUnsignedShort(buffer, getMethod());
@@ -109,14 +110,15 @@ public abstract class AMQMethodBodyImpl implements AMQMethodBody
}
- protected byte readByte(DataInputStream buffer) throws IOException
+ protected byte readByte(DataInput buffer) throws IOException
{
return buffer.readByte();
}
- protected AMQShortString readAMQShortString(DataInputStream buffer) throws IOException
+ protected AMQShortString readAMQShortString(MarkableDataInput buffer) throws IOException
{
- return EncodingUtils.readAMQShortString(buffer);
+ AMQShortString str = buffer.readAMQShortString();
+ return str == null ? null : str.intern(false);
}
protected int getSizeOf(AMQShortString string)
@@ -124,27 +126,27 @@ public abstract class AMQMethodBodyImpl implements AMQMethodBody
return EncodingUtils.encodedShortStringLength(string);
}
- protected void writeByte(DataOutputStream buffer, byte b) throws IOException
+ protected void writeByte(DataOutput buffer, byte b) throws IOException
{
buffer.writeByte(b);
}
- protected void writeAMQShortString(DataOutputStream buffer, AMQShortString string) throws IOException
+ protected void writeAMQShortString(DataOutput buffer, AMQShortString string) throws IOException
{
EncodingUtils.writeShortStringBytes(buffer, string);
}
- protected int readInt(DataInputStream buffer) throws IOException
+ protected int readInt(DataInput buffer) throws IOException
{
return buffer.readInt();
}
- protected void writeInt(DataOutputStream buffer, int i) throws IOException
+ protected void writeInt(DataOutput buffer, int i) throws IOException
{
buffer.writeInt(i);
}
- protected FieldTable readFieldTable(DataInputStream buffer) throws AMQFrameDecodingException, IOException
+ protected FieldTable readFieldTable(DataInput buffer) throws AMQFrameDecodingException, IOException
{
return EncodingUtils.readFieldTable(buffer);
}
@@ -154,17 +156,17 @@ public abstract class AMQMethodBodyImpl implements AMQMethodBody
return EncodingUtils.encodedFieldTableLength(table); //To change body of created methods use File | Settings | File Templates.
}
- protected void writeFieldTable(DataOutputStream buffer, FieldTable table) throws IOException
+ protected void writeFieldTable(DataOutput buffer, FieldTable table) throws IOException
{
EncodingUtils.writeFieldTableBytes(buffer, table);
}
- protected long readLong(DataInputStream buffer) throws IOException
+ protected long readLong(DataInput buffer) throws IOException
{
return buffer.readLong();
}
- protected void writeLong(DataOutputStream buffer, long l) throws IOException
+ protected void writeLong(DataOutput buffer, long l) throws IOException
{
buffer.writeLong(l);
}
@@ -174,27 +176,27 @@ public abstract class AMQMethodBodyImpl implements AMQMethodBody
return (response == null) ? 4 : response.length + 4;
}
- protected void writeBytes(DataOutputStream buffer, byte[] data) throws IOException
+ protected void writeBytes(DataOutput buffer, byte[] data) throws IOException
{
EncodingUtils.writeBytes(buffer,data);
}
- protected byte[] readBytes(DataInputStream buffer) throws IOException
+ protected byte[] readBytes(DataInput buffer) throws IOException
{
return EncodingUtils.readBytes(buffer);
}
- protected short readShort(DataInputStream buffer) throws IOException
+ protected short readShort(DataInput buffer) throws IOException
{
return EncodingUtils.readShort(buffer);
}
- protected void writeShort(DataOutputStream buffer, short s) throws IOException
+ protected void writeShort(DataOutput buffer, short s) throws IOException
{
EncodingUtils.writeShort(buffer, s);
}
- protected Content readContent(DataInputStream buffer)
+ protected Content readContent(DataInput buffer)
{
return null;
}
@@ -204,56 +206,56 @@ public abstract class AMQMethodBodyImpl implements AMQMethodBody
return 0;
}
- protected void writeContent(DataOutputStream buffer, Content body)
+ protected void writeContent(DataOutput buffer, Content body)
{
}
- protected byte readBitfield(DataInputStream buffer) throws IOException
+ protected byte readBitfield(DataInput buffer) throws IOException
{
return readByte(buffer);
}
- protected int readUnsignedShort(DataInputStream buffer) throws IOException
+ protected int readUnsignedShort(DataInput buffer) throws IOException
{
return buffer.readUnsignedShort();
}
- protected void writeBitfield(DataOutputStream buffer, byte bitfield0) throws IOException
+ protected void writeBitfield(DataOutput buffer, byte bitfield0) throws IOException
{
buffer.writeByte(bitfield0);
}
- protected void writeUnsignedShort(DataOutputStream buffer, int s) throws IOException
+ protected void writeUnsignedShort(DataOutput buffer, int s) throws IOException
{
EncodingUtils.writeUnsignedShort(buffer, s);
}
- protected long readUnsignedInteger(DataInputStream buffer) throws IOException
+ protected long readUnsignedInteger(DataInput buffer) throws IOException
{
return EncodingUtils.readUnsignedInteger(buffer);
}
- protected void writeUnsignedInteger(DataOutputStream buffer, long i) throws IOException
+ protected void writeUnsignedInteger(DataOutput buffer, long i) throws IOException
{
EncodingUtils.writeUnsignedInteger(buffer, i);
}
- protected short readUnsignedByte(DataInputStream buffer) throws IOException
+ protected short readUnsignedByte(DataInput buffer) throws IOException
{
return (short) buffer.readUnsignedByte();
}
- protected void writeUnsignedByte(DataOutputStream buffer, short unsignedByte) throws IOException
+ protected void writeUnsignedByte(DataOutput buffer, short unsignedByte) throws IOException
{
EncodingUtils.writeUnsignedByte(buffer, unsignedByte);
}
- protected long readTimestamp(DataInputStream buffer) throws IOException
+ protected long readTimestamp(DataInput buffer) throws IOException
{
return EncodingUtils.readTimestamp(buffer);
}
- protected void writeTimestamp(DataOutputStream buffer, long t) throws IOException
+ protected void writeTimestamp(DataOutput buffer, long t) throws IOException
{
EncodingUtils.writeTimestamp(buffer, t);
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyInstanceFactory.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyInstanceFactory.java
index df4d8bdcb6..88b1ca7189 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyInstanceFactory.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyInstanceFactory.java
@@ -21,11 +21,12 @@
package org.apache.qpid.framing;
-import java.io.DataInputStream;
+import org.apache.qpid.codec.MarkableDataInput;
+
import java.io.IOException;
public abstract interface AMQMethodBodyInstanceFactory
{
- public AMQMethodBody newInstance(DataInputStream buffer, long size) throws AMQFrameDecodingException, IOException;
+ public AMQMethodBody newInstance(MarkableDataInput buffer, long size) throws AMQFrameDecodingException, IOException;
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
index cc9a33f4cf..4ff7827d7f 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
@@ -24,8 +24,9 @@ package org.apache.qpid.framing;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.DataInput;
import java.io.DataInputStream;
-import java.io.DataOutputStream;
+import java.io.DataOutput;
import java.io.IOException;
import java.util.*;
import java.lang.ref.WeakReference;
@@ -93,22 +94,44 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
private AMQShortString substring(final int from, final int to)
{
- return new AMQShortString(_data, from+_offset, to+_offset);
+ return new AMQShortString(_data, from+_offset, to-from);
}
- private static final ThreadLocal<Map<AMQShortString, WeakReference<AMQShortString>>> _localInternMap =
- new ThreadLocal<Map<AMQShortString, WeakReference<AMQShortString>>>()
+ private static final int LOCAL_INTERN_CACHE_SIZE = 2048;
+
+ private static final ThreadLocal<Map<AMQShortString, AMQShortString>> _localInternMap =
+ new ThreadLocal<Map<AMQShortString, AMQShortString>>()
{
- protected Map<AMQShortString, WeakReference<AMQShortString>> initialValue()
+ protected Map<AMQShortString, AMQShortString> initialValue()
{
- return new WeakHashMap<AMQShortString, WeakReference<AMQShortString>>();
+ return new LinkedHashMap<AMQShortString, AMQShortString>()
+ {
+
+ protected boolean removeEldestEntry(Map.Entry<AMQShortString, AMQShortString> eldest)
+ {
+ return size() > LOCAL_INTERN_CACHE_SIZE;
+ }
+ };
};
};
private static final Map<AMQShortString, WeakReference<AMQShortString>> _globalInternMap =
new WeakHashMap<AMQShortString, WeakReference<AMQShortString>>();
+
+ private static final ThreadLocal<Map<String, WeakReference<AMQShortString>>> _localStringMap =
+ new ThreadLocal<Map<String, WeakReference<AMQShortString>>>()
+ {
+ protected Map<String, WeakReference<AMQShortString>> initialValue()
+ {
+ return new WeakHashMap<String, WeakReference<AMQShortString>>();
+ };
+ };
+
+ private static final Map<String, WeakReference<AMQShortString>> _globalStringMap =
+ new WeakHashMap<String, WeakReference<AMQShortString>>();
+
private static final Logger _logger = LoggerFactory.getLogger(AMQShortString.class);
private final byte[] _data;
@@ -200,32 +223,32 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
}
- private AMQShortString(DataInputStream data, final int length) throws IOException
+ private AMQShortString(DataInput data, final int length) throws IOException
{
if (length > MAX_LENGTH)
{
throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
}
byte[] dataBytes = new byte[length];
- data.read(dataBytes);
+ data.readFully(dataBytes);
_data = dataBytes;
_offset = 0;
_length = length;
}
- private AMQShortString(final byte[] data, final int from, final int to)
+ public AMQShortString(byte[] data, final int offset, final int length)
{
- if (data == null)
- {
- throw new NullPointerException("Cannot create AMQShortString with null data[]");
- }
- int length = to - from;
if (length > MAX_LENGTH)
{
throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
}
- _offset = from;
+ if (data == null)
+ {
+ throw new NullPointerException("Cannot create AMQShortString with null data[]");
+ }
+
+ _offset = offset;
_length = length;
_data = data;
}
@@ -234,9 +257,7 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
{
if(_data.length != _length)
{
- byte[] dataBytes = new byte[_length];
- System.arraycopy(_data,_offset,dataBytes,0,_length);
- return new AMQShortString(dataBytes,0,_length);
+ return copy();
}
else
{
@@ -265,7 +286,7 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
return new CharSubSequence(start, end);
}
- public static AMQShortString readFromBuffer(DataInputStream buffer) throws IOException
+ public static AMQShortString readFromBuffer(DataInput buffer) throws IOException
{
final int length = buffer.readUnsignedByte();
if (length == 0)
@@ -293,12 +314,12 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
}
}
- public void writeToBuffer(DataOutputStream buffer) throws IOException
+ public void writeToBuffer(DataOutput buffer) throws IOException
{
final int size = length();
//buffer.setAutoExpand(true);
- buffer.write((byte) size);
+ buffer.writeByte(size);
buffer.write(_data, _offset, size);
}
@@ -420,7 +441,17 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
{
if (_asString == null)
{
- _asString = new String(asChars());
+ AMQShortString intern = intern();
+
+ if(intern == this)
+ {
+ _asString = new String(asChars());
+ }
+ else
+ {
+ _asString = intern.asString();
+ }
+
}
return _asString;
}
@@ -609,42 +640,51 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
public AMQShortString intern()
{
+ return intern(true);
+ }
+
+ public AMQShortString intern(boolean keep)
+ {
hashCode();
- Map<AMQShortString, WeakReference<AMQShortString>> localMap =
+ Map<AMQShortString, AMQShortString> localMap =
_localInternMap.get();
- WeakReference<AMQShortString> ref = localMap.get(this);
- AMQShortString internString;
+ AMQShortString internString = localMap.get(this);
- if(ref != null)
+
+ if(internString != null)
{
- internString = ref.get();
- if(internString != null)
- {
- return internString;
- }
+ return internString;
}
+ WeakReference<AMQShortString> ref;
synchronized(_globalInternMap)
{
ref = _globalInternMap.get(this);
if((ref == null) || ((internString = ref.get()) == null))
{
- internString = shrink();
+ internString = keep ? shrink() : copy();
ref = new WeakReference(internString);
_globalInternMap.put(internString, ref);
}
}
- localMap.put(internString, ref);
+ localMap.put(internString, internString);
return internString;
}
+ private AMQShortString copy()
+ {
+ byte[] dataBytes = new byte[_length];
+ System.arraycopy(_data,_offset,dataBytes,0,_length);
+ return new AMQShortString(dataBytes,0,_length);
+ }
+
private int occurences(final byte delim)
{
int count = 0;
@@ -761,7 +801,46 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
public static AMQShortString valueOf(Object obj)
{
- return obj == null ? null : new AMQShortString(String.valueOf(obj));
+ return obj == null ? null : AMQShortString.valueOf(String.valueOf(obj));
+ }
+
+ public static AMQShortString valueOf(String obj)
+ {
+ if(obj == null)
+ {
+ return null;
+ }
+
+ Map<String, WeakReference<AMQShortString>> localMap =
+ _localStringMap.get();
+
+ WeakReference<AMQShortString> ref = localMap.get(obj);
+ AMQShortString internString;
+
+ if(ref != null)
+ {
+ internString = ref.get();
+ if(internString != null)
+ {
+ return internString;
+ }
+ }
+
+
+ synchronized(_globalStringMap)
+ {
+
+ ref = _globalStringMap.get(obj);
+ if((ref == null) || ((internString = ref.get()) == null))
+ {
+ internString = (new AMQShortString(obj)).intern();
+ ref = new WeakReference<AMQShortString>(internString);
+ _globalStringMap.put(obj, ref);
+ }
+
+ }
+ localMap.put(obj, ref);
+ return internString;
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQType.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQType.java
index f3da64e639..5c89af09c4 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQType.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQType.java
@@ -20,8 +20,8 @@
*/
package org.apache.qpid.framing;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
+import java.io.DataInput;
+import java.io.DataOutput;
import java.io.IOException;
import java.math.BigDecimal;
@@ -61,12 +61,12 @@ public enum AMQType
}
}
- public void writeValueImpl(Object value, DataOutputStream buffer) throws IOException
+ public void writeValueImpl(Object value, DataOutput buffer) throws IOException
{
EncodingUtils.writeLongStringBytes(buffer, (String) value);
}
- public Object readValueFromBuffer(DataInputStream buffer) throws IOException
+ public Object readValueFromBuffer(DataInput buffer) throws IOException
{
return EncodingUtils.readLongString(buffer);
}
@@ -107,12 +107,12 @@ public enum AMQType
}
}
- public void writeValueImpl(Object value, DataOutputStream buffer) throws IOException
+ public void writeValueImpl(Object value, DataOutput buffer) throws IOException
{
EncodingUtils.writeUnsignedInteger(buffer, (Long) value);
}
- public Object readValueFromBuffer(DataInputStream buffer) throws IOException
+ public Object readValueFromBuffer(DataInput buffer) throws IOException
{
return EncodingUtils.readUnsignedInteger(buffer);
}
@@ -138,7 +138,7 @@ public enum AMQType
}
}
- public void writeValueImpl(Object value, DataOutputStream buffer) throws IOException
+ public void writeValueImpl(Object value, DataOutput buffer) throws IOException
{
BigDecimal bd = (BigDecimal) value;
@@ -151,7 +151,7 @@ public enum AMQType
EncodingUtils.writeInteger(buffer, unscaled);
}
- public Object readValueFromBuffer(DataInputStream buffer) throws IOException
+ public Object readValueFromBuffer(DataInput buffer) throws IOException
{
byte places = EncodingUtils.readByte(buffer);
@@ -183,12 +183,12 @@ public enum AMQType
}
}
- public void writeValueImpl(Object value, DataOutputStream buffer) throws IOException
+ public void writeValueImpl(Object value, DataOutput buffer) throws IOException
{
EncodingUtils.writeLong(buffer, (Long) value);
}
- public Object readValueFromBuffer(DataInputStream buffer) throws IOException
+ public Object readValueFromBuffer(DataInput buffer) throws IOException
{
return EncodingUtils.readLong(buffer);
}
@@ -247,7 +247,7 @@ public enum AMQType
* @param value An instance of the type.
* @param buffer The byte buffer to write it to.
*/
- public void writeValueImpl(Object value, DataOutputStream buffer) throws IOException
+ public void writeValueImpl(Object value, DataOutput buffer) throws IOException
{
// Ensure that the value is a FieldTable.
if (!(value instanceof FieldTable))
@@ -268,7 +268,7 @@ public enum AMQType
*
* @return An instance of the type.
*/
- public Object readValueFromBuffer(DataInputStream buffer) throws IOException
+ public Object readValueFromBuffer(DataInput buffer) throws IOException
{
try
{
@@ -302,10 +302,10 @@ public enum AMQType
}
}
- public void writeValueImpl(Object value, DataOutputStream buffer)
+ public void writeValueImpl(Object value, DataOutput buffer)
{ }
- public Object readValueFromBuffer(DataInputStream buffer)
+ public Object readValueFromBuffer(DataInput buffer)
{
return null;
}
@@ -331,12 +331,12 @@ public enum AMQType
}
}
- public void writeValueImpl(Object value, DataOutputStream buffer) throws IOException
+ public void writeValueImpl(Object value, DataOutput buffer) throws IOException
{
EncodingUtils.writeLongstr(buffer, (byte[]) value);
}
- public Object readValueFromBuffer(DataInputStream buffer) throws IOException
+ public Object readValueFromBuffer(DataInput buffer) throws IOException
{
return EncodingUtils.readLongstr(buffer);
}
@@ -361,12 +361,12 @@ public enum AMQType
}
}
- public void writeValueImpl(Object value, DataOutputStream buffer) throws IOException
+ public void writeValueImpl(Object value, DataOutput buffer) throws IOException
{
EncodingUtils.writeLongStringBytes(buffer, (String) value);
}
- public Object readValueFromBuffer(DataInputStream buffer) throws IOException
+ public Object readValueFromBuffer(DataInput buffer) throws IOException
{
return EncodingUtils.readLongString(buffer);
}
@@ -392,12 +392,12 @@ public enum AMQType
}
}
- public void writeValueImpl(Object value, DataOutputStream buffer) throws IOException
+ public void writeValueImpl(Object value, DataOutput buffer) throws IOException
{
EncodingUtils.writeLongStringBytes(buffer, (String) value);
}
- public Object readValueFromBuffer(DataInputStream buffer) throws IOException
+ public Object readValueFromBuffer(DataInput buffer) throws IOException
{
return EncodingUtils.readLongString(buffer);
}
@@ -427,12 +427,12 @@ public enum AMQType
}
}
- public void writeValueImpl(Object value, DataOutputStream buffer) throws IOException
+ public void writeValueImpl(Object value, DataOutput buffer) throws IOException
{
EncodingUtils.writeBoolean(buffer, (Boolean) value);
}
- public Object readValueFromBuffer(DataInputStream buffer) throws IOException
+ public Object readValueFromBuffer(DataInput buffer) throws IOException
{
return EncodingUtils.readBoolean(buffer);
}
@@ -462,12 +462,12 @@ public enum AMQType
}
}
- public void writeValueImpl(Object value, DataOutputStream buffer) throws IOException
+ public void writeValueImpl(Object value, DataOutput buffer) throws IOException
{
EncodingUtils.writeChar(buffer, (Character) value);
}
- public Object readValueFromBuffer(DataInputStream buffer) throws IOException
+ public Object readValueFromBuffer(DataInput buffer) throws IOException
{
return EncodingUtils.readChar(buffer);
}
@@ -497,12 +497,12 @@ public enum AMQType
}
}
- public void writeValueImpl(Object value, DataOutputStream buffer) throws IOException
+ public void writeValueImpl(Object value, DataOutput buffer) throws IOException
{
EncodingUtils.writeByte(buffer, (Byte) value);
}
- public Object readValueFromBuffer(DataInputStream buffer) throws IOException
+ public Object readValueFromBuffer(DataInput buffer) throws IOException
{
return EncodingUtils.readByte(buffer);
}
@@ -536,12 +536,12 @@ public enum AMQType
}
}
- public void writeValueImpl(Object value, DataOutputStream buffer) throws IOException
+ public void writeValueImpl(Object value, DataOutput buffer) throws IOException
{
EncodingUtils.writeShort(buffer, (Short) value);
}
- public Object readValueFromBuffer(DataInputStream buffer) throws IOException
+ public Object readValueFromBuffer(DataInput buffer) throws IOException
{
return EncodingUtils.readShort(buffer);
}
@@ -578,12 +578,12 @@ public enum AMQType
}
}
- public void writeValueImpl(Object value, DataOutputStream buffer) throws IOException
+ public void writeValueImpl(Object value, DataOutput buffer) throws IOException
{
EncodingUtils.writeInteger(buffer, (Integer) value);
}
- public Object readValueFromBuffer(DataInputStream buffer) throws IOException
+ public Object readValueFromBuffer(DataInput buffer) throws IOException
{
return EncodingUtils.readInteger(buffer);
}
@@ -596,6 +596,22 @@ public enum AMQType
return EncodingUtils.encodedLongLength();
}
+ public int getEncodingSize(long value)
+ {
+ return EncodingUtils.encodedLongLength();
+ }
+
+ public AMQTypedValue asTypedValue(long value)
+ {
+ return AMQTypedValue.createAMQTypedValue(value);
+ }
+
+ public void writeToBuffer(long value, DataOutput buffer) throws IOException
+ {
+ buffer.writeByte(identifier());
+ EncodingUtils.writeLong(buffer, value);
+ }
+
public Object toNativeValue(Object value)
{
if (value instanceof Long)
@@ -625,12 +641,18 @@ public enum AMQType
}
}
- public void writeValueImpl(Object value, DataOutputStream buffer) throws IOException
+ public void writeValueImpl(Object value, DataOutput buffer) throws IOException
{
EncodingUtils.writeLong(buffer, (Long) value);
}
- public Object readValueFromBuffer(DataInputStream buffer) throws IOException
+ public long readLongFromBuffer(DataInput buffer) throws IOException
+ {
+ return EncodingUtils.readLong(buffer);
+ }
+
+
+ public Object readValueFromBuffer(DataInput buffer) throws IOException
{
return EncodingUtils.readLong(buffer);
}
@@ -660,12 +682,12 @@ public enum AMQType
}
}
- public void writeValueImpl(Object value, DataOutputStream buffer) throws IOException
+ public void writeValueImpl(Object value, DataOutput buffer) throws IOException
{
EncodingUtils.writeFloat(buffer, (Float) value);
}
- public Object readValueFromBuffer(DataInputStream buffer) throws IOException
+ public Object readValueFromBuffer(DataInput buffer) throws IOException
{
return EncodingUtils.readFloat(buffer);
}
@@ -699,12 +721,12 @@ public enum AMQType
}
}
- public void writeValueImpl(Object value, DataOutputStream buffer) throws IOException
+ public void writeValueImpl(Object value, DataOutput buffer) throws IOException
{
EncodingUtils.writeDouble(buffer, (Double) value);
}
- public Object readValueFromBuffer(DataInputStream buffer) throws IOException
+ public Object readValueFromBuffer(DataInput buffer) throws IOException
{
return EncodingUtils.readDouble(buffer);
}
@@ -761,7 +783,7 @@ public enum AMQType
*/
public AMQTypedValue asTypedValue(Object value)
{
- return new AMQTypedValue(this, toNativeValue(value));
+ return AMQTypedValue.createAMQTypedValue(this, toNativeValue(value));
}
/**
@@ -771,7 +793,7 @@ public enum AMQType
* @param value An instance of the type.
* @param buffer The byte buffer to write it to.
*/
- public void writeToBuffer(Object value, DataOutputStream buffer) throws IOException
+ public void writeToBuffer(Object value, DataOutput buffer) throws IOException
{
buffer.writeByte(identifier());
writeValueImpl(value, buffer);
@@ -783,7 +805,7 @@ public enum AMQType
* @param value An instance of the type.
* @param buffer The byte buffer to write it to.
*/
- abstract void writeValueImpl(Object value, DataOutputStream buffer) throws IOException;
+ abstract void writeValueImpl(Object value, DataOutput buffer) throws IOException;
/**
* Reads an instance of the type from a specified byte buffer.
@@ -792,5 +814,5 @@ public enum AMQType
*
* @return An instance of the type.
*/
- abstract Object readValueFromBuffer(DataInputStream buffer) throws IOException;
+ abstract Object readValueFromBuffer(DataInput buffer) throws IOException;
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQTypedValue.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQTypedValue.java
index 1dbedca362..f64164c10b 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQTypedValue.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQTypedValue.java
@@ -20,9 +20,7 @@
*/
package org.apache.qpid.framing;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
+import java.io.*;
import java.util.Date;
import java.util.Map;
import java.math.BigDecimal;
@@ -42,81 +40,223 @@ import java.math.BigDecimal;
* <tr><td> Extract the value from a fully typed AMQP value.
* </table>
*/
-public class AMQTypedValue
+public abstract class AMQTypedValue
{
- /** The type of the value. */
- private final AMQType _type;
- /** The Java native representation of the AMQP typed value. */
- private final Object _value;
+ public abstract AMQType getType();
- public AMQTypedValue(AMQType type, Object value)
+ public abstract Object getValue();
+
+ public abstract void writeToBuffer(DataOutput buffer) throws IOException;
+
+ public abstract int getEncodingSize();
+
+
+ private static final class GenericTypedValue extends AMQTypedValue
{
- if (type == null)
+ /** The type of the value. */
+ private final AMQType _type;
+
+ /** The Java native representation of the AMQP typed value. */
+ private final Object _value;
+
+ private GenericTypedValue(AMQType type, Object value)
{
- throw new NullPointerException("Cannot create a typed value with null type");
+ if (type == null)
+ {
+ throw new NullPointerException("Cannot create a typed value with null type");
+ }
+
+ _type = type;
+ _value = type.toNativeValue(value);
}
- _type = type;
- _value = type.toNativeValue(value);
- }
+ private GenericTypedValue(AMQType type, DataInput buffer) throws IOException
+ {
+ _type = type;
+ _value = type.readValueFromBuffer(buffer);
+ }
+
+
+ public AMQType getType()
+ {
+ return _type;
+ }
+
+ public Object getValue()
+ {
+ return _value;
+ }
+
+ public void writeToBuffer(DataOutput buffer) throws IOException
+ {
+ _type.writeToBuffer(_value, buffer);
+ }
+
+ public int getEncodingSize()
+ {
+ return _type.getEncodingSize(_value);
+ }
+
+
+ public String toString()
+ {
+ return "[" + getType() + ": " + getValue() + "]";
+ }
+
+
+ public boolean equals(Object o)
+ {
+ if(o instanceof GenericTypedValue)
+ {
+ GenericTypedValue other = (GenericTypedValue) o;
+ return _type == other._type && (_value == null ? other._value == null : _value.equals(other._value));
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public int hashCode()
+ {
+ return _type.hashCode() ^ (_value == null ? 0 : _value.hashCode());
+ }
- private AMQTypedValue(AMQType type, DataInputStream buffer) throws IOException
- {
- _type = type;
- _value = type.readValueFromBuffer(buffer);
}
- public AMQType getType()
+ private static final class LongTypedValue extends AMQTypedValue
{
- return _type;
+
+ private final long _value;
+
+ private LongTypedValue(long value)
+ {
+ _value = value;
+ }
+
+ public LongTypedValue(DataInput buffer) throws IOException
+ {
+ _value = EncodingUtils.readLong(buffer);
+ }
+
+ public AMQType getType()
+ {
+ return AMQType.LONG;
+ }
+
+
+ public Object getValue()
+ {
+ return _value;
+ }
+
+ public void writeToBuffer(DataOutput buffer) throws IOException
+ {
+ EncodingUtils.writeByte(buffer,AMQType.LONG.identifier());
+ EncodingUtils.writeLong(buffer,_value);
+ }
+
+
+ public int getEncodingSize()
+ {
+ return EncodingUtils.encodedLongLength();
+ }
}
- public Object getValue()
+ private static final class IntTypedValue extends AMQTypedValue
{
- return _value;
+ @Override
+ public String toString()
+ {
+ return "[INT: " + String.valueOf(_value) + "]";
+ }
+
+ private final int _value;
+
+ public IntTypedValue(int value)
+ {
+ _value = value;
+ }
+
+ public AMQType getType()
+ {
+ return AMQType.INT;
+ }
+
+
+ public Object getValue()
+ {
+ return _value;
+ }
+
+ public void writeToBuffer(DataOutput buffer) throws IOException
+ {
+ EncodingUtils.writeByte(buffer,AMQType.INT.identifier());
+ EncodingUtils.writeInteger(buffer, _value);
+ }
+
+
+ public int getEncodingSize()
+ {
+ return EncodingUtils.encodedIntegerLength();
+ }
}
- public void writeToBuffer(DataOutputStream buffer) throws IOException
+
+ public static AMQTypedValue readFromBuffer(DataInput buffer) throws IOException
{
- _type.writeToBuffer(_value, buffer);
+ AMQType type = AMQTypeMap.getType(buffer.readByte());
+
+ switch(type)
+ {
+ case LONG:
+ return new LongTypedValue(buffer);
+
+ case INT:
+ int value = EncodingUtils.readInteger(buffer);
+ return createAMQTypedValue(value);
+
+ default:
+ return new GenericTypedValue(type, buffer);
+ }
+
}
- public int getEncodingSize()
+ private static final AMQTypedValue[] INT_VALUES = new AMQTypedValue[16];
+ static
{
- return _type.getEncodingSize(_value);
+ for(int i = 0 ; i < 16; i ++)
+ {
+ INT_VALUES[i] = new IntTypedValue(i);
+ }
}
- public static AMQTypedValue readFromBuffer(DataInputStream buffer) throws IOException
+ public static AMQTypedValue createAMQTypedValue(int i)
{
- AMQType type = AMQTypeMap.getType(buffer.readByte());
-
- return new AMQTypedValue(type, buffer);
+ return (i & 0x0f) == i ? INT_VALUES[i] : new IntTypedValue(i);
}
- public String toString()
+
+ public static AMQTypedValue createAMQTypedValue(long value)
{
- return "[" + getType() + ": " + getValue() + "]";
+ return new LongTypedValue(value);
}
-
- public boolean equals(Object o)
+ public static AMQTypedValue createAMQTypedValue(AMQType type, Object value)
{
- if(o instanceof AMQTypedValue)
+ switch(type)
{
- AMQTypedValue other = (AMQTypedValue) o;
- return _type == other._type && (_value == null ? other._value == null : _value.equals(other._value));
- }
- else
- {
- return false;
+ case LONG:
+ return new LongTypedValue((Long) AMQType.LONG.toNativeValue(value));
+ case INT:
+ return new IntTypedValue((Integer) AMQType.INT.toNativeValue(value));
+
+ default:
+ return new GenericTypedValue(type, value);
}
}
- public int hashCode()
- {
- return _type.hashCode() ^ (_value == null ? 0 : _value.hashCode());
- }
public static AMQTypedValue toTypedValue(Object val)
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java
index 57622b5054..2739f7d14b 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java
@@ -20,8 +20,9 @@
*/
package org.apache.qpid.framing;
+import java.io.DataInput;
import java.io.DataInputStream;
-import java.io.DataOutputStream;
+import java.io.DataOutput;
import java.io.IOException;
import org.slf4j.Logger;
@@ -80,6 +81,7 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
private static final int USER_ID_MASK = 1 << 4;
private static final int APPLICATION_ID_MASK = 1 << 3;
private static final int CLUSTER_ID_MASK = 1 << 2;
+ private byte[] _encodedForm;
public BasicContentHeaderProperties()
@@ -87,6 +89,12 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
public int getPropertyListSize()
{
+ if(_encodedForm != null && (_headers == null || _headers.isClean()))
+ {
+ return _encodedForm.length;
+ }
+ else
+ {
int size = 0;
if ((_propertyFlags & (CONTENT_TYPE_MASK)) > 0)
@@ -167,6 +175,7 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
}
return size;
+ }
}
public void setPropertyFlags(int propertyFlags)
@@ -179,87 +188,94 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
return _propertyFlags;
}
- public void writePropertyListPayload(DataOutputStream buffer) throws IOException
+ public void writePropertyListPayload(DataOutput buffer) throws IOException
{
- if ((_propertyFlags & (CONTENT_TYPE_MASK)) != 0)
+ if(_encodedForm != null && (_headers == null || !_headers.isClean()))
{
- EncodingUtils.writeShortStringBytes(buffer, _contentType);
+ buffer.write(_encodedForm);
}
-
- if ((_propertyFlags & ENCODING_MASK) != 0)
+ else
{
- EncodingUtils.writeShortStringBytes(buffer, _encoding);
- }
+ if ((_propertyFlags & (CONTENT_TYPE_MASK)) != 0)
+ {
+ EncodingUtils.writeShortStringBytes(buffer, _contentType);
+ }
- if ((_propertyFlags & HEADERS_MASK) != 0)
- {
- EncodingUtils.writeFieldTableBytes(buffer, _headers);
- }
+ if ((_propertyFlags & ENCODING_MASK) != 0)
+ {
+ EncodingUtils.writeShortStringBytes(buffer, _encoding);
+ }
- if ((_propertyFlags & DELIVERY_MODE_MASK) != 0)
- {
- buffer.writeByte(_deliveryMode);
- }
+ if ((_propertyFlags & HEADERS_MASK) != 0)
+ {
+ EncodingUtils.writeFieldTableBytes(buffer, _headers);
+ }
- if ((_propertyFlags & PRIORITY_MASK) != 0)
- {
- buffer.writeByte(_priority);
- }
+ if ((_propertyFlags & DELIVERY_MODE_MASK) != 0)
+ {
+ buffer.writeByte(_deliveryMode);
+ }
- if ((_propertyFlags & CORRELATION_ID_MASK) != 0)
- {
- EncodingUtils.writeShortStringBytes(buffer, _correlationId);
- }
+ if ((_propertyFlags & PRIORITY_MASK) != 0)
+ {
+ buffer.writeByte(_priority);
+ }
- if ((_propertyFlags & REPLY_TO_MASK) != 0)
- {
- EncodingUtils.writeShortStringBytes(buffer, _replyTo);
- }
+ if ((_propertyFlags & CORRELATION_ID_MASK) != 0)
+ {
+ EncodingUtils.writeShortStringBytes(buffer, _correlationId);
+ }
- if ((_propertyFlags & EXPIRATION_MASK) != 0)
- {
- if (_expiration == 0L)
+ if ((_propertyFlags & REPLY_TO_MASK) != 0)
{
- EncodingUtils.writeShortStringBytes(buffer, ZERO_STRING);
+ EncodingUtils.writeShortStringBytes(buffer, _replyTo);
}
- else
+
+ if ((_propertyFlags & EXPIRATION_MASK) != 0)
{
- EncodingUtils.writeShortStringBytes(buffer, String.valueOf(_expiration));
+ if (_expiration == 0L)
+ {
+ EncodingUtils.writeShortStringBytes(buffer, ZERO_STRING);
+ }
+ else
+ {
+ EncodingUtils.writeShortStringBytes(buffer, String.valueOf(_expiration));
+ }
}
- }
- if ((_propertyFlags & MESSAGE_ID_MASK) != 0)
- {
- EncodingUtils.writeShortStringBytes(buffer, _messageId);
- }
+ if ((_propertyFlags & MESSAGE_ID_MASK) != 0)
+ {
+ EncodingUtils.writeShortStringBytes(buffer, _messageId);
+ }
- if ((_propertyFlags & TIMESTAMP_MASK) != 0)
- {
- EncodingUtils.writeTimestamp(buffer, _timestamp);
- }
+ if ((_propertyFlags & TIMESTAMP_MASK) != 0)
+ {
+ EncodingUtils.writeTimestamp(buffer, _timestamp);
+ }
- if ((_propertyFlags & TYPE_MASK) != 0)
- {
- EncodingUtils.writeShortStringBytes(buffer, _type);
- }
+ if ((_propertyFlags & TYPE_MASK) != 0)
+ {
+ EncodingUtils.writeShortStringBytes(buffer, _type);
+ }
- if ((_propertyFlags & USER_ID_MASK) != 0)
- {
- EncodingUtils.writeShortStringBytes(buffer, _userId);
- }
+ if ((_propertyFlags & USER_ID_MASK) != 0)
+ {
+ EncodingUtils.writeShortStringBytes(buffer, _userId);
+ }
- if ((_propertyFlags & APPLICATION_ID_MASK) != 0)
- {
- EncodingUtils.writeShortStringBytes(buffer, _appId);
- }
+ if ((_propertyFlags & APPLICATION_ID_MASK) != 0)
+ {
+ EncodingUtils.writeShortStringBytes(buffer, _appId);
+ }
- if ((_propertyFlags & CLUSTER_ID_MASK) != 0)
- {
- EncodingUtils.writeShortStringBytes(buffer, _clusterId);
+ if ((_propertyFlags & CLUSTER_ID_MASK) != 0)
+ {
+ EncodingUtils.writeShortStringBytes(buffer, _clusterId);
+ }
}
}
- public void populatePropertiesFromBuffer(DataInputStream buffer, int propertyFlags, int size) throws AMQFrameDecodingException, IOException
+ public void populatePropertiesFromBuffer(DataInput buffer, int propertyFlags, int size) throws AMQFrameDecodingException, IOException
{
_propertyFlags = propertyFlags;
@@ -268,26 +284,40 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
_logger.debug("Property flags: " + _propertyFlags);
}
- decode(buffer);
+ _encodedForm = new byte[size];
+ buffer.readFully(_encodedForm);
+
+ ByteArrayDataInput input = new ByteArrayDataInput(_encodedForm);
+
+ decode(input);
+
}
- private void decode(DataInputStream buffer) throws IOException, AMQFrameDecodingException
+ private void decode(ByteArrayDataInput buffer) throws IOException, AMQFrameDecodingException
{
// ByteBuffer buffer = ByteBuffer.wrap(_encodedForm);
+ int headersOffset = 0;
+
if ((_propertyFlags & (CONTENT_TYPE_MASK)) != 0)
{
- _contentType = EncodingUtils.readAMQShortString(buffer);
+ _contentType = buffer.readAMQShortString();
+ headersOffset += EncodingUtils.encodedShortStringLength(_contentType);
}
if ((_propertyFlags & ENCODING_MASK) != 0)
{
- _encoding = EncodingUtils.readAMQShortString(buffer);
+ _encoding = buffer.readAMQShortString();
+ headersOffset += EncodingUtils.encodedShortStringLength(_encoding);
}
if ((_propertyFlags & HEADERS_MASK) != 0)
{
- _headers = EncodingUtils.readFieldTable(buffer);
+ long length = EncodingUtils.readUnsignedInteger(buffer);
+
+ _headers = new FieldTable(_encodedForm, headersOffset+4, (int)length);
+
+ buffer.skipBytes((int)length);
}
if ((_propertyFlags & DELIVERY_MODE_MASK) != 0)
@@ -302,12 +332,12 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
if ((_propertyFlags & CORRELATION_ID_MASK) != 0)
{
- _correlationId = EncodingUtils.readAMQShortString(buffer);
+ _correlationId = buffer.readAMQShortString();
}
if ((_propertyFlags & REPLY_TO_MASK) != 0)
{
- _replyTo = EncodingUtils.readAMQShortString(buffer);
+ _replyTo = buffer.readAMQShortString();
}
if ((_propertyFlags & EXPIRATION_MASK) != 0)
@@ -317,7 +347,7 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
if ((_propertyFlags & MESSAGE_ID_MASK) != 0)
{
- _messageId = EncodingUtils.readAMQShortString(buffer);
+ _messageId = buffer.readAMQShortString();
}
if ((_propertyFlags & TIMESTAMP_MASK) != 0)
@@ -327,22 +357,22 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
if ((_propertyFlags & TYPE_MASK) != 0)
{
- _type = EncodingUtils.readAMQShortString(buffer);
+ _type = buffer.readAMQShortString();
}
if ((_propertyFlags & USER_ID_MASK) != 0)
{
- _userId = EncodingUtils.readAMQShortString(buffer);
+ _userId = buffer.readAMQShortString();
}
if ((_propertyFlags & APPLICATION_ID_MASK) != 0)
{
- _appId = EncodingUtils.readAMQShortString(buffer);
+ _appId = buffer.readAMQShortString();
}
if ((_propertyFlags & CLUSTER_ID_MASK) != 0)
{
- _clusterId = EncodingUtils.readAMQShortString(buffer);
+ _clusterId = buffer.readAMQShortString();
}
@@ -363,11 +393,12 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
{
_propertyFlags |= (CONTENT_TYPE_MASK);
_contentType = contentType;
+ _encodedForm = null;
}
public void setContentType(String contentType)
{
- setContentType((contentType == null) ? null : new AMQShortString(contentType));
+ setContentType((contentType == null) ? null : AMQShortString.valueOf(contentType));
}
public String getEncodingAsString()
@@ -384,13 +415,15 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
public void setEncoding(String encoding)
{
_propertyFlags |= ENCODING_MASK;
- _encoding = (encoding == null) ? null : new AMQShortString(encoding);
+ _encoding = (encoding == null) ? null : AMQShortString.valueOf(encoding);
+ _encodedForm = null;
}
public void setEncoding(AMQShortString encoding)
{
_propertyFlags |= ENCODING_MASK;
_encoding = encoding;
+ _encodedForm = null;
}
public FieldTable getHeaders()
@@ -407,6 +440,7 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
{
_propertyFlags |= HEADERS_MASK;
_headers = headers;
+ _encodedForm = null;
}
public byte getDeliveryMode()
@@ -418,6 +452,7 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
{
_propertyFlags |= DELIVERY_MODE_MASK;
_deliveryMode = deliveryMode;
+ _encodedForm = null;
}
public byte getPriority()
@@ -429,6 +464,7 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
{
_propertyFlags |= PRIORITY_MASK;
_priority = priority;
+ _encodedForm = null;
}
public AMQShortString getCorrelationId()
@@ -443,13 +479,14 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
public void setCorrelationId(String correlationId)
{
- setCorrelationId((correlationId == null) ? null : new AMQShortString(correlationId));
+ setCorrelationId((correlationId == null) ? null : AMQShortString.valueOf(correlationId));
}
public void setCorrelationId(AMQShortString correlationId)
{
_propertyFlags |= CORRELATION_ID_MASK;
_correlationId = correlationId;
+ _encodedForm = null;
}
public String getReplyToAsString()
@@ -464,13 +501,14 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
public void setReplyTo(String replyTo)
{
- setReplyTo((replyTo == null) ? null : new AMQShortString(replyTo));
+ setReplyTo((replyTo == null) ? null : AMQShortString.valueOf(replyTo));
}
public void setReplyTo(AMQShortString replyTo)
{
_propertyFlags |= REPLY_TO_MASK;
_replyTo = replyTo;
+ _encodedForm = null;
}
public long getExpiration()
@@ -482,6 +520,7 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
{
_propertyFlags |= EXPIRATION_MASK;
_expiration = expiration;
+ _encodedForm = null;
}
public AMQShortString getMessageId()
@@ -498,12 +537,14 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
{
_propertyFlags |= MESSAGE_ID_MASK;
_messageId = (messageId == null) ? null : new AMQShortString(messageId);
+ _encodedForm = null;
}
public void setMessageId(AMQShortString messageId)
{
_propertyFlags |= MESSAGE_ID_MASK;
_messageId = messageId;
+ _encodedForm = null;
}
public long getTimestamp()
@@ -515,6 +556,7 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
{
_propertyFlags |= TIMESTAMP_MASK;
_timestamp = timestamp;
+ _encodedForm = null;
}
public String getTypeAsString()
@@ -529,13 +571,14 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
public void setType(String type)
{
- setType((type == null) ? null : new AMQShortString(type));
+ setType((type == null) ? null : AMQShortString.valueOf(type));
}
public void setType(AMQShortString type)
{
_propertyFlags |= TYPE_MASK;
_type = type;
+ _encodedForm = null;
}
public String getUserIdAsString()
@@ -550,13 +593,14 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
public void setUserId(String userId)
{
- setUserId((userId == null) ? null : new AMQShortString(userId));
+ setUserId((userId == null) ? null : AMQShortString.valueOf(userId));
}
public void setUserId(AMQShortString userId)
{
_propertyFlags |= USER_ID_MASK;
_userId = userId;
+ _encodedForm = null;
}
public String getAppIdAsString()
@@ -571,13 +615,14 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
public void setAppId(String appId)
{
- setAppId((appId == null) ? null : new AMQShortString(appId));
+ setAppId((appId == null) ? null : AMQShortString.valueOf(appId));
}
public void setAppId(AMQShortString appId)
{
_propertyFlags |= APPLICATION_ID_MASK;
_appId = appId;
+ _encodedForm = null;
}
public String getClusterIdAsString()
@@ -592,13 +637,14 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
public void setClusterId(String clusterId)
{
- setClusterId((clusterId == null) ? null : new AMQShortString(clusterId));
+ setClusterId((clusterId == null) ? null : AMQShortString.valueOf(clusterId));
}
public void setClusterId(AMQShortString clusterId)
{
_propertyFlags |= CLUSTER_ID_MASK;
_clusterId = clusterId;
+ _encodedForm = null;
}
public String toString()
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/BodyFactory.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/BodyFactory.java
index f9580d82b1..554e9373d8 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/BodyFactory.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/BodyFactory.java
@@ -20,7 +20,8 @@
*/
package org.apache.qpid.framing;
-import java.io.DataInputStream;
+import org.apache.qpid.codec.MarkableDataInput;
+
import java.io.IOException;
/**
@@ -28,5 +29,5 @@ import java.io.IOException;
*/
public interface BodyFactory
{
- AMQBody createBody(DataInputStream in, long bodySize) throws AMQFrameDecodingException, IOException;
+ AMQBody createBody(MarkableDataInput in, long bodySize) throws AMQFrameDecodingException, IOException;
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/ByteArrayDataInput.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/ByteArrayDataInput.java
new file mode 100644
index 0000000000..656185629b
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/ByteArrayDataInput.java
@@ -0,0 +1,174 @@
+package org.apache.qpid.framing;
+
+import org.apache.qpid.codec.MarkableDataInput;
+
+import java.io.IOException;
+
+public class ByteArrayDataInput implements ExtendedDataInput, MarkableDataInput
+{
+ private byte[] _data;
+ private int _offset;
+ private int _length;
+ private int _origin;
+ private int _mark;
+
+ public ByteArrayDataInput(byte[] data)
+ {
+ this(data,0, data.length);
+ }
+
+ public ByteArrayDataInput(byte[] data, int offset, int length)
+ {
+ _data = data;
+ _offset = offset;
+ _length = length;
+ _origin = offset;
+ _mark = 0;
+ }
+
+ public void readFully(byte[] b)
+ {
+ System.arraycopy(_data,_offset,b,0,b.length);
+ _offset+=b.length;
+ }
+
+ public void readFully(byte[] b, int off, int len)
+ {
+ System.arraycopy(_data,_offset,b,off,len);
+ _offset+=len;
+ }
+
+ public int skipBytes(int n)
+ {
+ return _offset+=n;
+ }
+
+ public boolean readBoolean()
+ {
+ return _data[_offset++] != 0;
+ }
+
+ public byte readByte()
+ {
+ return _data[_offset++];
+ }
+
+ public int readUnsignedByte()
+ {
+ return ((int)_data[_offset++]) & 0xFF;
+ }
+
+ public short readShort()
+ {
+ return (short) (((((int)_data[_offset++]) << 8) & 0xFF00) | (((int)_data[_offset++]) & 0xFF));
+ }
+
+ public int readUnsignedShort()
+ {
+ return (((((int)_data[_offset++]) << 8) & 0xFF00) | (((int)_data[_offset++]) & 0xFF));
+ }
+
+ public char readChar()
+ {
+ return (char) (((((int)_data[_offset++]) << 8) & 0xFF00) | (((int)_data[_offset++]) & 0xFF));
+ }
+
+ public int readInt()
+ {
+ return ((((int)_data[_offset++]) << 24) & 0xFF000000)
+ | ((((int)_data[_offset++]) << 16) & 0xFF0000)
+ | ((((int)_data[_offset++]) << 8) & 0xFF00)
+ | (((int)_data[_offset++]) & 0xFF);
+ }
+
+ public long readLong()
+ {
+ return ((((long)_data[_offset++]) << 56) & 0xFF00000000000000L)
+ | ((((long)_data[_offset++]) << 48) & 0xFF000000000000L)
+ | ((((long)_data[_offset++]) << 40) & 0xFF0000000000L)
+ | ((((long)_data[_offset++]) << 32) & 0xFF00000000L)
+ | ((((long)_data[_offset++]) << 24) & 0xFF000000L)
+ | ((((long)_data[_offset++]) << 16) & 0xFF0000L)
+ | ((((long)_data[_offset++]) << 8) & 0xFF00L)
+ | (((long)_data[_offset++]) & 0xFFL);
+ }
+
+ public float readFloat()
+ {
+ return Float.intBitsToFloat(readInt());
+ }
+
+ public double readDouble()
+ {
+ return Double.longBitsToDouble(readLong());
+ }
+
+ public AMQShortString readAMQShortString()
+ {
+ int length = _data[_offset++] & 0xff;
+ if(length == 0)
+ {
+ return null;
+ }
+ else
+ {
+ final AMQShortString amqShortString = new AMQShortString(_data, _offset, length);
+ _offset+=length;
+ return amqShortString;
+ }
+ }
+
+ public String readLine()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public String readUTF()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int available()
+ {
+ return (_origin+_length)-_offset;
+ }
+
+
+ public long skip(long i)
+ {
+ _offset+=i;
+ return i;
+ }
+
+ public int read(byte[] b)
+ {
+ readFully(b);
+ return b.length;
+ }
+
+ public int position()
+ {
+ return _offset - _origin;
+ }
+
+ public void position(int position)
+ {
+ _offset = position + _origin;
+ }
+
+ public int length()
+ {
+ return _length;
+ }
+
+
+ public void mark(int readAhead)
+ {
+ _mark = _offset-_origin;
+ }
+
+ public void reset()
+ {
+ _offset = _origin + _mark;
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/CompositeAMQDataBlock.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/CompositeAMQDataBlock.java
index 15bc20c52d..098e3652ad 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/CompositeAMQDataBlock.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/CompositeAMQDataBlock.java
@@ -20,7 +20,7 @@
*/
package org.apache.qpid.framing;
-import java.io.DataOutputStream;
+import java.io.DataOutput;
import java.io.IOException;
public class CompositeAMQDataBlock extends AMQDataBlock implements EncodableAMQDataBlock
@@ -50,7 +50,7 @@ public class CompositeAMQDataBlock extends AMQDataBlock implements EncodableAMQD
return frameSize;
}
- public void writePayload(DataOutputStream buffer) throws IOException
+ public void writePayload(DataOutput buffer) throws IOException
{
for (int i = 0; i < _blocks.length; i++)
{
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java
index aedb35f92a..541d104dc9 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java
@@ -20,9 +20,11 @@
*/
package org.apache.qpid.framing;
+import java.io.DataInput;
import java.io.DataInputStream;
-import java.io.DataOutputStream;
+import java.io.DataOutput;
import java.io.IOException;
+import java.nio.ByteBuffer;
import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
import org.apache.qpid.AMQException;
@@ -37,10 +39,10 @@ public class ContentBody implements AMQBody
{
}
- public ContentBody(DataInputStream buffer, long size) throws AMQFrameDecodingException, IOException
+ public ContentBody(DataInput buffer, long size) throws AMQFrameDecodingException, IOException
{
_payload = new byte[(int)size];
- buffer.read(_payload);
+ buffer.readFully(_payload);
}
@@ -59,7 +61,7 @@ public class ContentBody implements AMQBody
return _payload == null ? 0 : _payload.length;
}
- public void writePayload(DataOutputStream buffer) throws IOException
+ public void writePayload(DataOutput buffer) throws IOException
{
buffer.write(_payload);
}
@@ -84,11 +86,62 @@ public class ContentBody implements AMQBody
{
}
+ private static class BufferContentBody implements AMQBody
+ {
+ private final int _length;
+ private final int _offset;
+ private final ByteBuffer _buf;
+
+ private BufferContentBody( ByteBuffer buf, int offset, int length)
+ {
+ _length = length;
+ _offset = offset;
+ _buf = buf;
+ }
+
+ public byte getFrameType()
+ {
+ return TYPE;
+ }
+
+
+ public int getSize()
+ {
+ return _length;
+ }
+ public void writePayload(DataOutput buffer) throws IOException
+ {
+ if(_buf.hasArray())
+ {
+ buffer.write(_buf.array(), _buf.arrayOffset() + _offset, _length);
+ }
+ else
+ {
+ byte[] data = new byte[_length];
+ ByteBuffer buf = _buf.duplicate();
+
+ buf.position(_offset);
+ buf.limit(_offset+_length);
+ buf.get(data);
+ buffer.write(data);
+ }
+ }
+
+
+ public void handle(int channelId, AMQVersionAwareProtocolSession amqProtocolSession) throws AMQException
+ {
+ throw new RuntimeException("Buffered Body only to be used for outgoing data");
+ }
+ }
+
+ public static AMQFrame createAMQFrame(int channelId, ByteBuffer buf, int offset, int length)
+ {
+ return new AMQFrame(channelId, new BufferContentBody(buf, offset, length));
+ }
public static AMQFrame createAMQFrame(int channelId, ContentBody body)
{
- final AMQFrame frame = new AMQFrame(channelId, body);
- return frame;
+ return new AMQFrame(channelId, body);
}
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentBodyFactory.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentBodyFactory.java
index a0b030ab6b..de2ffe9755 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentBodyFactory.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentBodyFactory.java
@@ -20,9 +20,9 @@
*/
package org.apache.qpid.framing;
-import java.io.DataInputStream;
import java.io.IOException;
+import org.apache.qpid.codec.MarkableDataInput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,7 +42,7 @@ public class ContentBodyFactory implements BodyFactory
_log.debug("Creating content body factory");
}
- public AMQBody createBody(DataInputStream in, long bodySize) throws AMQFrameDecodingException, IOException
+ public AMQBody createBody(MarkableDataInput in, long bodySize) throws AMQFrameDecodingException, IOException
{
return new ContentBody(in, bodySize);
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java
index 18d0f26152..8a2ad53157 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java
@@ -20,8 +20,9 @@
*/
package org.apache.qpid.framing;
+import java.io.DataInput;
import java.io.DataInputStream;
-import java.io.DataOutputStream;
+import java.io.DataOutput;
import java.io.IOException;
import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
@@ -45,7 +46,7 @@ public class ContentHeaderBody implements AMQBody
{
}
- public ContentHeaderBody(DataInputStream buffer, long size) throws AMQFrameDecodingException, IOException
+ public ContentHeaderBody(DataInput buffer, long size) throws AMQFrameDecodingException, IOException
{
classId = buffer.readUnsignedShort();
weight = buffer.readUnsignedShort();
@@ -106,7 +107,7 @@ public class ContentHeaderBody implements AMQBody
return 2 + 2 + 8 + 2 + properties.getPropertyListSize();
}
- public void writePayload(DataOutputStream buffer) throws IOException
+ public void writePayload(DataOutput buffer) throws IOException
{
EncodingUtils.writeUnsignedShort(buffer, classId);
EncodingUtils.writeUnsignedShort(buffer, weight);
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBodyFactory.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBodyFactory.java
index a474e337b7..c3e4c69ec0 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBodyFactory.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBodyFactory.java
@@ -20,9 +20,9 @@
*/
package org.apache.qpid.framing;
-import java.io.DataInputStream;
import java.io.IOException;
+import org.apache.qpid.codec.MarkableDataInput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,7 +42,7 @@ public class ContentHeaderBodyFactory implements BodyFactory
_log.debug("Creating content header body factory");
}
- public AMQBody createBody(DataInputStream in, long bodySize) throws AMQFrameDecodingException, IOException
+ public AMQBody createBody(MarkableDataInput in, long bodySize) throws AMQFrameDecodingException, IOException
{
// all content headers are the same - it is only the properties that differ.
// the content header body further delegates construction of properties
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderProperties.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderProperties.java
index 237929f9a3..ea8358a538 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderProperties.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderProperties.java
@@ -20,8 +20,9 @@
*/
package org.apache.qpid.framing;
+import java.io.DataInput;
import java.io.DataInputStream;
-import java.io.DataOutputStream;
+import java.io.DataOutput;
import java.io.IOException;
@@ -35,7 +36,7 @@ public interface ContentHeaderProperties
* Writes the property list to the buffer, in a suitably encoded form.
* @param buffer The buffer to write to
*/
- void writePropertyListPayload(DataOutputStream buffer) throws IOException;
+ void writePropertyListPayload(DataOutput buffer) throws IOException;
/**
* Populates the properties from buffer.
@@ -43,7 +44,7 @@ public interface ContentHeaderProperties
* @param propertyFlags he property flags.
* @throws AMQFrameDecodingException when the buffer does not contain valid data
*/
- void populatePropertiesFromBuffer(DataInputStream buffer, int propertyFlags, int size)
+ void populatePropertiesFromBuffer(DataInput buffer, int propertyFlags, int size)
throws AMQFrameDecodingException, IOException;
/**
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java
index 43ee8cd1f1..48bd52858d 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.framing;
+import java.io.DataInput;
import java.io.DataInputStream;
import java.io.IOException;
@@ -39,7 +40,7 @@ public class ContentHeaderPropertiesFactory
}
public ContentHeaderProperties createContentHeaderProperties(int classId, int propertyFlags,
- DataInputStream buffer, int size)
+ DataInput buffer, int size)
throws AMQFrameDecodingException, IOException
{
ContentHeaderProperties properties;
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java
index 2d7e27405c..e018407509 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java
@@ -219,7 +219,7 @@ public class EncodingUtils
return 0;
}
- public static void writeShortStringBytes(DataOutputStream buffer, String s) throws IOException
+ public static void writeShortStringBytes(DataOutput buffer, String s) throws IOException
{
if (s != null)
{
@@ -243,7 +243,7 @@ public class EncodingUtils
}
}
- public static void writeShortStringBytes(DataOutputStream buffer, AMQShortString s) throws IOException
+ public static void writeShortStringBytes(DataOutput buffer, AMQShortString s) throws IOException
{
if (s != null)
{
@@ -257,7 +257,7 @@ public class EncodingUtils
}
}
- public static void writeLongStringBytes(DataOutputStream buffer, String s) throws IOException
+ public static void writeLongStringBytes(DataOutput buffer, String s) throws IOException
{
assert (s == null) || (s.length() <= 0xFFFE);
if (s != null)
@@ -279,7 +279,7 @@ public class EncodingUtils
}
}
- public static void writeLongStringBytes(DataOutputStream buffer, char[] s) throws IOException
+ public static void writeLongStringBytes(DataOutput buffer, char[] s) throws IOException
{
assert (s == null) || (s.length <= 0xFFFE);
if (s != null)
@@ -300,7 +300,7 @@ public class EncodingUtils
}
}
- public static void writeLongStringBytes(DataOutputStream buffer, byte[] bytes) throws IOException
+ public static void writeLongStringBytes(DataOutput buffer, byte[] bytes) throws IOException
{
assert (bytes == null) || (bytes.length <= 0xFFFE);
if (bytes != null)
@@ -314,13 +314,13 @@ public class EncodingUtils
}
}
- public static void writeUnsignedByte(DataOutputStream buffer, short b) throws IOException
+ public static void writeUnsignedByte(DataOutput buffer, short b) throws IOException
{
byte bv = (byte) b;
buffer.write(bv);
}
- public static void writeUnsignedShort(DataOutputStream buffer, int s) throws IOException
+ public static void writeUnsignedShort(DataOutput buffer, int s) throws IOException
{
// TODO: Is this comparison safe? Do I need to cast RHS to long?
if (s < Short.MAX_VALUE)
@@ -340,7 +340,7 @@ public class EncodingUtils
return 4;
}
- public static void writeUnsignedInteger(DataOutputStream buffer, long l) throws IOException
+ public static void writeUnsignedInteger(DataOutput buffer, long l) throws IOException
{
// TODO: Is this comparison safe? Do I need to cast RHS to long?
if (l < Integer.MAX_VALUE)
@@ -360,7 +360,7 @@ public class EncodingUtils
}
}
- public static void writeFieldTableBytes(DataOutputStream buffer, FieldTable table) throws IOException
+ public static void writeFieldTableBytes(DataOutput buffer, FieldTable table) throws IOException
{
if (table != null)
{
@@ -372,12 +372,12 @@ public class EncodingUtils
}
}
- public static void writeContentBytes(DataOutputStream buffer, Content content)
+ public static void writeContentBytes(DataOutput buffer, Content content)
{
// TODO: New Content class required for AMQP 0-9.
}
- public static void writeBooleans(DataOutputStream buffer, boolean[] values) throws IOException
+ public static void writeBooleans(DataOutput buffer, boolean[] values) throws IOException
{
byte packedValue = 0;
for (int i = 0; i < values.length; i++)
@@ -391,13 +391,13 @@ public class EncodingUtils
buffer.write(packedValue);
}
- public static void writeBooleans(DataOutputStream buffer, boolean value) throws IOException
+ public static void writeBooleans(DataOutput buffer, boolean value) throws IOException
{
buffer.write(value ? (byte) 1 : (byte) 0);
}
- public static void writeBooleans(DataOutputStream buffer, boolean value0, boolean value1) throws IOException
+ public static void writeBooleans(DataOutput buffer, boolean value0, boolean value1) throws IOException
{
byte packedValue = value0 ? (byte) 1 : (byte) 0;
@@ -409,7 +409,7 @@ public class EncodingUtils
buffer.write(packedValue);
}
- public static void writeBooleans(DataOutputStream buffer, boolean value0, boolean value1, boolean value2) throws IOException
+ public static void writeBooleans(DataOutput buffer, boolean value0, boolean value1, boolean value2) throws IOException
{
byte packedValue = value0 ? (byte) 1 : (byte) 0;
@@ -426,7 +426,7 @@ public class EncodingUtils
buffer.write(packedValue);
}
- public static void writeBooleans(DataOutputStream buffer, boolean value0, boolean value1, boolean value2, boolean value3) throws IOException
+ public static void writeBooleans(DataOutput buffer, boolean value0, boolean value1, boolean value2, boolean value3) throws IOException
{
byte packedValue = value0 ? (byte) 1 : (byte) 0;
@@ -448,7 +448,7 @@ public class EncodingUtils
buffer.write(packedValue);
}
- public static void writeBooleans(DataOutputStream buffer, boolean value0, boolean value1, boolean value2, boolean value3,
+ public static void writeBooleans(DataOutput buffer, boolean value0, boolean value1, boolean value2, boolean value3,
boolean value4) throws IOException
{
byte packedValue = value0 ? (byte) 1 : (byte) 0;
@@ -476,7 +476,7 @@ public class EncodingUtils
buffer.write(packedValue);
}
- public static void writeBooleans(DataOutputStream buffer, boolean value0, boolean value1, boolean value2, boolean value3,
+ public static void writeBooleans(DataOutput buffer, boolean value0, boolean value1, boolean value2, boolean value3,
boolean value4, boolean value5) throws IOException
{
byte packedValue = value0 ? (byte) 1 : (byte) 0;
@@ -509,7 +509,7 @@ public class EncodingUtils
buffer.write(packedValue);
}
- public static void writeBooleans(DataOutputStream buffer, boolean value0, boolean value1, boolean value2, boolean value3,
+ public static void writeBooleans(DataOutput buffer, boolean value0, boolean value1, boolean value2, boolean value3,
boolean value4, boolean value5, boolean value6) throws IOException
{
byte packedValue = value0 ? (byte) 1 : (byte) 0;
@@ -547,7 +547,7 @@ public class EncodingUtils
buffer.write(packedValue);
}
- public static void writeBooleans(DataOutputStream buffer, boolean value0, boolean value1, boolean value2, boolean value3,
+ public static void writeBooleans(DataOutput buffer, boolean value0, boolean value1, boolean value2, boolean value3,
boolean value4, boolean value5, boolean value6, boolean value7) throws IOException
{
byte packedValue = value0 ? (byte) 1 : (byte) 0;
@@ -596,7 +596,7 @@ public class EncodingUtils
* @param buffer
* @param data
*/
- public static void writeLongstr(DataOutputStream buffer, byte[] data) throws IOException
+ public static void writeLongstr(DataOutput buffer, byte[] data) throws IOException
{
if (data != null)
{
@@ -609,12 +609,12 @@ public class EncodingUtils
}
}
- public static void writeTimestamp(DataOutputStream buffer, long timestamp) throws IOException
+ public static void writeTimestamp(DataOutput buffer, long timestamp) throws IOException
{
writeLong(buffer, timestamp);
}
- public static boolean[] readBooleans(DataInputStream buffer) throws IOException
+ public static boolean[] readBooleans(DataInput buffer) throws IOException
{
final byte packedValue = buffer.readByte();
if (packedValue == 0)
@@ -641,7 +641,7 @@ public class EncodingUtils
return result;
}
- public static FieldTable readFieldTable(DataInputStream buffer) throws AMQFrameDecodingException, IOException
+ public static FieldTable readFieldTable(DataInput buffer) throws AMQFrameDecodingException, IOException
{
long length = ((long)(buffer.readInt())) & 0xFFFFFFFFL;
if (length == 0)
@@ -654,19 +654,19 @@ public class EncodingUtils
}
}
- public static Content readContent(DataInputStream buffer) throws AMQFrameDecodingException
+ public static Content readContent(DataInput buffer) throws AMQFrameDecodingException
{
// TODO: New Content class required for AMQP 0-9.
return null;
}
- public static AMQShortString readAMQShortString(DataInputStream buffer) throws IOException
+ public static AMQShortString readAMQShortString(DataInput buffer) throws IOException
{
return AMQShortString.readFromBuffer(buffer);
}
- public static String readShortString(DataInputStream buffer) throws IOException
+ public static String readShortString(DataInput buffer) throws IOException
{
short length = (short) (((short)buffer.readByte()) & 0xFF);
if (length == 0)
@@ -681,7 +681,7 @@ public class EncodingUtils
// this approach here is valid since we know that all the chars are
// ASCII (0-127)
byte[] stringBytes = new byte[length];
- buffer.read(stringBytes, 0, length);
+ buffer.readFully(stringBytes, 0, length);
char[] stringChars = new char[length];
for (int i = 0; i < stringChars.length; i++)
{
@@ -692,7 +692,7 @@ public class EncodingUtils
}
}
- public static String readLongString(DataInputStream buffer) throws IOException
+ public static String readLongString(DataInput buffer) throws IOException
{
long length = ((long)(buffer.readInt())) & 0xFFFFFFFFL;
if (length == 0)
@@ -707,7 +707,7 @@ public class EncodingUtils
// this approach here is valid since we know that all the chars are
// ASCII (0-127)
byte[] stringBytes = new byte[(int) length];
- buffer.read(stringBytes, 0, (int) length);
+ buffer.readFully(stringBytes, 0, (int) length);
char[] stringChars = new char[(int) length];
for (int i = 0; i < stringChars.length; i++)
{
@@ -718,7 +718,7 @@ public class EncodingUtils
}
}
- public static byte[] readLongstr(DataInputStream buffer) throws IOException
+ public static byte[] readLongstr(DataInput buffer) throws IOException
{
long length = ((long)(buffer.readInt())) & 0xFFFFFFFFL;
if (length == 0)
@@ -728,13 +728,13 @@ public class EncodingUtils
else
{
byte[] result = new byte[(int) length];
- buffer.read(result);
+ buffer.readFully(result);
return result;
}
}
- public static long readTimestamp(DataInputStream buffer) throws IOException
+ public static long readTimestamp(DataInput buffer) throws IOException
{
// Discard msb from AMQ timestamp
// buffer.getUnsignedInt();
@@ -818,12 +818,12 @@ public class EncodingUtils
// AMQP_BOOLEAN_PROPERTY_PREFIX
- public static void writeBoolean(DataOutputStream buffer, Boolean aBoolean) throws IOException
+ public static void writeBoolean(DataOutput buffer, boolean aBoolean) throws IOException
{
buffer.write(aBoolean ? 1 : 0);
}
- public static boolean readBoolean(DataInputStream buffer) throws IOException
+ public static boolean readBoolean(DataInput buffer) throws IOException
{
byte packedValue = buffer.readByte();
@@ -836,12 +836,12 @@ public class EncodingUtils
}
// AMQP_BYTE_PROPERTY_PREFIX
- public static void writeByte(DataOutputStream buffer, Byte aByte) throws IOException
+ public static void writeByte(DataOutput buffer, byte aByte) throws IOException
{
buffer.writeByte(aByte);
}
- public static byte readByte(DataInputStream buffer) throws IOException
+ public static byte readByte(DataInput buffer) throws IOException
{
return buffer.readByte();
}
@@ -852,12 +852,12 @@ public class EncodingUtils
}
// AMQP_SHORT_PROPERTY_PREFIX
- public static void writeShort(DataOutputStream buffer, Short aShort) throws IOException
+ public static void writeShort(DataOutput buffer, short aShort) throws IOException
{
buffer.writeShort(aShort);
}
- public static short readShort(DataInputStream buffer) throws IOException
+ public static short readShort(DataInput buffer) throws IOException
{
return buffer.readShort();
}
@@ -868,12 +868,12 @@ public class EncodingUtils
}
// INTEGER_PROPERTY_PREFIX
- public static void writeInteger(DataOutputStream buffer, Integer aInteger) throws IOException
+ public static void writeInteger(DataOutput buffer, int aInteger) throws IOException
{
buffer.writeInt(aInteger);
}
- public static int readInteger(DataInputStream buffer) throws IOException
+ public static int readInteger(DataInput buffer) throws IOException
{
return buffer.readInt();
}
@@ -884,12 +884,12 @@ public class EncodingUtils
}
// AMQP_LONG_PROPERTY_PREFIX
- public static void writeLong(DataOutputStream buffer, Long aLong) throws IOException
+ public static void writeLong(DataOutput buffer, long aLong) throws IOException
{
buffer.writeLong(aLong);
}
- public static long readLong(DataInputStream buffer) throws IOException
+ public static long readLong(DataInput buffer) throws IOException
{
return buffer.readLong();
}
@@ -900,12 +900,12 @@ public class EncodingUtils
}
// Float_PROPERTY_PREFIX
- public static void writeFloat(DataOutputStream buffer, Float aFloat) throws IOException
+ public static void writeFloat(DataOutput buffer, float aFloat) throws IOException
{
buffer.writeFloat(aFloat);
}
- public static float readFloat(DataInputStream buffer) throws IOException
+ public static float readFloat(DataInput buffer) throws IOException
{
return buffer.readFloat();
}
@@ -916,12 +916,12 @@ public class EncodingUtils
}
// Double_PROPERTY_PREFIX
- public static void writeDouble(DataOutputStream buffer, Double aDouble) throws IOException
+ public static void writeDouble(DataOutput buffer, Double aDouble) throws IOException
{
buffer.writeDouble(aDouble);
}
- public static double readDouble(DataInputStream buffer) throws IOException
+ public static double readDouble(DataInput buffer) throws IOException
{
return buffer.readDouble();
}
@@ -931,7 +931,7 @@ public class EncodingUtils
return 8;
}
- public static byte[] readBytes(DataInputStream buffer) throws IOException
+ public static byte[] readBytes(DataInput buffer) throws IOException
{
long length = ((long)(buffer.readInt())) & 0xFFFFFFFFL;
if (length == 0)
@@ -941,13 +941,13 @@ public class EncodingUtils
else
{
byte[] dataBytes = new byte[(int)length];
- buffer.read(dataBytes, 0, (int) length);
+ buffer.readFully(dataBytes, 0, (int) length);
return dataBytes;
}
}
- public static void writeBytes(DataOutputStream buffer, byte[] data) throws IOException
+ public static void writeBytes(DataOutput buffer, byte[] data) throws IOException
{
if (data != null)
{
@@ -969,19 +969,19 @@ public class EncodingUtils
return encodedByteLength();
}
- public static char readChar(DataInputStream buffer) throws IOException
+ public static char readChar(DataInput buffer) throws IOException
{
// This is valid as we know that the Character is ASCII 0..127
- return (char) buffer.read();
+ return (char) buffer.readByte();
}
- public static void writeChar(DataOutputStream buffer, char character) throws IOException
+ public static void writeChar(DataOutput buffer, char character) throws IOException
{
// This is valid as we know that the Character is ASCII 0..127
writeByte(buffer, (byte) character);
}
- public static long readLongAsShortString(DataInputStream buffer) throws IOException
+ public static long readLongAsShortString(DataInput buffer) throws IOException
{
short length = (short) buffer.readUnsignedByte();
short pos = 0;
@@ -1018,7 +1018,7 @@ public class EncodingUtils
return result;
}
- public static long readUnsignedInteger(DataInputStream buffer) throws IOException
+ public static long readUnsignedInteger(DataInput buffer) throws IOException
{
long l = 0xFF & buffer.readByte();
l <<= 8;
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/ExtendedDataInput.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/ExtendedDataInput.java
new file mode 100644
index 0000000000..c789d9275e
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/ExtendedDataInput.java
@@ -0,0 +1,14 @@
+package org.apache.qpid.framing;
+
+import java.io.DataInput;
+
+public interface ExtendedDataInput extends DataInput
+{
+ AMQShortString readAMQShortString();
+
+ int available();
+
+ int position();
+
+ void position(int position);
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java
index 4a126b8504..863e363b87 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java
@@ -25,11 +25,7 @@ import org.slf4j.LoggerFactory;
import org.apache.qpid.AMQPInvalidClassException;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
+import java.io.*;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Enumeration;
@@ -44,18 +40,27 @@ import java.util.Set;
public class FieldTable
{
private static final Logger _logger = LoggerFactory.getLogger(FieldTable.class);
- private static final String STRICT_AMQP = "STRICT_AMQP";
- private final boolean _strictAMQP = Boolean.valueOf(System.getProperty(STRICT_AMQP, "false"));
+ private static final String STRICT_AMQP_NAME = "STRICT_AMQP";
+ private static final boolean STRICT_AMQP = Boolean.valueOf(System.getProperty(STRICT_AMQP_NAME, "false"));
private byte[] _encodedForm;
+ private int _encodedFormOffset;
private LinkedHashMap<AMQShortString, AMQTypedValue> _properties = null;
private long _encodedSize;
private static final int INITIAL_HASHMAP_CAPACITY = 16;
private static final int INITIAL_ENCODED_FORM_SIZE = 256;
+ private final boolean _strictAMQP;
public FieldTable()
{
+ this(STRICT_AMQP);
+ }
+
+
+ public FieldTable(boolean strictAMQP)
+ {
super();
+ _strictAMQP = strictAMQP;
}
/**
@@ -64,14 +69,28 @@ public class FieldTable
* @param buffer the buffer from which to read data. The length byte must be read already
* @param length the length of the field table. Must be > 0.
*/
- public FieldTable(DataInputStream buffer, long length) throws IOException
+ public FieldTable(DataInput buffer, long length) throws IOException
{
this();
_encodedForm = new byte[(int) length];
- buffer.read(_encodedForm);
+ buffer.readFully(_encodedForm);
_encodedSize = length;
}
+ public FieldTable(byte[] encodedForm, int offset, int length) throws IOException
+ {
+ this();
+ _encodedForm = encodedForm;
+ _encodedFormOffset = offset;
+ _encodedSize = length;
+ }
+
+
+ public boolean isClean()
+ {
+ return _encodedForm != null;
+ }
+
public AMQTypedValue getProperty(AMQShortString string)
{
checkPropertyName(string);
@@ -181,7 +200,7 @@ public class FieldTable
public Boolean getBoolean(String string)
{
- return getBoolean(new AMQShortString(string));
+ return getBoolean(AMQShortString.valueOf(string));
}
public Boolean getBoolean(AMQShortString string)
@@ -199,7 +218,7 @@ public class FieldTable
public Byte getByte(String string)
{
- return getByte(new AMQShortString(string));
+ return getByte(AMQShortString.valueOf(string));
}
public Byte getByte(AMQShortString string)
@@ -217,7 +236,7 @@ public class FieldTable
public Short getShort(String string)
{
- return getShort(new AMQShortString(string));
+ return getShort(AMQShortString.valueOf(string));
}
public Short getShort(AMQShortString string)
@@ -235,7 +254,7 @@ public class FieldTable
public Integer getInteger(String string)
{
- return getInteger(new AMQShortString(string));
+ return getInteger(AMQShortString.valueOf(string));
}
public Integer getInteger(AMQShortString string)
@@ -253,7 +272,7 @@ public class FieldTable
public Long getLong(String string)
{
- return getLong(new AMQShortString(string));
+ return getLong(AMQShortString.valueOf(string));
}
public Long getLong(AMQShortString string)
@@ -271,7 +290,7 @@ public class FieldTable
public Float getFloat(String string)
{
- return getFloat(new AMQShortString(string));
+ return getFloat(AMQShortString.valueOf(string));
}
public Float getFloat(AMQShortString string)
@@ -289,7 +308,7 @@ public class FieldTable
public Double getDouble(String string)
{
- return getDouble(new AMQShortString(string));
+ return getDouble(AMQShortString.valueOf(string));
}
public Double getDouble(AMQShortString string)
@@ -307,7 +326,7 @@ public class FieldTable
public String getString(String string)
{
- return getString(new AMQShortString(string));
+ return getString(AMQShortString.valueOf(string));
}
public String getString(AMQShortString string)
@@ -330,7 +349,7 @@ public class FieldTable
public Character getCharacter(String string)
{
- return getCharacter(new AMQShortString(string));
+ return getCharacter(AMQShortString.valueOf(string));
}
public Character getCharacter(AMQShortString string)
@@ -348,7 +367,7 @@ public class FieldTable
public byte[] getBytes(String string)
{
- return getBytes(new AMQShortString(string));
+ return getBytes(AMQShortString.valueOf(string));
}
public byte[] getBytes(AMQShortString string)
@@ -374,7 +393,7 @@ public class FieldTable
*/
public FieldTable getFieldTable(String string)
{
- return getFieldTable(new AMQShortString(string));
+ return getFieldTable(AMQShortString.valueOf(string));
}
/**
@@ -401,7 +420,7 @@ public class FieldTable
public Object getObject(String string)
{
- return getObject(new AMQShortString(string));
+ return getObject(AMQShortString.valueOf(string));
}
public Object getObject(AMQShortString string)
@@ -447,7 +466,7 @@ public class FieldTable
// ************ Setters
public Object setBoolean(String string, Boolean b)
{
- return setBoolean(new AMQShortString(string), b);
+ return setBoolean(AMQShortString.valueOf(string), b);
}
public Object setBoolean(AMQShortString string, Boolean b)
@@ -457,7 +476,7 @@ public class FieldTable
public Object setByte(String string, Byte b)
{
- return setByte(new AMQShortString(string), b);
+ return setByte(AMQShortString.valueOf(string), b);
}
public Object setByte(AMQShortString string, Byte b)
@@ -467,7 +486,7 @@ public class FieldTable
public Object setShort(String string, Short i)
{
- return setShort(new AMQShortString(string), i);
+ return setShort(AMQShortString.valueOf(string), i);
}
public Object setShort(AMQShortString string, Short i)
@@ -475,29 +494,29 @@ public class FieldTable
return setProperty(string, AMQType.SHORT.asTypedValue(i));
}
- public Object setInteger(String string, Integer i)
+ public Object setInteger(String string, int i)
{
- return setInteger(new AMQShortString(string), i);
+ return setInteger(AMQShortString.valueOf(string), i);
}
- public Object setInteger(AMQShortString string, Integer i)
+ public Object setInteger(AMQShortString string, int i)
{
- return setProperty(string, AMQType.INT.asTypedValue(i));
+ return setProperty(string, AMQTypedValue.createAMQTypedValue(i));
}
- public Object setLong(String string, Long l)
+ public Object setLong(String string, long l)
{
- return setLong(new AMQShortString(string), l);
+ return setLong(AMQShortString.valueOf(string), l);
}
- public Object setLong(AMQShortString string, Long l)
+ public Object setLong(AMQShortString string, long l)
{
- return setProperty(string, AMQType.LONG.asTypedValue(l));
+ return setProperty(string, AMQTypedValue.createAMQTypedValue(l));
}
public Object setFloat(String string, Float f)
{
- return setFloat(new AMQShortString(string), f);
+ return setFloat(AMQShortString.valueOf(string), f);
}
public Object setFloat(AMQShortString string, Float v)
@@ -507,7 +526,7 @@ public class FieldTable
public Object setDouble(String string, Double d)
{
- return setDouble(new AMQShortString(string), d);
+ return setDouble(AMQShortString.valueOf(string), d);
}
public Object setDouble(AMQShortString string, Double v)
@@ -517,7 +536,7 @@ public class FieldTable
public Object setString(String string, String s)
{
- return setString(new AMQShortString(string), s);
+ return setString(AMQShortString.valueOf(string), s);
}
public Object setAsciiString(AMQShortString string, String value)
@@ -546,7 +565,7 @@ public class FieldTable
public Object setChar(String string, char c)
{
- return setChar(new AMQShortString(string), c);
+ return setChar(AMQShortString.valueOf(string), c);
}
public Object setChar(AMQShortString string, char c)
@@ -556,7 +575,7 @@ public class FieldTable
public Object setBytes(String string, byte[] b)
{
- return setBytes(new AMQShortString(string), b);
+ return setBytes(AMQShortString.valueOf(string), b);
}
public Object setBytes(AMQShortString string, byte[] bytes)
@@ -566,7 +585,7 @@ public class FieldTable
public Object setBytes(String string, byte[] bytes, int start, int length)
{
- return setBytes(new AMQShortString(string), bytes, start, length);
+ return setBytes(AMQShortString.valueOf(string), bytes, start, length);
}
public Object setBytes(AMQShortString string, byte[] bytes, int start, int length)
@@ -579,7 +598,7 @@ public class FieldTable
public Object setObject(String string, Object o)
{
- return setObject(new AMQShortString(string), o);
+ return setObject(AMQShortString.valueOf(string), o);
}
public Object setTimestamp(AMQShortString string, long datetime)
@@ -617,7 +636,7 @@ public class FieldTable
*/
public Object setFieldTable(String string, FieldTable ftValue)
{
- return setFieldTable(new AMQShortString(string), ftValue);
+ return setFieldTable(AMQShortString.valueOf(string), ftValue);
}
/**
@@ -681,7 +700,7 @@ public class FieldTable
public boolean isNullStringValue(String name)
{
- AMQTypedValue value = getProperty(new AMQShortString(name));
+ AMQTypedValue value = getProperty(AMQShortString.valueOf(name));
return (value != null) && (value.getType() == AMQType.VOID);
}
@@ -713,7 +732,7 @@ public class FieldTable
public boolean itemExists(String string)
{
- return itemExists(new AMQShortString(string));
+ return itemExists(AMQShortString.valueOf(string));
}
public String toString()
@@ -769,7 +788,7 @@ public class FieldTable
// ************************* Byte Buffer Processing
- public void writeToBuffer(DataOutputStream buffer) throws IOException
+ public void writeToBuffer(DataOutput buffer) throws IOException
{
final boolean trace = _logger.isDebugEnabled();
@@ -919,7 +938,7 @@ public class FieldTable
public boolean containsKey(String key)
{
- return containsKey(new AMQShortString(key));
+ return containsKey(AMQShortString.valueOf(key));
}
public Set<String> keys()
@@ -942,7 +961,7 @@ public class FieldTable
public Object get(String key)
{
- return get(new AMQShortString(key));
+ return get(AMQShortString.valueOf(key));
}
public Object get(AMQShortString key)
@@ -958,7 +977,7 @@ public class FieldTable
public Object remove(String key)
{
- return remove(new AMQShortString(key));
+ return remove(AMQShortString.valueOf(key));
}
@@ -1005,12 +1024,12 @@ public class FieldTable
return _properties.keySet();
}
- private void putDataInBuffer(DataOutputStream buffer) throws IOException
+ private void putDataInBuffer(DataOutput buffer) throws IOException
{
if (_encodedForm != null)
{
- buffer.write(_encodedForm);
+ buffer.write(_encodedForm,_encodedFormOffset,(int)_encodedSize);
}
else if (_properties != null)
{
@@ -1039,9 +1058,8 @@ public class FieldTable
private void setFromBuffer() throws AMQFrameDecodingException, IOException
{
- final ByteArrayInputStream in = new ByteArrayInputStream(_encodedForm);
- DataInputStream buffer = new DataInputStream(in);
- final boolean trace = _logger.isDebugEnabled();
+ ByteArrayDataInput baid = new ByteArrayDataInput(_encodedForm, _encodedFormOffset, (int)_encodedSize);
+
if (_encodedSize > 0)
{
@@ -1051,12 +1069,12 @@ public class FieldTable
do
{
- final AMQShortString key = EncodingUtils.readAMQShortString(buffer);
- AMQTypedValue value = AMQTypedValue.readFromBuffer(buffer);
+ final AMQShortString key = baid.readAMQShortString();
+ AMQTypedValue value = AMQTypedValue.readFromBuffer(baid);
_properties.put(key, value);
}
- while (in.available() > 0);
+ while (baid.available() > 0);
}
@@ -1101,7 +1119,7 @@ public class FieldTable
FieldTable table = new FieldTable();
for(Map.Entry<String,Object> entry : map.entrySet())
{
- table.put(new AMQShortString(entry.getKey()), entry.getValue());
+ table.put(AMQShortString.valueOf(entry.getKey()), entry.getValue());
}
return table;
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java
index 438a46f28b..af0c5b845c 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.framing;
+import java.io.DataInput;
import java.io.DataInputStream;
import java.io.IOException;
@@ -30,7 +31,7 @@ public class FieldTableFactory
return new FieldTable();
}
- public static FieldTable newFieldTable(DataInputStream byteBuffer, long length) throws AMQFrameDecodingException, IOException
+ public static FieldTable newFieldTable(DataInput byteBuffer, long length) throws AMQFrameDecodingException, IOException
{
return new FieldTable(byteBuffer, length);
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBody.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBody.java
index a6ce721a50..95b6246717 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBody.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBody.java
@@ -21,7 +21,7 @@
package org.apache.qpid.framing;
import java.io.DataInputStream;
-import java.io.DataOutputStream;
+import java.io.DataOutput;
import java.io.IOException;
import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
@@ -56,7 +56,7 @@ public class HeartbeatBody implements AMQBody
return 0;//heartbeats we generate have no payload
}
- public void writePayload(DataOutputStream buffer)
+ public void writePayload(DataOutput buffer)
{
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBodyFactory.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBodyFactory.java
index dfc49c6167..971caca41a 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBodyFactory.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBodyFactory.java
@@ -20,12 +20,13 @@
*/
package org.apache.qpid.framing;
-import java.io.DataInputStream;
+import org.apache.qpid.codec.MarkableDataInput;
public class HeartbeatBodyFactory implements BodyFactory
{
- public AMQBody createBody(DataInputStream in, long bodySize) throws AMQFrameDecodingException
+ public AMQBody createBody(MarkableDataInput in, long bodySize) throws AMQFrameDecodingException
{
return new HeartbeatBody();
}
+
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java
index 8c018316f0..2925724dc2 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java
@@ -21,13 +21,10 @@
package org.apache.qpid.framing;
import org.apache.qpid.AMQException;
+import org.apache.qpid.codec.MarkableDataInput;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
+import java.io.*;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
import java.util.Arrays;
public class ProtocolInitiation extends AMQDataBlock implements EncodableAMQDataBlock
@@ -66,7 +63,7 @@ public class ProtocolInitiation extends AMQDataBlock implements EncodableAMQData
pv.equals(ProtocolVersion.v0_91) ? 1 : pv.getMinorVersion());
}
- public ProtocolInitiation(DataInputStream in) throws IOException
+ public ProtocolInitiation(MarkableDataInput in) throws IOException
{
_protocolHeader = new byte[4];
in.read(_protocolHeader);
@@ -82,7 +79,7 @@ public class ProtocolInitiation extends AMQDataBlock implements EncodableAMQData
return 4 + 1 + 1 + 1 + 1;
}
- public void writePayload(DataOutputStream buffer) throws IOException
+ public void writePayload(DataOutput buffer) throws IOException
{
buffer.write(_protocolHeader);
@@ -143,7 +140,7 @@ public class ProtocolInitiation extends AMQDataBlock implements EncodableAMQData
* @return true if we have enough data to decode the PI frame fully, false if more
* data is required
*/
- public boolean decodable(DataInputStream in) throws IOException
+ public boolean decodable(MarkableDataInput in) throws IOException
{
return (in.available() >= 8);
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/SmallCompositeAMQDataBlock.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/SmallCompositeAMQDataBlock.java
index d2925d13a8..dd854dd498 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/SmallCompositeAMQDataBlock.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/SmallCompositeAMQDataBlock.java
@@ -21,7 +21,7 @@
package org.apache.qpid.framing;
-import java.io.DataOutputStream;
+import java.io.DataOutput;
import java.io.IOException;
public class SmallCompositeAMQDataBlock extends AMQDataBlock implements EncodableAMQDataBlock
@@ -69,7 +69,7 @@ public class SmallCompositeAMQDataBlock extends AMQDataBlock implements Encodabl
return frameSize;
}
- public void writePayload(DataOutputStream buffer) throws IOException
+ public void writePayload(DataOutput buffer) throws IOException
{
if (_firstFrame != null)
{
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/VersionSpecificRegistry.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/VersionSpecificRegistry.java
index ed9136f7c9..e770fdd7e4 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/VersionSpecificRegistry.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/VersionSpecificRegistry.java
@@ -23,6 +23,7 @@ package org.apache.qpid.framing;
import java.io.DataInputStream;
import java.io.IOException;
+import org.apache.qpid.codec.MarkableDataInput;
import org.apache.qpid.framing.abstraction.ProtocolVersionMethodConverter;
import org.slf4j.Logger;
@@ -145,7 +146,7 @@ public class VersionSpecificRegistry
}
- public AMQMethodBody get(short classID, short methodID, DataInputStream in, long size) throws AMQFrameDecodingException, IOException
+ public AMQMethodBody get(short classID, short methodID, MarkableDataInput in, long size) throws AMQFrameDecodingException, IOException
{
AMQMethodBodyInstanceFactory bodyFactory;
try
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/pool/ReadWriteJobQueue.java b/qpid/java/common/src/main/java/org/apache/qpid/pool/ReadWriteJobQueue.java
deleted file mode 100644
index 8de0f93ce9..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/pool/ReadWriteJobQueue.java
+++ /dev/null
@@ -1,432 +0,0 @@
-package org.apache.qpid.pool;
-
-import java.util.AbstractQueue;
-import java.util.Iterator;
-import java.util.Collection;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/*
-*
-* 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.
-*
-*/
-public class ReadWriteJobQueue extends AbstractQueue<Runnable> implements BlockingQueue<Runnable>
-{
-
- private final AtomicInteger _count = new AtomicInteger(0);
-
- private final ReentrantLock _takeLock = new ReentrantLock();
-
- private final Condition _notEmpty = _takeLock.newCondition();
-
- private final ReentrantLock _putLock = new ReentrantLock();
-
- private final ConcurrentLinkedQueue<ReadWriteRunnable> _readJobQueue = new ConcurrentLinkedQueue<ReadWriteRunnable>();
-
- private final ConcurrentLinkedQueue<ReadWriteRunnable> _writeJobQueue = new ConcurrentLinkedQueue<ReadWriteRunnable>();
-
-
- private class ReadWriteJobIterator implements Iterator<Runnable>
- {
-
- private boolean _onReads;
- private Iterator<ReadWriteRunnable> _iter = _writeJobQueue.iterator();
-
- public boolean hasNext()
- {
- if(!_iter.hasNext())
- {
- if(_onReads)
- {
- _iter = _readJobQueue.iterator();
- _onReads = true;
- return _iter.hasNext();
- }
- else
- {
- return false;
- }
- }
- else
- {
- return true;
- }
- }
-
- public Runnable next()
- {
- if(_iter.hasNext())
- {
- return _iter.next();
- }
- else
- {
- return null;
- }
- }
-
- public void remove()
- {
- _takeLock.lock();
- try
- {
- _iter.remove();
- _count.decrementAndGet();
- }
- finally
- {
- _takeLock.unlock();
- }
- }
- }
-
- public Iterator<Runnable> iterator()
- {
- return new ReadWriteJobIterator();
- }
-
- public int size()
- {
- return _count.get();
- }
-
- public boolean offer(final Runnable runnable)
- {
- final ReadWriteRunnable job = (ReadWriteRunnable) runnable;
- final ReentrantLock putLock = _putLock;
- putLock.lock();
- try
- {
- if(job.isRead())
- {
- _readJobQueue.offer(job);
- }
- else
- {
- _writeJobQueue.offer(job);
- }
- if(_count.getAndIncrement() == 0)
- {
- _takeLock.lock();
- try
- {
- _notEmpty.signal();
- }
- finally
- {
- _takeLock.unlock();
- }
- }
- return true;
- }
- finally
- {
- putLock.unlock();
- }
- }
-
- public void put(final Runnable runnable) throws InterruptedException
- {
- final ReadWriteRunnable job = (ReadWriteRunnable) runnable;
- final ReentrantLock putLock = _putLock;
- putLock.lock();
-
- try
- {
- if(job.isRead())
- {
- _readJobQueue.offer(job);
- }
- else
- {
- _writeJobQueue.offer(job);
- }
- if(_count.getAndIncrement() == 0)
- {
- _takeLock.lock();
- try
- {
- _notEmpty.signal();
- }
- finally
- {
- _takeLock.unlock();
- }
- }
-
- }
- finally
- {
- putLock.unlock();
- }
- }
-
-
-
- public boolean offer(final Runnable runnable, final long timeout, final TimeUnit unit) throws InterruptedException
- {
- final ReadWriteRunnable job = (ReadWriteRunnable) runnable;
- final ReentrantLock putLock = _putLock;
- putLock.lock();
-
- try
- {
- if(job.isRead())
- {
- _readJobQueue.offer(job);
- }
- else
- {
- _writeJobQueue.offer(job);
- }
- if(_count.getAndIncrement() == 0)
- {
- _takeLock.lock();
- try
- {
- _notEmpty.signal();
- }
- finally
- {
- _takeLock.unlock();
- }
- }
-
- return true;
- }
- finally
- {
- putLock.unlock();
- }
-
- }
-
- public Runnable take() throws InterruptedException
- {
- final ReentrantLock takeLock = _takeLock;
- takeLock.lockInterruptibly();
- try
- {
- try
- {
- while (_count.get() == 0)
- {
- _notEmpty.await();
- }
- }
- catch (InterruptedException ie)
- {
- _notEmpty.signal();
- throw ie;
- }
-
- ReadWriteRunnable job = _writeJobQueue.poll();
- if(job == null)
- {
- job = _readJobQueue.poll();
- }
- int c = _count.getAndDecrement();
- if (c > 1)
- {
- _notEmpty.signal();
- }
- return job;
- }
- finally
- {
- takeLock.unlock();
- }
-
-
- }
-
- public Runnable poll(final long timeout, final TimeUnit unit) throws InterruptedException
- {
- final ReentrantLock takeLock = _takeLock;
- final AtomicInteger count = _count;
- long nanos = unit.toNanos(timeout);
- takeLock.lockInterruptibly();
- ReadWriteRunnable job = null;
- try
- {
-
- for (;;)
- {
- if (count.get() > 0)
- {
- job = _writeJobQueue.poll();
- if(job == null)
- {
- job = _readJobQueue.poll();
- }
- int c = count.getAndDecrement();
- if (c > 1)
- {
- _notEmpty.signal();
- }
- break;
- }
- if (nanos <= 0)
- {
- return null;
- }
- try
- {
- nanos = _notEmpty.awaitNanos(nanos);
- }
- catch (InterruptedException ie)
- {
- _notEmpty.signal();
- throw ie;
- }
- }
- }
- finally
- {
- takeLock.unlock();
- }
-
- return job;
- }
-
- public int remainingCapacity()
- {
- return Integer.MAX_VALUE;
- }
-
- public int drainTo(final Collection<? super Runnable> c)
- {
- int total = 0;
-
- _putLock.lock();
- _takeLock.lock();
- try
- {
- ReadWriteRunnable job;
- while((job = _writeJobQueue.peek())!= null)
- {
- c.add(job);
- _writeJobQueue.poll();
- _count.decrementAndGet();
- total++;
- }
-
- while((job = _readJobQueue.peek())!= null)
- {
- c.add(job);
- _readJobQueue.poll();
- _count.decrementAndGet();
- total++;
- }
-
- }
- finally
- {
- _takeLock.unlock();
- _putLock.unlock();
- }
- return total;
- }
-
- public int drainTo(final Collection<? super Runnable> c, final int maxElements)
- {
- int total = 0;
-
- _putLock.lock();
- _takeLock.lock();
- try
- {
- ReadWriteRunnable job;
- while(total<=maxElements && (job = _writeJobQueue.peek())!= null)
- {
- c.add(job);
- _writeJobQueue.poll();
- _count.decrementAndGet();
- total++;
- }
-
- while(total<=maxElements && (job = _readJobQueue.peek())!= null)
- {
- c.add(job);
- _readJobQueue.poll();
- _count.decrementAndGet();
- total++;
- }
-
- }
- finally
- {
- _takeLock.unlock();
- _putLock.unlock();
- }
- return total;
-
- }
-
- public Runnable poll()
- {
- final ReentrantLock takeLock = _takeLock;
- takeLock.lock();
- try
- {
- if(_count.get() > 0)
- {
- ReadWriteRunnable job = _writeJobQueue.poll();
- if(job == null)
- {
- job = _readJobQueue.poll();
- }
- _count.decrementAndGet();
- return job;
- }
- else
- {
- return null;
- }
- }
- finally
- {
- takeLock.unlock();
- }
-
- }
-
- public Runnable peek()
- {
- final ReentrantLock takeLock = _takeLock;
- takeLock.lock();
- try
- {
- ReadWriteRunnable job = _writeJobQueue.peek();
- if(job == null)
- {
- job = _readJobQueue.peek();
- }
- return job;
- }
- finally
- {
- takeLock.unlock();
- }
- }
-}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/pool/ReadWriteRunnable.java b/qpid/java/common/src/main/java/org/apache/qpid/pool/ReadWriteRunnable.java
deleted file mode 100644
index 140c93ca8d..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/pool/ReadWriteRunnable.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.apache.qpid.pool;
-
-/*
-*
-* 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.
-*
-*/
-public interface ReadWriteRunnable extends Runnable
-{
- boolean isRead();
-}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/pool/ReferenceCountingExecutorService.java b/qpid/java/common/src/main/java/org/apache/qpid/pool/ReferenceCountingExecutorService.java
index 8152a1f5e9..3e99b244c4 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/pool/ReferenceCountingExecutorService.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/pool/ReferenceCountingExecutorService.java
@@ -96,8 +96,6 @@ public class ReferenceCountingExecutorService
*/
private ThreadFactory _threadFactory = Executors.defaultThreadFactory();
- private final boolean _useBiasedPool = Boolean.getBoolean("org.apache.qpid.use_write_biased_pool");
-
/**
* Retrieves the singleton instance of this reference counter.
*
@@ -125,26 +123,12 @@ public class ReferenceCountingExecutorService
{
if (_refCount++ == 0)
{
- // Use a job queue that biases to writes
- if(_useBiasedPool)
- {
- _pool = new ThreadPoolExecutor(_poolSize, _poolSize,
- 0L, TimeUnit.MILLISECONDS,
- new ReadWriteJobQueue(),
- _threadFactory);
-
- }
- else
- {
- _pool = new ThreadPoolExecutor(_poolSize, _poolSize,
- 0L, TimeUnit.MILLISECONDS,
- new LinkedBlockingQueue<Runnable>(),
- _threadFactory);
- }
-
+ _pool = new ThreadPoolExecutor(_poolSize, _poolSize,
+ 0L, TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue<Runnable>(),
+ _threadFactory);
}
-
return _pool;
}
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java
index b78433052c..dee5f696b9 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java
@@ -383,13 +383,19 @@ public class Connection extends ConnectionInvoker
public void received(ProtocolEvent event)
{
- log.debug("RECV: [%s] %s", this, event);
+ if(log.isDebugEnabled())
+ {
+ log.debug("RECV: [%s] %s", this, event);
+ }
event.delegate(this, delegate);
}
public void send(ProtocolEvent event)
{
- log.debug("SEND: [%s] %s", this, event);
+ if(log.isDebugEnabled())
+ {
+ log.debug("SEND: [%s] %s", this, event);
+ }
Sender s = sender;
if (s == null)
{
@@ -400,8 +406,15 @@ public class Connection extends ConnectionInvoker
public void flush()
{
- log.debug("FLUSH: [%s]", this);
- sender.flush();
+ if(log.isDebugEnabled())
+ {
+ log.debug("FLUSH: [%s]", this);
+ }
+ final Sender<ProtocolEvent> theSender = sender;
+ if(theSender != null)
+ {
+ theSender.flush();
+ }
}
protected void invoke(Method method)
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/Header.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/Header.java
index 9439e5e0de..543856ca39 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/Header.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/Header.java
@@ -20,13 +20,7 @@
*/
package org.apache.qpid.transport;
-import org.apache.qpid.transport.network.Frame;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.LinkedHashMap;
-import java.nio.ByteBuffer;
+import java.util.*;
/**
@@ -35,45 +29,87 @@ import java.nio.ByteBuffer;
* @author Rafael H. Schloming
*/
-public class Header {
+public class Header
+{
- private final Struct[] structs;
+ private final DeliveryProperties _deliveryProps;
+ private final MessageProperties _messageProps;
+ private final List<Struct> _nonStandardProps;
- public Header(List<Struct> structs)
+ public Header(DeliveryProperties deliveryProps, MessageProperties messageProps)
{
- this(structs.toArray(new Struct[structs.size()]));
+ this(deliveryProps, messageProps, null);
}
- public Header(Struct ... structs)
+ public Header(DeliveryProperties deliveryProps, MessageProperties messageProps, List<Struct> nonStandardProps)
{
- this.structs = structs;
+ _deliveryProps = deliveryProps;
+ _messageProps = messageProps;
+ _nonStandardProps = nonStandardProps;
}
public Struct[] getStructs()
{
+ int size = 0;
+ if(_deliveryProps != null)
+ {
+ size++;
+ }
+ if(_messageProps != null)
+ {
+ size++;
+ }
+ if(_nonStandardProps != null)
+ {
+ size+=_nonStandardProps.size();
+ }
+ Struct[] structs = new Struct[size];
+ int index = 0;
+ if(_deliveryProps != null)
+ {
+ structs[index++] = _deliveryProps;
+ }
+ if(_messageProps != null)
+ {
+ structs[index++] = _messageProps;
+ }
+ if(_nonStandardProps != null)
+ {
+ for(Struct struct : _nonStandardProps)
+ {
+ structs[index++] = struct;
+ }
+ }
+
return structs;
}
+ public DeliveryProperties getDeliveryProperties()
+ {
+ return _deliveryProps;
+ }
- public <T> T get(Class<T> klass)
+ public MessageProperties getMessageProperties()
{
- for (Struct st : structs)
- {
- if (klass.isInstance(st))
- {
- return (T) st;
- }
- }
+ return _messageProps;
+ }
- return null;
+ public List<Struct> getNonStandardProperties()
+ {
+ return _nonStandardProps;
}
public String toString()
{
- StringBuffer str = new StringBuffer();
+ StringBuilder str = new StringBuilder();
str.append(" Header(");
boolean first = true;
- for (Struct s : structs)
+ if(_deliveryProps !=null)
+ {
+ first=false;
+ str.append(_deliveryProps);
+ }
+ if(_messageProps != null)
{
if (first)
{
@@ -83,9 +119,24 @@ public class Header {
{
str.append(", ");
}
- str.append(s);
+ str.append(_messageProps);
+ }
+ if(_nonStandardProps != null)
+ {
+ for (Struct s : _nonStandardProps)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ str.append(", ");
+ }
+ str.append(s);
+ }
}
- str.append(")");
+ str.append(')');
return str.toString();
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/Range.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/Range.java
index f4335dc8a6..c47171dc4b 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/Range.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/Range.java
@@ -21,6 +21,8 @@
package org.apache.qpid.transport;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import static org.apache.qpid.util.Serial.*;
@@ -32,94 +34,265 @@ import static org.apache.qpid.util.Serial.*;
* @author Rafael H. Schloming
*/
-public final class Range
+public abstract class Range implements RangeSet
{
- private final int lower;
- private final int upper;
+ public static Range newInstance(int point)
+ {
+ return new PointImpl(point);
+ }
+
+ public static Range newInstance(int lower, int upper)
+ {
+ return lower == upper ? new PointImpl(lower) : new RangeImpl(lower, upper);
+ }
+
+ public abstract int getLower();
+
+ public abstract int getUpper();
+
+ public abstract boolean includes(int value);
+
+ public abstract boolean includes(Range range);
+
+ public abstract boolean intersects(Range range);
+
+ public abstract boolean touches(Range range);
+
+ public abstract Range span(Range range);
+
+ public abstract List<Range> subtract(Range range);
- public Range(int lower, int upper)
+
+ public Range intersect(Range range)
{
- this.lower = lower;
- this.upper = upper;
+ int l = max(getLower(), range.getLower());
+ int r = min(getUpper(), range.getUpper());
+ if (gt(l, r))
+ {
+ return null;
+ }
+ else
+ {
+ return newInstance(l, r);
+ }
}
- public int getLower()
+
+
+ public int size()
{
- return lower;
+ return 1;
}
- public int getUpper()
+ public Iterator<Range> iterator()
{
- return upper;
+ return new RangeIterator();
}
- public boolean includes(int value)
+ public Range getFirst()
{
- return le(lower, value) && le(value, upper);
+ return this;
}
- public boolean includes(Range range)
+ public Range getLast()
{
- return includes(range.lower) && includes(range.upper);
+ return this;
}
- public boolean intersects(Range range)
+ public void add(Range range)
{
- return (includes(range.lower) || includes(range.upper) ||
- range.includes(lower) || range.includes(upper));
+ throw new UnsupportedOperationException();
}
- public boolean touches(Range range)
+ public void add(int lower, int upper)
{
- return (intersects(range) ||
- includes(range.upper + 1) || includes(range.lower - 1) ||
- range.includes(upper + 1) || range.includes(lower - 1));
+ throw new UnsupportedOperationException();
}
- public Range span(Range range)
+ public void add(int value)
{
- return new Range(min(lower, range.lower), max(upper, range.upper));
+ throw new UnsupportedOperationException();
}
- public List<Range> subtract(Range range)
+ public void clear()
{
- List<Range> result = new ArrayList<Range>();
+ throw new UnsupportedOperationException();
+ }
- if (includes(range.lower) && le(lower, range.lower - 1))
+ public RangeSet copy()
+ {
+ RangeSet rangeSet = RangeSetFactory.createRangeSet();
+ rangeSet.add(this);
+ return rangeSet;
+ }
+
+ private static class PointImpl extends Range
+ {
+ private final int point;
+
+ private PointImpl(int point)
+ {
+ this.point = point;
+ }
+
+ public int getLower()
{
- result.add(new Range(lower, range.lower - 1));
+ return point;
}
- if (includes(range.upper) && le(range.upper + 1, upper))
+ public int getUpper()
{
- result.add(new Range(range.upper + 1, upper));
+ return point;
}
- if (result.isEmpty() && !range.includes(this))
+ public boolean includes(int value)
{
- result.add(this);
+ return value == point;
}
- return result;
+
+ public boolean includes(Range range)
+ {
+ return range.getLower() == point && range.getUpper() == point;
+ }
+
+ public boolean intersects(Range range)
+ {
+ return range.includes(point);
+ }
+
+ public boolean touches(Range range)
+ {
+ return intersects(range) ||
+ includes(range.getUpper() + 1) || includes(range.getLower() - 1) ||
+ range.includes(point + 1) || range.includes(point - 1);
+ }
+
+ public Range span(Range range)
+ {
+ return newInstance(min(point, range.getLower()), max(point, range.getUpper()));
+ }
+
+ public List<Range> subtract(Range range)
+ {
+ if(range.includes(point))
+ {
+ return Collections.emptyList();
+ }
+ else
+ {
+ return Collections.singletonList((Range) this);
+ }
+ }
+
+ public String toString()
+ {
+ return "[" + point + ", " + point + "]";
+ }
+
+
}
- public Range intersect(Range range)
+ private static class RangeImpl extends Range
{
- int l = max(lower, range.lower);
- int r = min(upper, range.upper);
- if (gt(l, r))
+ private final int lower;
+ private final int upper;
+
+ private RangeImpl(int lower, int upper)
{
- return null;
+ this.lower = lower;
+ this.upper = upper;
}
- else
+
+ public int getLower()
+ {
+ return lower;
+ }
+
+ public int getUpper()
+ {
+ return upper;
+ }
+
+ public boolean includes(int value)
+ {
+ return le(lower, value) && le(value, upper);
+ }
+
+ public boolean includes(Range range)
+ {
+ return includes(range.getLower()) && includes(range.getUpper());
+ }
+
+ public boolean intersects(Range range)
+ {
+ return (includes(range.getLower()) || includes(range.getUpper()) ||
+ range.includes(lower) || range.includes(upper));
+ }
+
+ public boolean touches(Range range)
+ {
+ return (intersects(range) ||
+ includes(range.getUpper() + 1) || includes(range.getLower() - 1) ||
+ range.includes(upper + 1) || range.includes(lower - 1));
+ }
+
+ public Range span(Range range)
{
- return new Range(l, r);
+ return newInstance(min(lower, range.getLower()), max(upper, range.getUpper()));
+ }
+
+ public List<Range> subtract(Range range)
+ {
+ List<Range> result = new ArrayList<Range>();
+
+ if (includes(range.getLower()) && le(lower, range.getLower() - 1))
+ {
+ result.add(newInstance(lower, range.getLower() - 1));
+ }
+
+ if (includes(range.getUpper()) && le(range.getUpper() + 1, upper))
+ {
+ result.add(newInstance(range.getUpper() + 1, upper));
+ }
+
+ if (result.isEmpty() && !range.includes(this))
+ {
+ result.add(this);
+ }
+
+ return result;
+ }
+
+
+ public String toString()
+ {
+ return "[" + lower + ", " + upper + "]";
}
}
- public String toString()
+
+ private class RangeIterator implements Iterator<Range>
{
- return "[" + lower + ", " + upper + "]";
- }
+ private boolean atFirst = true;
+
+ public boolean hasNext()
+ {
+ return atFirst;
+ }
+
+ public Range next()
+ {
+ Range range = atFirst ? Range.this : null;
+ atFirst = false;
+ return range;
+ }
+
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/RangeSet.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/RangeSet.java
index 3850dc162b..34ebd02777 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/RangeSet.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/RangeSet.java
@@ -20,9 +20,7 @@
*/
package org.apache.qpid.transport;
-import java.util.Iterator;
-import java.util.ListIterator;
-import java.util.LinkedList;
+import java.util.*;
import static org.apache.qpid.util.Serial.*;
@@ -32,121 +30,29 @@ import static org.apache.qpid.util.Serial.*;
* @author Rafael H. Schloming
*/
-public final class RangeSet implements Iterable<Range>
+public interface RangeSet extends Iterable<Range>
{
- private LinkedList<Range> ranges = new LinkedList<Range>();
-
- public int size()
- {
- return ranges.size();
- }
-
- public Iterator<Range> iterator()
- {
- return ranges.iterator();
- }
-
- public Range getFirst()
- {
- return ranges.getFirst();
- }
-
- public Range getLast()
- {
- return ranges.getLast();
- }
-
- public boolean includes(Range range)
- {
- for (Range r : this)
- {
- if (r.includes(range))
- {
- return true;
- }
- }
-
- return false;
- }
-
- public boolean includes(int n)
- {
- for (Range r : this)
- {
- if (r.includes(n))
- {
- return true;
- }
- }
-
- return false;
- }
-
- public void add(Range range)
- {
- ListIterator<Range> it = ranges.listIterator();
-
- while (it.hasNext())
- {
- Range next = it.next();
- if (range.touches(next))
- {
- it.remove();
- range = range.span(next);
- }
- else if (lt(range.getUpper(), next.getLower()))
- {
- it.previous();
- it.add(range);
- return;
- }
- }
-
- it.add(range);
- }
-
- public void add(int lower, int upper)
- {
- add(new Range(lower, upper));
- }
-
- public void add(int value)
- {
- add(value, value);
- }
-
- public void clear()
- {
- ranges.clear();
- }
-
- public RangeSet copy()
- {
- RangeSet copy = new RangeSet();
- copy.ranges.addAll(ranges);
- return copy;
- }
-
- public String toString()
- {
- StringBuffer str = new StringBuffer();
- str.append("{");
- boolean first = true;
- for (Range range : ranges)
- {
- if (first)
- {
- first = false;
- }
- else
- {
- str.append(", ");
- }
- str.append(range);
- }
- str.append("}");
- return str.toString();
- }
+ int size();
+
+ Iterator<Range> iterator();
+
+ Range getFirst();
+
+ Range getLast();
+
+ boolean includes(Range range);
+
+ boolean includes(int n);
+
+ void add(Range range);
+
+ void add(int lower, int upper);
+
+ void add(int value);
+
+ void clear();
+
+ RangeSet copy();
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/filter/BooleanExpression.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/RangeSetFactory.java
index 14a5c7ea87..0f19d7e2b2 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/filter/BooleanExpression.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/RangeSetFactory.java
@@ -1,33 +1,34 @@
-/* Licensed to the Apache Software Foundation (ASF) under one
+/*
+ *
+ * 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.filter;
+package org.apache.qpid.transport;
-import org.apache.qpid.AMQInternalException;
-import org.apache.qpid.client.message.AbstractJMSMessage;
-
-
-/**
- * A BooleanExpression is an expression that always
- * produces a Boolean result.
- */
-public interface BooleanExpression extends Expression
+public class RangeSetFactory
{
+ public static RangeSet createRangeSet()
+ {
+ return new RangeSetImpl();
+ }
- public boolean matches(AbstractJMSMessage message) throws AMQInternalException;
-
+ public static RangeSet createRangeSet(int size)
+ {
+ return new RangeSetImpl(size);
+ }
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/RangeSetImpl.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/RangeSetImpl.java
new file mode 100644
index 0000000000..f2540afb40
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/RangeSetImpl.java
@@ -0,0 +1,178 @@
+/*
+ *
+ * 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.transport;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import static org.apache.qpid.util.Serial.lt;
+
+public class RangeSetImpl implements RangeSet
+{
+
+ private List<Range> ranges;
+
+ public RangeSetImpl()
+ {
+ ranges = new ArrayList<Range>();
+ }
+
+ public RangeSetImpl(int size)
+ {
+ ranges = new ArrayList<Range>(size);
+ }
+
+
+ public RangeSetImpl(org.apache.qpid.transport.RangeSetImpl copy)
+ {
+ ranges = new ArrayList<Range>(copy.ranges);
+ }
+
+ public int size()
+ {
+ return ranges.size();
+ }
+
+ public Iterator<Range> iterator()
+ {
+ return ranges.iterator();
+ }
+
+ public Range getFirst()
+ {
+ return ranges.get(0);
+ }
+
+ public Range getLast()
+ {
+ return ranges.get(ranges.size() - 1);
+ }
+
+ public boolean includes(Range range)
+ {
+ for (Range r : this)
+ {
+ if (r.includes(range))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public boolean includes(int n)
+ {
+ for (Range r : this)
+ {
+ if (r.includes(n))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public void add(Range range)
+ {
+ ListIterator<Range> it = ranges.listIterator();
+
+ while (it.hasNext())
+ {
+ Range next = it.next();
+ if (range.touches(next))
+ {
+ it.remove();
+ range = range.span(next);
+ }
+ else if (lt(range.getUpper(), next.getLower()))
+ {
+ it.previous();
+ it.add(range);
+ return;
+ }
+ }
+
+ it.add(range);
+ }
+
+ public void add(int lower, int upper)
+ {
+ switch(ranges.size())
+ {
+ case 0:
+ ranges.add(Range.newInstance(lower, upper));
+ break;
+
+ case 1:
+ Range first = ranges.get(0);
+ if(first.getUpper() + 1 >= lower && upper >= first.getUpper())
+ {
+ ranges.set(0, Range.newInstance(first.getLower(), upper));
+ break;
+ }
+
+ default:
+ add(Range.newInstance(lower, upper));
+ }
+
+
+ }
+
+ public void add(int value)
+ {
+ add(value, value);
+ }
+
+ public void clear()
+ {
+ ranges.clear();
+ }
+
+ public RangeSet copy()
+ {
+ return new org.apache.qpid.transport.RangeSetImpl(this);
+ }
+
+ public String toString()
+ {
+ StringBuffer str = new StringBuffer();
+ str.append("{");
+ boolean first = true;
+ for (Range range : ranges)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ str.append(", ");
+ }
+ str.append(range);
+ }
+ str.append("}");
+ return str.toString();
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/Session.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/Session.java
index 321e5256b2..5a9ea73cae 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/Session.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/Session.java
@@ -44,6 +44,7 @@ import static org.apache.qpid.util.Serial.max;
import static org.apache.qpid.util.Strings.toUTF8;
import java.nio.ByteBuffer;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -61,7 +62,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class Session extends SessionInvoker
{
private static final Logger log = Logger.get(Session.class);
-
+
public enum State { NEW, DETACHED, RESUMING, OPEN, CLOSING, CLOSED }
static class DefaultSessionListener implements SessionListener
@@ -96,6 +97,9 @@ public class Session extends SessionInvoker
private final long timeout = Long.getLong(ClientProperties.QPID_SYNC_OP_TIMEOUT,
Long.getLong(ClientProperties.AMQJ_DEFAULT_SYNCWRITE_TIMEOUT,
ClientProperties.DEFAULT_SYNC_OPERATION_TIMEOUT));
+ private final long blockedSendTimeout = Long.getLong("qpid.flow_control_wait_failure", timeout);
+ private long blockedSendReportingPeriod = Long.getLong("qpid.flow_control_wait_notify_period",5000L);
+
private boolean autoSync = false;
private boolean incomingInit;
@@ -228,10 +232,21 @@ public class Session extends SessionInvoker
{
try
{
- if (!credit.tryAcquire(timeout, TimeUnit.MILLISECONDS))
+ long wait = blockedSendTimeout > blockedSendReportingPeriod ? blockedSendReportingPeriod :
+ blockedSendTimeout;
+ long totalWait = 1L;
+ while(totalWait <= blockedSendTimeout && !credit.tryAcquire(wait, TimeUnit.MILLISECONDS))
{
+ totalWait+=wait;
+ log.warn("Message send delayed by " + (totalWait)/1000 + "s due to broker enforced flow control");
+
+
+ }
+ if(totalWait > blockedSendTimeout)
+ {
+ log.error("Message send failed due to timeout waiting on broker enforced flow control");
throw new SessionException
- ("timed out waiting for message credit");
+ ("timed out waiting for message credit");
}
}
catch (InterruptedException e)
@@ -247,7 +262,7 @@ public class Session extends SessionInvoker
synchronized (processedLock)
{
incomingInit = false;
- processed = new RangeSet();
+ processed = RangeSetFactory.createRangeSet();
}
}
@@ -276,22 +291,22 @@ public class Session extends SessionInvoker
else if (m instanceof MessageTransfer)
{
MessageTransfer xfr = (MessageTransfer)m;
-
- if (xfr.getHeader() != null)
+
+ Header header = xfr.getHeader();
+
+ if (header != null)
{
- if (xfr.getHeader().get(DeliveryProperties.class) != null)
+ if (header.getDeliveryProperties() != null)
{
- xfr.getHeader().get(DeliveryProperties.class).setRedelivered(true);
+ header.getDeliveryProperties().setRedelivered(true);
}
else
{
- Struct[] structs = xfr.getHeader().getStructs();
DeliveryProperties deliveryProps = new DeliveryProperties();
deliveryProps.setRedelivered(true);
-
- List<Struct> list = Arrays.asList(structs);
- list.add(deliveryProps);
- xfr.setHeader(new Header(list));
+
+ xfr.setHeader(new Header(deliveryProps, header.getMessageProperties(),
+ header.getNonStandardProperties()));
}
}
@@ -299,7 +314,7 @@ public class Session extends SessionInvoker
{
DeliveryProperties deliveryProps = new DeliveryProperties();
deliveryProps.setRedelivered(true);
- xfr.setHeader(new Header(deliveryProps));
+ xfr.setHeader(new Header(deliveryProps, null, null));
}
}
sessionCommandPoint(m.getId(), 0);
@@ -394,38 +409,46 @@ public class Session extends SessionInvoker
public void processed(int command)
{
- processed(new Range(command, command));
+ processed(command, command);
}
- public void processed(int lower, int upper)
+ public void processed(Range range)
{
- processed(new Range(lower, upper));
+ processed(range.getLower(), range.getUpper());
}
- public void processed(Range range)
+ public void processed(int lower, int upper)
{
- log.debug("%s processed(%s) %s %s", this, range, syncPoint, maxProcessed);
+ if(log.isDebugEnabled())
+ {
+ log.debug("%s processed([%d,%d]) %s %s", this, lower, upper, syncPoint, maxProcessed);
+ }
boolean flush;
synchronized (processedLock)
{
- log.debug("%s", processed);
+ if(log.isDebugEnabled())
+ {
+ log.debug("%s", processed);
+ }
- if (ge(range.getUpper(), commandsIn))
+ if (ge(upper, commandsIn))
{
throw new IllegalArgumentException
- ("range exceeds max received command-id: " + range);
+ ("range exceeds max received command-id: " + Range.newInstance(lower, upper));
}
- processed.add(range);
+ processed.add(lower, upper);
+
Range first = processed.getFirst();
- int lower = first.getLower();
- int upper = first.getUpper();
+
+ int flower = first.getLower();
+ int fupper = first.getUpper();
int old = maxProcessed;
- if (le(lower, maxProcessed + 1))
+ if (le(flower, maxProcessed + 1))
{
- maxProcessed = max(maxProcessed, upper);
+ maxProcessed = max(maxProcessed, fupper);
}
boolean synced = ge(maxProcessed, syncPoint);
flush = lt(old, syncPoint) && synced;
@@ -442,7 +465,7 @@ public class Session extends SessionInvoker
void flushExpected()
{
- RangeSet rs = new RangeSet();
+ RangeSet rs = RangeSetFactory.createRangeSet();
synchronized (processedLock)
{
if (incomingInit)
@@ -478,7 +501,7 @@ public class Session extends SessionInvoker
{
synchronized (processedLock)
{
- RangeSet newProcessed = new RangeSet();
+ RangeSet newProcessed = RangeSetFactory.createRangeSet();
for (Range pr : processed)
{
for (Range kr : kc)
@@ -534,7 +557,12 @@ public class Session extends SessionInvoker
{
maxComplete = max(maxComplete, upper);
}
- log.debug("%s commands remaining: %s", this, commandsOut - maxComplete);
+
+ if(log.isDebugEnabled())
+ {
+ log.debug("%s commands remaining: %s", this, commandsOut - maxComplete);
+ }
+
commands.notifyAll();
return gt(maxComplete, old);
}
@@ -801,8 +829,17 @@ public class Session extends SessionInvoker
Waiter w = new Waiter(commands, timeout);
while (w.hasTime() && state != CLOSED && lt(maxComplete, point))
{
- checkFailoverRequired("Session sync was interrupted by failover.");
- log.debug("%s waiting for[%d]: %d, %s", this, point, maxComplete, commands);
+ checkFailoverRequired("Session sync was interrupted by failover.");
+ if(log.isDebugEnabled())
+ {
+ List<Method> waitingFor =
+ Arrays.asList(commands)
+ .subList(mod(maxComplete,commands.length),
+ mod(commandsOut-1, commands.length) < mod(maxComplete, commands.length)
+ ? commands.length-1
+ : mod(commandsOut-1, commands.length));
+ log.debug("%s waiting for[%d]: %d, %s", this, point, maxComplete, waitingFor);
+ }
w.await();
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java
index 3341149e5f..028b912ba1 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java
@@ -91,21 +91,38 @@ public class SessionDelegate
{
RangeSet ranges = cmp.getCommands();
RangeSet known = null;
- if (cmp.getTimelyReply())
- {
- known = new RangeSet();
- }
if (ranges != null)
{
- for (Range range : ranges)
+ if(ranges.size() == 1)
{
+ Range range = ranges.getFirst();
boolean advanced = ssn.complete(range.getLower(), range.getUpper());
- if (advanced && known != null)
+
+ if(advanced && cmp.getTimelyReply())
{
- known.add(range);
+ known = range;
}
}
+ else
+ {
+ if (cmp.getTimelyReply())
+ {
+ known = RangeSetFactory.createRangeSet();
+ }
+ for (Range range : ranges)
+ {
+ boolean advanced = ssn.complete(range.getLower(), range.getUpper());
+ if (advanced && known != null)
+ {
+ known.add(range);
+ }
+ }
+ }
+ }
+ else if (cmp.getTimelyReply())
+ {
+ known = RangeSetFactory.createRangeSet();
}
if (known != null)
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractDecoder.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractDecoder.java
index 09ce6a7eb1..6ff3b21400 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractDecoder.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractDecoder.java
@@ -29,12 +29,7 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
-import org.apache.qpid.transport.Binary;
-import org.apache.qpid.transport.RangeSet;
-import org.apache.qpid.transport.Struct;
-import org.apache.qpid.transport.Type;
-
-import static org.apache.qpid.transport.util.Functions.*;
+import org.apache.qpid.transport.*;
/**
@@ -194,18 +189,19 @@ abstract class AbstractDecoder implements Decoder
public RangeSet readSequenceSet()
{
int count = readUint16()/8;
- if (count == 0)
+ switch(count)
{
- return null;
- }
- else
- {
- RangeSet ranges = new RangeSet();
- for (int i = 0; i < count; i++)
- {
- ranges.add(readSequenceNo(), readSequenceNo());
- }
- return ranges;
+ case 0:
+ return null;
+ case 1:
+ return Range.newInstance(readSequenceNo(), readSequenceNo());
+ default:
+ RangeSet ranges = RangeSetFactory.createRangeSet(count);
+ for (int i = 0; i < count; i++)
+ {
+ ranges.add(readSequenceNo(), readSequenceNo());
+ }
+ return ranges;
}
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/BBEncoder.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/BBEncoder.java
index 4486b03a67..d9150bed65 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/BBEncoder.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/BBEncoder.java
@@ -70,6 +70,16 @@ public final class BBEncoder extends AbstractEncoder
return slice;
}
+ public int position()
+ {
+ return out.position();
+ }
+
+ public ByteBuffer underlyingBuffer()
+ {
+ return out;
+ }
+
private void grow(int size)
{
ByteBuffer old = out;
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/Assembler.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/Assembler.java
index 1a85ab88a5..8cd5c29f6d 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/Assembler.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/Assembler.java
@@ -26,13 +26,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.apache.qpid.transport.Header;
-import org.apache.qpid.transport.Method;
-import org.apache.qpid.transport.ProtocolError;
-import org.apache.qpid.transport.ProtocolEvent;
-import org.apache.qpid.transport.ProtocolHeader;
-import org.apache.qpid.transport.Receiver;
-import org.apache.qpid.transport.Struct;
+import org.apache.qpid.transport.*;
import org.apache.qpid.transport.codec.BBDecoder;
/**
@@ -198,12 +192,33 @@ public class Assembler implements Receiver<NetworkEvent>, NetworkDelegate
break;
case HEADER:
command = getIncompleteCommand(channel);
- List<Struct> structs = new ArrayList<Struct>(2);
+ List<Struct> structs = null;
+ DeliveryProperties deliveryProps = null;
+ MessageProperties messageProps = null;
+
while (dec.hasRemaining())
{
- structs.add(dec.readStruct32());
+ Struct struct = dec.readStruct32();
+ if(struct instanceof DeliveryProperties && deliveryProps == null)
+ {
+ deliveryProps = (DeliveryProperties) struct;
+ }
+ else if(struct instanceof MessageProperties && messageProps == null)
+ {
+ messageProps = (MessageProperties) struct;
+ }
+ else
+ {
+ if(structs == null)
+ {
+ structs = new ArrayList<Struct>(2);
+ }
+ structs.add(struct);
+ }
+
}
- command.setHeader(new Header(structs));
+ command.setHeader(new Header(deliveryProps,messageProps,structs));
+
if (frame.isLastSegment())
{
setIncompleteCommand(channel, null);
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/Disassembler.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/Disassembler.java
index 685034d1a9..6ac9df9bc3 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/Disassembler.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/Disassembler.java
@@ -87,27 +87,35 @@ public final class Disassembler implements Sender<ProtocolEvent>, ProtocolDelega
}
}
+ private final ByteBuffer _frameHeader = ByteBuffer.allocate(HEADER_SIZE);
+
+ {
+ _frameHeader.order(ByteOrder.BIG_ENDIAN);
+ }
+
private void frame(byte flags, byte type, byte track, int channel, int size, ByteBuffer buf)
{
synchronized (sendlock)
{
- ByteBuffer data = ByteBuffer.allocate(size + HEADER_SIZE);
- data.order(ByteOrder.BIG_ENDIAN);
+ ByteBuffer data = _frameHeader;
+ _frameHeader.rewind();
+
data.put(0, flags);
data.put(1, type);
data.putShort(2, (short) (size + HEADER_SIZE));
data.put(5, track);
data.putShort(6, (short) channel);
- data.position(HEADER_SIZE);
+
int limit = buf.limit();
buf.limit(buf.position() + size);
- data.put(buf);
- buf.limit(limit);
-
+
data.rewind();
sender.send(data);
+ sender.send(buf);
+ buf.limit(limit);
+
}
}
@@ -179,7 +187,7 @@ public final class Disassembler implements Sender<ProtocolEvent>, ProtocolDelega
}
}
method.write(enc);
- ByteBuffer methodSeg = enc.segment();
+ int methodLimit = enc.position();
byte flags = FIRST_SEG;
@@ -189,29 +197,44 @@ public final class Disassembler implements Sender<ProtocolEvent>, ProtocolDelega
flags |= LAST_SEG;
}
- ByteBuffer headerSeg = null;
+ int headerLimit = -1;
if (payload)
{
final Header hdr = method.getHeader();
if (hdr != null)
{
- final Struct[] structs = hdr.getStructs();
-
- for (Struct st : structs)
+ if(hdr.getDeliveryProperties() != null)
+ {
+ enc.writeStruct32(hdr.getDeliveryProperties());
+ }
+ if(hdr.getMessageProperties() != null)
+ {
+ enc.writeStruct32(hdr.getMessageProperties());
+ }
+ if(hdr.getNonStandardProperties() != null)
{
- enc.writeStruct32(st);
+ for (Struct st : hdr.getNonStandardProperties())
+ {
+ enc.writeStruct32(st);
+ }
}
}
- headerSeg = enc.segment();
+ headerLimit = enc.position();
}
synchronized (sendlock)
{
- fragment(flags, type, method, methodSeg);
+ ByteBuffer buf = enc.underlyingBuffer();
+ buf.position(0);
+ buf.limit(methodLimit);
+
+ fragment(flags, type, method, buf);
if (payload)
{
ByteBuffer body = method.getBody();
- fragment(body == null ? LAST_SEG : 0x0, SegmentType.HEADER, method, headerSeg);
+ buf.limit(headerLimit);
+ buf.position(methodLimit);
+ fragment(body == null ? LAST_SEG : 0x0, SegmentType.HEADER, method, buf);
if (body != null)
{
fragment(LAST_SEG, SegmentType.BODY, method, body);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/util/ByteBufferInputStream.java b/qpid/java/common/src/main/java/org/apache/qpid/util/ByteBufferInputStream.java
index 898a667736..b72b342187 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/util/ByteBufferInputStream.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/util/ByteBufferInputStream.java
@@ -18,12 +18,15 @@
* under the License.
*
*/
-package org.apache.qpid.server.util;
+package org.apache.qpid.util;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
+/**
+ * Wraps @link {@link ByteBuffer} into {@link InputStream}
+ */
public class ByteBufferInputStream extends InputStream
{
private final ByteBuffer _buffer;
@@ -36,13 +39,20 @@ public class ByteBufferInputStream extends InputStream
@Override
public int read() throws IOException
{
- return _buffer.get() & 0xFF;
+ if (_buffer.hasRemaining())
+ {
+ return _buffer.get() & 0xFF;
+ }
+ return -1;
}
-
@Override
public int read(byte[] b, int off, int len) throws IOException
{
+ if (!_buffer.hasRemaining())
+ {
+ return -1;
+ }
if(_buffer.remaining() < len)
{
len = _buffer.remaining();
@@ -73,9 +83,7 @@ public class ByteBufferInputStream extends InputStream
@Override
public long skip(long n) throws IOException
{
-
_buffer.position(_buffer.position()+(int)n);
-
return n;
}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java b/qpid/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java
index bd189feb1c..cb9a9468bb 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java
+++ b/qpid/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java
@@ -581,10 +581,10 @@ public class PropertyFieldTableTest extends TestCase
table.setBytes("bytes", bytes);
table.setChar("char", 'c');
- table.setDouble("double", Double.MAX_VALUE);
- table.setFloat("float", Float.MAX_VALUE);
table.setInteger("int", Integer.MAX_VALUE);
table.setLong("long", Long.MAX_VALUE);
+ table.setDouble("double", Double.MAX_VALUE);
+ table.setFloat("float", Float.MAX_VALUE);
table.setShort("short", Short.MAX_VALUE);
table.setString("string", "hello");
table.setString("null-string", null);
@@ -823,9 +823,7 @@ public class PropertyFieldTableTest extends TestCase
*/
public void testCheckPropertyNamehasMaxLength()
{
- String oldVal = System.getProperty("STRICT_AMQP");
- System.setProperty("STRICT_AMQP", "true");
- FieldTable table = new FieldTable();
+ FieldTable table = new FieldTable(true);
StringBuffer longPropertyName = new StringBuffer(129);
@@ -845,14 +843,6 @@ public class PropertyFieldTableTest extends TestCase
}
// so length should be zero
Assert.assertEquals(0, table.getEncodedSize());
- if (oldVal != null)
- {
- System.setProperty("STRICT_AMQP", oldVal);
- }
- else
- {
- System.clearProperty("STRICT_AMQP");
- }
}
/**
@@ -860,9 +850,7 @@ public class PropertyFieldTableTest extends TestCase
*/
public void testCheckPropertyNameStartCharacterIsLetter()
{
- String oldVal = System.getProperty("STRICT_AMQP");
- System.setProperty("STRICT_AMQP", "true");
- FieldTable table = new FieldTable();
+ FieldTable table = new FieldTable(true);
// Try a name that starts with a number
try
@@ -876,14 +864,6 @@ public class PropertyFieldTableTest extends TestCase
}
// so length should be zero
Assert.assertEquals(0, table.getEncodedSize());
- if (oldVal != null)
- {
- System.setProperty("STRICT_AMQP", oldVal);
- }
- else
- {
- System.clearProperty("STRICT_AMQP");
- }
}
/**
@@ -891,9 +871,7 @@ public class PropertyFieldTableTest extends TestCase
*/
public void testCheckPropertyNameStartCharacterIsHashorDollar()
{
- String oldVal = System.getProperty("STRICT_AMQP");
- System.setProperty("STRICT_AMQP", "true");
- FieldTable table = new FieldTable();
+ FieldTable table = new FieldTable(true);
// Try a name that starts with a number
try
@@ -906,14 +884,6 @@ public class PropertyFieldTableTest extends TestCase
fail("property name are allowed to start with # and $s");
}
- if (oldVal != null)
- {
- System.setProperty("STRICT_AMQP", oldVal);
- }
- else
- {
- System.clearProperty("STRICT_AMQP");
- }
}
/**
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/RangeSetTest.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/RangeSetTest.java
index ad45d00e46..889250e004 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/transport/RangeSetTest.java
+++ b/qpid/java/common/src/test/java/org/apache/qpid/transport/RangeSetTest.java
@@ -60,7 +60,7 @@ public class RangeSetTest extends TestCase
public void test1()
{
- RangeSet ranges = new RangeSet();
+ RangeSet ranges = RangeSetFactory.createRangeSet();
ranges.add(5, 10);
check(ranges);
ranges.add(15, 20);
@@ -77,7 +77,7 @@ public class RangeSetTest extends TestCase
public void test2()
{
- RangeSet rs = new RangeSet();
+ RangeSet rs = RangeSetFactory.createRangeSet();
check(rs);
rs.add(1);
@@ -128,7 +128,7 @@ public class RangeSetTest extends TestCase
public void testAddSelf()
{
- RangeSet a = new RangeSet();
+ RangeSet a = RangeSetFactory.createRangeSet();
a.add(0, 8);
check(a);
a.add(0, 8);
@@ -141,8 +141,8 @@ public class RangeSetTest extends TestCase
public void testIntersect1()
{
- Range a = new Range(0, 10);
- Range b = new Range(9, 20);
+ Range a = Range.newInstance(0, 10);
+ Range b = Range.newInstance(9, 20);
Range i1 = a.intersect(b);
Range i2 = b.intersect(a);
assertEquals(i1.getUpper(), 10);
@@ -153,16 +153,16 @@ public class RangeSetTest extends TestCase
public void testIntersect2()
{
- Range a = new Range(0, 10);
- Range b = new Range(11, 20);
+ Range a = Range.newInstance(0, 10);
+ Range b = Range.newInstance(11, 20);
assertNull(a.intersect(b));
assertNull(b.intersect(a));
}
public void testIntersect3()
{
- Range a = new Range(0, 10);
- Range b = new Range(3, 5);
+ Range a = Range.newInstance(0, 10);
+ Range b = Range.newInstance(3, 5);
Range i1 = a.intersect(b);
Range i2 = b.intersect(a);
assertEquals(i1.getUpper(), 5);
@@ -173,14 +173,14 @@ public class RangeSetTest extends TestCase
public void testSubtract1()
{
- Range a = new Range(0, 10);
+ Range a = Range.newInstance(0, 10);
assertTrue(a.subtract(a).isEmpty());
}
public void testSubtract2()
{
- Range a = new Range(0, 10);
- Range b = new Range(20, 30);
+ Range a = Range.newInstance(0, 10);
+ Range b = Range.newInstance(20, 30);
List<Range> ranges = a.subtract(b);
assertEquals(ranges.size(), 1);
Range d = ranges.get(0);
@@ -190,8 +190,8 @@ public class RangeSetTest extends TestCase
public void testSubtract3()
{
- Range a = new Range(20, 30);
- Range b = new Range(0, 10);
+ Range a = Range.newInstance(20, 30);
+ Range b = Range.newInstance(0, 10);
List<Range> ranges = a.subtract(b);
assertEquals(ranges.size(), 1);
Range d = ranges.get(0);
@@ -201,8 +201,8 @@ public class RangeSetTest extends TestCase
public void testSubtract4()
{
- Range a = new Range(0, 10);
- Range b = new Range(3, 5);
+ Range a = Range.newInstance(0, 10);
+ Range b = Range.newInstance(3, 5);
List<Range> ranges = a.subtract(b);
assertEquals(ranges.size(), 2);
Range low = ranges.get(0);
@@ -215,8 +215,8 @@ public class RangeSetTest extends TestCase
public void testSubtract5()
{
- Range a = new Range(0, 10);
- Range b = new Range(3, 20);
+ Range a = Range.newInstance(0, 10);
+ Range b = Range.newInstance(3, 20);
List<Range> ranges = a.subtract(b);
assertEquals(ranges.size(), 1);
Range d = ranges.get(0);
@@ -226,8 +226,8 @@ public class RangeSetTest extends TestCase
public void testSubtract6()
{
- Range a = new Range(0, 10);
- Range b = new Range(-10, 5);
+ Range a = Range.newInstance(0, 10);
+ Range b = Range.newInstance(-10, 5);
List<Range> ranges = a.subtract(b);
assertEquals(ranges.size(), 1);
Range d = ranges.get(0);
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/util/ByteBufferInputStreamTest.java b/qpid/java/common/src/test/java/org/apache/qpid/util/ByteBufferInputStreamTest.java
new file mode 100644
index 0000000000..0b393a489f
--- /dev/null
+++ b/qpid/java/common/src/test/java/org/apache/qpid/util/ByteBufferInputStreamTest.java
@@ -0,0 +1,111 @@
+/*
+ *
+ * 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.util;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+public class ByteBufferInputStreamTest extends TestCase
+{
+ private byte[] _data = {2, 1, 5, 3, 4};
+ private ByteBufferInputStream _inputStream;
+
+ public void setUp() throws Exception
+ {
+ _inputStream = new ByteBufferInputStream(ByteBuffer.wrap(_data));
+ }
+
+ public void testRead() throws IOException
+ {
+ for (int i = 0; i < _data.length; i++)
+ {
+ assertEquals("Unexpected byte at position " + i, _data[i], _inputStream.read());
+ }
+ assertEquals("EOF not reached", -1, _inputStream.read());
+ }
+
+ public void testReadByteArray() throws IOException
+ {
+ byte[] readBytes = new byte[_data.length];
+ int length = _inputStream.read(readBytes, 0, 2);
+
+ byte[] expected = new byte[_data.length];
+ System.arraycopy(_data, 0, expected, 0, 2);
+
+ assertTrue("Unexpected data", Arrays.equals(expected, readBytes));
+ assertEquals("Unexpected length", 2, length);
+
+ length = _inputStream.read(readBytes, 2, 3);
+
+ assertTrue("Unexpected data", Arrays.equals(_data, readBytes));
+ assertEquals("Unexpected length", 3, length);
+
+ length = _inputStream.read(readBytes);
+ assertEquals("EOF not reached", -1, length);
+ }
+
+ public void testSkip() throws IOException
+ {
+ _inputStream.skip(3);
+ byte[] readBytes = new byte[_data.length - 3];
+ int length = _inputStream.read(readBytes);
+
+ byte[] expected = new byte[_data.length - 3];
+ System.arraycopy(_data, 3, expected, 0, _data.length - 3);
+
+ assertTrue("Unexpected data", Arrays.equals(expected, readBytes));
+ assertEquals("Unexpected length", _data.length - 3, length);
+ }
+
+ public void testAvailable() throws IOException
+ {
+ int available = _inputStream.available();
+ assertEquals("Unexpected number of available bytes", _data.length, available);
+ byte[] readBytes = new byte[_data.length];
+ _inputStream.read(readBytes);
+ available = _inputStream.available();
+ assertEquals("Unexpected number of available bytes", 0, available);
+ }
+
+ public void testMarkReset() throws IOException
+ {
+ _inputStream.mark(0);
+ byte[] readBytes = new byte[_data.length];
+ int length = _inputStream.read(readBytes);
+ assertEquals("Unexpected length", _data.length, length);
+ assertEquals("Unexpected number of available bytes", 0, _inputStream.available());
+
+ _inputStream.reset();
+ readBytes = new byte[_data.length];
+ length = _inputStream.read(readBytes);
+ assertEquals("Unexpected length", _data.length, length);
+ assertEquals("Unexpected number of available bytes", 0, _inputStream.available());
+ }
+
+ public void testMarkSupported() throws IOException
+ {
+ assertTrue("Unexpected mark supported", _inputStream.markSupported());
+ }
+
+}
diff --git a/qpid/java/common/templates/method/version/MethodBodyClass.vm b/qpid/java/common/templates/method/version/MethodBodyClass.vm
index ce8a453eeb..0e444b87df 100644
--- a/qpid/java/common/templates/method/version/MethodBodyClass.vm
+++ b/qpid/java/common/templates/method/version/MethodBodyClass.vm
@@ -46,8 +46,9 @@
package org.apache.qpid.framing.amqp_$version.getMajor()_$version.getMinor();
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
+import java.io.DataInput;
+import org.apache.qpid.codec.MarkableDataInput;
+import java.io.DataOutput;
import java.io.IOException;
import java.util.HashMap;
@@ -58,7 +59,7 @@ public class ${javaClassName} extends AMQMethodBody_$version.getMajor()_$version
{
private static final AMQMethodBodyInstanceFactory FACTORY_INSTANCE = new AMQMethodBodyInstanceFactory()
{
- public AMQMethodBody newInstance(DataInputStream in, long size) throws AMQFrameDecodingException, IOException
+ public AMQMethodBody newInstance(MarkableDataInput in, long size) throws AMQFrameDecodingException, IOException
{
return new ${javaClassName}(in);
}
@@ -86,7 +87,7 @@ public class ${javaClassName} extends AMQMethodBody_$version.getMajor()_$version
// Constructor
- public ${javaClassName}(DataInputStream buffer) throws AMQFrameDecodingException, IOException
+ public ${javaClassName}(MarkableDataInput buffer) throws AMQFrameDecodingException, IOException
{
#foreach( $field in $method.ConsolidatedFields )
_$field.Name = read$field.getEncodingType()( buffer );
@@ -171,7 +172,7 @@ public class ${javaClassName} extends AMQMethodBody_$version.getMajor()_$version
return size;
}
- public void writeMethodPayload(DataOutputStream buffer) throws IOException
+ public void writeMethodPayload(DataOutput buffer) throws IOException
{
#foreach( $field in $method.ConsolidatedFields )
write$field.getEncodingType()( buffer, _$field.Name );
diff --git a/qpid/java/common/templates/model/MethodRegistryClass.vm b/qpid/java/common/templates/model/MethodRegistryClass.vm
index 8258175ce7..f8a55f245a 100644
--- a/qpid/java/common/templates/model/MethodRegistryClass.vm
+++ b/qpid/java/common/templates/model/MethodRegistryClass.vm
@@ -30,10 +30,10 @@
package org.apache.qpid.framing;
-import java.io.DataInputStream;
import java.io.IOException;
import org.apache.qpid.framing.abstraction.ProtocolVersionMethodConverter;
+import org.apache.qpid.codec.MarkableDataInput;
import java.util.Map;
import java.util.HashMap;
@@ -54,7 +54,7 @@ public abstract class MethodRegistry
#end
- public abstract AMQMethodBody convertToBody(DataInputStream in, long size)
+ public abstract AMQMethodBody convertToBody(MarkableDataInput in, long size)
throws AMQFrameDecodingException, IOException;
public abstract int getMaxClassId();
diff --git a/qpid/java/common/templates/model/version/MethodRegistryClass.vm b/qpid/java/common/templates/model/version/MethodRegistryClass.vm
index 79553f7748..ab5db0ea38 100644
--- a/qpid/java/common/templates/model/version/MethodRegistryClass.vm
+++ b/qpid/java/common/templates/model/version/MethodRegistryClass.vm
@@ -35,10 +35,10 @@ import org.apache.qpid.protocol.AMQConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.DataInputStream;
import java.io.IOException;
import org.apache.qpid.framing.abstraction.ProtocolVersionMethodConverter;
+import org.apache.qpid.codec.MarkableDataInput;
public class MethodRegistry_$version.getMajor()_$version.getMinor() extends MethodRegistry
@@ -87,7 +87,7 @@ public class MethodRegistry_$version.getMajor()_$version.getMinor() extends Meth
}
- public AMQMethodBody convertToBody(DataInputStream in, long size)
+ public AMQMethodBody convertToBody(MarkableDataInput in, long size)
throws AMQFrameDecodingException, IOException
{
int classId = in.readUnsignedShort();
diff --git a/qpid/java/jca/example/qpid-jca-example-properties.xml b/qpid/java/jca/example/qpid-jca-example-properties.xml
index ee0478a6e5..076e5dc241 100644
--- a/qpid/java/jca/example/qpid-jca-example-properties.xml
+++ b/qpid/java/jca/example/qpid-jca-example-properties.xml
@@ -49,17 +49,17 @@
value="responder.Queue;{create:always, node:{type:queue, x-declare:{auto-delete:true}}}"/>
<property name="qpid.hello.topic.dest.address.BURL"
- value="topic://amq.topic//hello.jcaTopic?routingKey='hello.jcaTopic',autodelete='true'"/>
+ value="BURL:topic://amq.topic//hello.jcaTopic?routingKey='hello.jcaTopic',autodelete='true'"/>
<property name="qpid.goodbye.topic.dest.address.BURL"
- value="topic://amq.topic//goodbye.jcaTopic?routingKey='goodbye.jcaTopic',autodelete='true'"/>
+ value="BURL:topic://amq.topic//goodbye.jcaTopic?routingKey='goodbye.jcaTopic',autodelete='true'"/>
<property name="qpid.hellogoodbye.topic.dest.address.BURL"
- value="topic://amq.topic//#.jcaTopic"/>
+ value="BURL:topic://amq.topic//#.jcaTopic"/>
<property name="qpid.hello.queue.dest.address.BURL"
- value="direct://amq.direct//hello.Queue?routingkey='hello.Queue'"/>
+ value="BURL:direct://amq.direct//hello.Queue?routingkey='hello.Queue'"/>
<property name="qpid.goodbye.queue.dest.address.BURL"
- value="direct://amq.direct//goodbye.Queue?routingkey='goodbye.Queue'"/>
+ value="BURL:direct://amq.direct//goodbye.Queue?routingkey='goodbye.Queue'"/>
<property name="qpid.responder.queue.dest.address.BURL"
- value="direct://amq.direct//responder.Queue?routingkey='responder.Queue'"/>
+ value="BURL:direct://amq.direct//responder.Queue?routingkey='responder.Queue'"/>
<!-- This macro allows us to construct a property name which contains a property expansion -->
<macrodef name="set-address-property">
diff --git a/qpid/java/jca/src/main/java/org/apache/qpid/ra/QpidRAManagedConnection.java b/qpid/java/jca/src/main/java/org/apache/qpid/ra/QpidRAManagedConnection.java
index fb1b7f060c..53896d8872 100644
--- a/qpid/java/jca/src/main/java/org/apache/qpid/ra/QpidRAManagedConnection.java
+++ b/qpid/java/jca/src/main/java/org/apache/qpid/ra/QpidRAManagedConnection.java
@@ -57,6 +57,8 @@ import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.transaction.xa.XAResource;
+import org.apache.qpid.client.Closeable;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -752,26 +754,25 @@ public class QpidRAManagedConnection implements ManagedConnection, ExceptionList
try
{
- boolean transacted = _cri.isTransacted();
- int acknowledgeMode = Session.AUTO_ACKNOWLEDGE;
- boolean localTx = _mcf.getUseLocalTx();
+ boolean transacted = _cri.isTransacted() || _mcf.getUseLocalTx();
+ int acknowledgeMode = (transacted) ? Session.SESSION_TRANSACTED : _cri.getAcknowledgeMode();
if (_cri.getType() == QpidRAConnectionFactory.TOPIC_CONNECTION)
{
if (_userName != null && _password != null)
{
- if(!localTx)
+ if(!transacted)
{
_connection = _mcf.getCleanAMQConnectionFactory().createXATopicConnection(_userName, _password);
}
else
{
- _connection = _mcf.getCleanAMQConnectionFactory().createTopicConnection();
+ _connection = _mcf.getCleanAMQConnectionFactory().createTopicConnection(_userName, _password);
}
}
else
{
- if(!localTx)
+ if(!transacted)
{
_connection = _mcf.getDefaultAMQConnectionFactory().createXATopicConnection();
}
@@ -781,32 +782,31 @@ public class QpidRAManagedConnection implements ManagedConnection, ExceptionList
}
}
- if(!localTx)
+ if(!transacted)
{
_xaSession = ((XATopicConnection)_connection).createXATopicSession();
-
}
else
{
- _session = ((TopicConnection)_connection).createTopicSession(localTx, acknowledgeMode);
+ _session = ((TopicConnection)_connection).createTopicSession(transacted, acknowledgeMode);
}
}
else if (_cri.getType() == QpidRAConnectionFactory.QUEUE_CONNECTION)
{
if (_userName != null && _password != null)
{
- if(!localTx)
+ if(!transacted)
{
_connection = _mcf.getCleanAMQConnectionFactory().createXAQueueConnection(_userName, _password);
}
else
{
- _connection = _mcf.getCleanAMQConnectionFactory().createQueueConnection();
+ _connection = _mcf.getCleanAMQConnectionFactory().createQueueConnection(_userName, _password);
}
}
else
{
- if(!localTx)
+ if(!transacted)
{
_connection = _mcf.getDefaultAMQConnectionFactory().createXAQueueConnection();
}
@@ -816,14 +816,14 @@ public class QpidRAManagedConnection implements ManagedConnection, ExceptionList
}
}
- if(!localTx)
+ if(!transacted)
{
_xaSession = ((XAQueueConnection)_connection).createXAQueueSession();
}
else
{
- _session = ((QueueConnection)_connection).createQueueSession(localTx, acknowledgeMode);
+ _session = ((QueueConnection)_connection).createQueueSession(transacted, acknowledgeMode);
}
}
@@ -831,18 +831,18 @@ public class QpidRAManagedConnection implements ManagedConnection, ExceptionList
{
if (_userName != null && _password != null)
{
- if(!localTx)
+ if(!transacted)
{
_connection = _mcf.getCleanAMQConnectionFactory().createXAConnection(_userName, _password);
}
else
{
- _connection = _mcf.getCleanAMQConnectionFactory().createConnection();
+ _connection = _mcf.getCleanAMQConnectionFactory().createConnection(_userName, _password);
}
}
else
{
- if(!localTx)
+ if(!transacted)
{
_connection = _mcf.getDefaultAMQConnectionFactory().createXAConnection();
}
@@ -852,22 +852,24 @@ public class QpidRAManagedConnection implements ManagedConnection, ExceptionList
}
}
- if(!localTx)
+ if(!transacted)
{
_xaSession = ((XAQueueConnection)_connection).createXASession();
}
else
{
- _session = ((QueueConnection)_connection).createSession(localTx, acknowledgeMode);
+ _session = ((QueueConnection)_connection).createSession(transacted, acknowledgeMode);
}
}
_connection.setExceptionListener(this);
+
}
catch (JMSException je)
{
+ _log.error(je.getMessage(), je);
throw new ResourceException(je.getMessage(), je);
}
}
@@ -877,4 +879,9 @@ public class QpidRAManagedConnection implements ManagedConnection, ExceptionList
this._inManagedTx = inManagedTx;
}
+ public boolean isConnectionClosed()
+ {
+ Closeable c = (Closeable)_connection;
+ return (c == null || c.isClosed() || c.isClosing());
+ }
}
diff --git a/qpid/java/jca/src/main/java/org/apache/qpid/ra/QpidRAMessage.java b/qpid/java/jca/src/main/java/org/apache/qpid/ra/QpidRAMessage.java
index 691fe8c40a..295a453010 100644
--- a/qpid/java/jca/src/main/java/org/apache/qpid/ra/QpidRAMessage.java
+++ b/qpid/java/jca/src/main/java/org/apache/qpid/ra/QpidRAMessage.java
@@ -71,7 +71,7 @@ public class QpidRAMessage implements Message
_log.trace("acknowledge()");
}
- _session.getSession(); // Check for closed
+ _session.getSessionInternal(); // Check for closed
_message.acknowledge();
}
diff --git a/qpid/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionImpl.java b/qpid/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionImpl.java
index a270253c13..fdd4888a3d 100644
--- a/qpid/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionImpl.java
+++ b/qpid/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionImpl.java
@@ -410,19 +410,24 @@ public class QpidRASessionImpl implements Session, QueueSession, TopicSession, X
lock();
try
{
- Session session = getSessionInternal();
if (_cri.isTransacted() == false)
{
throw new IllegalStateException("Session is not transacted");
}
+ if(_lockedMC.isConnectionClosed())
+ {
+ throw new IllegalStateException("Attempting to call commit when the underlying connection has been closed.");
+ }
+
if (_log.isTraceEnabled())
{
_log.trace("Commit session " + this);
}
- session.commit();
+ getSessionInternal().commit();
+
}
finally
{
diff --git a/qpid/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidActivation.java b/qpid/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidActivation.java
index 98427d7f9d..57edec8eee 100644
--- a/qpid/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidActivation.java
+++ b/qpid/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidActivation.java
@@ -113,6 +113,9 @@ public class QpidActivation implements ExceptionListener
// Whether we are in the failure recovery loop
private AtomicBoolean _inFailure = new AtomicBoolean(false);
+ //Whether or not we have completed activating
+ private AtomicBoolean _activated = new AtomicBoolean(false);
+
static
{
try
@@ -242,7 +245,7 @@ public class QpidActivation implements ExceptionListener
_log.trace("start()");
}
_deliveryActive.set(true);
- _ra.getWorkManager().scheduleWork(new SetupActivation());
+ new Thread(new SetupActivation()).start();
}
/**
@@ -323,8 +326,10 @@ public class QpidActivation implements ExceptionListener
throw e;
}
}
+
amqConnection.start() ;
this._connection = amqConnection ;
+ _activated.set(true);
_log.debug("Setup complete " + this);
}
@@ -422,7 +427,6 @@ public class QpidActivation implements ExceptionListener
" of type " +
destinationType.getName());
_destination = Util.lookup(ctx, destinationName, destinationType);
- //_destination = (Destination)ctx.lookup(destinationName);
}
else
@@ -490,7 +494,14 @@ public class QpidActivation implements ExceptionListener
public void onException(final JMSException jmse)
{
- handleFailure(jmse) ;
+ if(_activated.get())
+ {
+ handleFailure(jmse) ;
+ }
+ else
+ {
+ _log.warn("Received JMSException: " + jmse + " while endpoint was not activated.");
+ }
}
/**
diff --git a/qpid/java/lib/cobertura/README.txt b/qpid/java/lib/cobertura/README.txt
index 8e4cc09a80..080bb5f2f3 100644
--- a/qpid/java/lib/cobertura/README.txt
+++ b/qpid/java/lib/cobertura/README.txt
@@ -1,10 +1,9 @@
-Download the cobertura binary from the following location:
+Download the cobertura binary from the following location and expand it into
+this directory.
http://cobertura.sourceforge.net/download.html
-
-Unpack it into the cobertura (this) directory with tar --strip-path 1 -xf.
-This should leave you with cobertura.jar in qpid/java/lib/cobertura.
+Alternatively run "ant download-cobertura" to do this automatically.
+(to set a http proxy for ant use ANT_OPTS="-Dhttp.proxyHost=<host> -Dhttp.proxyPort=<port>")
Run "ant cover-test coverage-report" to generate coverage report.
-
diff --git a/qpid/java/lib/poms/je-4.0.117.xml b/qpid/java/lib/poms/je-4.0.117.xml
deleted file mode 100644
index 85573a99f9..0000000000
--- a/qpid/java/lib/poms/je-4.0.117.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<dep>
- <groupId>com.sleepycat</groupId>
- <artifactId>je</artifactId>
- <version>4.0.117</version>
-</dep>
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/client/prefetch/PrefetchBehaviourTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/client/prefetch/PrefetchBehaviourTest.java
index d2950b095b..5c5ad66777 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/client/prefetch/PrefetchBehaviourTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/client/prefetch/PrefetchBehaviourTest.java
@@ -5,12 +5,14 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.jms.Connection;
+import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
+import javax.jms.TextMessage;
import org.apache.qpid.configuration.ClientProperties;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
@@ -133,4 +135,41 @@ public class PrefetchBehaviourTest extends QpidBrokerTestCase
assertFalse("Unexpecte exception during async message processing",_exceptionCaught.get());
}
+ /**
+ * Test Goal: Verify if connection stop releases all messages in it's prefetch buffer.
+ * Test Strategy: Send 10 messages to a queue. Create a consumer with maxprefetch of 5, but never consume them.
+ * Stop the connection. Create a new connection and a consumer with maxprefetch 10 on the same queue.
+ * Try to receive all 10 messages.
+ */
+ public void testConnectionStop() throws Exception
+ {
+ setTestClientSystemProperty(ClientProperties.MAX_PREFETCH_PROP_NAME, "10");
+ Connection con = getConnection();
+ con.start();
+ Session ssn = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Destination queue = ssn.createQueue("ADDR:my-queue;{create: always}");
+
+ MessageProducer prod = ssn.createProducer(queue);
+ for (int i=0; i<10;i++)
+ {
+ prod.send(ssn.createTextMessage("Msg" + i));
+ }
+
+ MessageConsumer consumer = ssn.createConsumer(queue);
+ // This is to ensure we get the first client to prefetch.
+ Message msg = consumer.receive(1000);
+ assertNotNull("The first consumer should get one message",msg);
+ con.stop();
+
+ Connection con2 = getConnection();
+ con2.start();
+ Session ssn2 = con2.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer consumer2 = ssn2.createConsumer(queue);
+ for (int i=0; i<9;i++)
+ {
+ TextMessage m = (TextMessage)consumer2.receive(1000);
+ assertNotNull("The second consumer should get 9 messages, but received only " + i,m);
+ }
+ }
+
}
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
new file mode 100644
index 0000000000..08a932eba1
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MessageGroupQueueTest.java
@@ -0,0 +1,481 @@
+/*
+*
+* 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.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 javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import java.util.HashMap;
+import java.util.Map;
+
+public class MessageGroupQueueTest extends QpidBrokerTestCase
+{
+ protected final String QUEUE = "MessageGroupQueue";
+
+ private Connection producerConnection;
+ private MessageProducer producer;
+ private Session producerSession;
+ private Queue queue;
+ private Connection consumerConnection;
+
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ producerConnection = getConnection();
+ producerSession = producerConnection.createSession(true, Session.AUTO_ACKNOWLEDGE);
+
+ producerConnection.start();
+
+ consumerConnection = getConnection();
+
+ }
+
+ protected void tearDown() throws Exception
+ {
+ producerConnection.close();
+ consumerConnection.close();
+ super.tearDown();
+ }
+
+
+ public void testSimpleGroupAssignment() throws Exception
+ {
+ simpleGroupAssignment(false);
+ }
+
+ public void testSharedGroupSimpleGroupAssignment() throws Exception
+ {
+ simpleGroupAssignment(true);
+ }
+
+
+ /**
+ * Pre populate the queue with messages with groups as follows
+ *
+ * ONE
+ * TWO
+ * ONE
+ * TWO
+ *
+ * Create two consumers with prefetch of 1, the first consumer should then be assigned group ONE, the second
+ * consumer assigned group TWO if they are started in sequence.
+ *
+ * Thus doing
+ *
+ * c1 <--- (ONE)
+ * c2 <--- (TWO)
+ * c2 ack --->
+ *
+ * c2 should now be able to receive a second message from group TWO (skipping over the message from group ONE)
+ *
+ * i.e.
+ *
+ * c2 <--- (TWO)
+ * c2 ack --->
+ * c1 <--- (ONE)
+ * c1 ack --->
+ *
+ */
+ private void simpleGroupAssignment(boolean sharedGroups) throws AMQException, JMSException
+ {
+ final Map<String,Object> arguments = new HashMap<String, Object>();
+ arguments.put("qpid.group_header_key","group");
+ if(sharedGroups)
+ {
+ arguments.put("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);
+
+ String[] groups = { "ONE", "TWO"};
+
+ for (int msg = 0; msg < 4; msg++)
+ {
+ producer.send(createMessage(msg, groups[msg % groups.length]));
+ }
+ producerSession.commit();
+ producer.close();
+ producerSession.close();
+ producerConnection.close();
+
+ Session cs1 = ((AMQConnection)consumerConnection).createSession(false, Session.CLIENT_ACKNOWLEDGE,1);
+ Session cs2 = ((AMQConnection)consumerConnection).createSession(false, Session.CLIENT_ACKNOWLEDGE,1);
+
+
+ MessageConsumer consumer1 = cs1.createConsumer(queue);
+ MessageConsumer consumer2 = cs2.createConsumer(queue);
+
+ consumerConnection.start();
+ Message cs1Received = consumer1.receive(1000);
+ assertNotNull("Consumer 1 should have received first message", cs1Received);
+
+ Message cs2Received = consumer2.receive(1000);
+
+ assertNotNull("Consumer 2 should have received first message", cs2Received);
+
+ cs1Received.acknowledge();
+ cs2Received.acknowledge();
+
+ Message cs2Received2 = consumer2.receive(1000);
+
+ assertNotNull("Consumer 2 should have received second message", cs2Received2);
+ assertEquals("Differing groups", cs2Received2.getStringProperty("group"),
+ cs2Received.getStringProperty("group"));
+
+ Message cs1Received2 = consumer1.receive(1000);
+
+ assertNotNull("Consumer 1 should have received second message", cs1Received2);
+ assertEquals("Differing groups", cs1Received2.getStringProperty("group"),
+ cs1Received.getStringProperty("group"));
+
+ cs1Received2.acknowledge();
+ cs2Received2.acknowledge();
+
+ assertNull(consumer1.receive(1000));
+ assertNull(consumer2.receive(1000));
+ }
+
+
+ public void testConsumerCloseGroupAssignment() throws Exception
+ {
+ consumerCloseGroupAssignment(false);
+ }
+
+ public void testSharedGroupConsumerCloseGroupAssignment() throws Exception
+ {
+ consumerCloseGroupAssignment(true);
+ }
+
+ /**
+ *
+ * Tests that upon closing a consumer, groups previously assigned to that consumer are reassigned to a different
+ * consumer.
+ *
+ * Pre-populate the queue as ONE, ONE, TWO, ONE
+ *
+ * create in sequence two consumers
+ *
+ * receive first from c1 then c2 (thus ONE is assigned to c1, TWO to c2)
+ *
+ * Then close c1 before acking.
+ *
+ * If we now attempt to receive from c2, then the remaining messages in group ONE should be available (which
+ * requires c2 to go "backwards" in the queue).
+ *
+ **/
+ private void consumerCloseGroupAssignment(boolean sharedGroups) throws AMQException, JMSException
+ {
+ final Map<String,Object> arguments = new HashMap<String, Object>();
+ arguments.put("qpid.group_header_key","group");
+ if(sharedGroups)
+ {
+ arguments.put("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);
+
+ producer.send(createMessage(1, "ONE"));
+ producer.send(createMessage(2, "ONE"));
+ producer.send(createMessage(3, "TWO"));
+ producer.send(createMessage(4, "ONE"));
+
+ producerSession.commit();
+ producer.close();
+ producerSession.close();
+ producerConnection.close();
+
+ Session cs1 = ((AMQConnection)consumerConnection).createSession(true, Session.SESSION_TRANSACTED,1);
+ Session cs2 = ((AMQConnection)consumerConnection).createSession(true, Session.SESSION_TRANSACTED,1);
+
+ MessageConsumer consumer1 = cs1.createConsumer(queue);
+
+ consumerConnection.start();
+ MessageConsumer consumer2 = cs2.createConsumer(queue);
+
+ Message cs1Received = consumer1.receive(1000);
+ assertNotNull("Consumer 1 should have received first message", cs1Received);
+ assertEquals("incorrect message received", 1, cs1Received.getIntProperty("msg"));
+
+ Message cs2Received = consumer2.receive(1000);
+
+ assertNotNull("Consumer 2 should have received first message", cs2Received);
+ assertEquals("incorrect message received", 3, cs2Received.getIntProperty("msg"));
+ cs2.commit();
+
+ Message cs2Received2 = consumer2.receive(1000);
+
+ assertNull("Consumer 2 should not yet have received a second message", cs2Received2);
+
+ consumer1.close();
+
+ cs1.commit();
+ Message cs2Received3 = consumer2.receive(1000);
+
+ assertNotNull("Consumer 2 should have received second message", cs2Received3);
+ assertEquals("Unexpected group", "ONE", cs2Received3.getStringProperty("group"));
+ assertEquals("incorrect message received", 2, cs2Received3.getIntProperty("msg"));
+
+ cs2.commit();
+
+
+ Message cs2Received4 = consumer2.receive(1000);
+
+ assertNotNull("Consumer 2 should have received third message", cs2Received4);
+ assertEquals("Unexpected group", "ONE", cs2Received4.getStringProperty("group"));
+ assertEquals("incorrect message received", 4, cs2Received4.getIntProperty("msg"));
+ cs2.commit();
+
+ assertNull(consumer2.receive(1000));
+ }
+
+
+
+
+ public void testConsumerCloseWithRelease() throws Exception
+ {
+ consumerCloseWithRelease(false);
+ }
+
+ public void testSharedGroupConsumerCloseWithRelease() throws Exception
+ {
+ consumerCloseWithRelease(true);
+ }
+
+
+ /**
+ *
+ * Tests that upon closing a consumer and its session, groups previously assigned to that consumer are reassigned
+ * toa different consumer, including messages which were previously delivered but have now been released.
+ *
+ * Pre-populate the queue as ONE, ONE, TWO, ONE
+ *
+ * create in sequence two consumers
+ *
+ * receive first from c1 then c2 (thus ONE is assigned to c1, TWO to c2)
+ *
+ * Then close c1 and its session without acking.
+ *
+ * If we now attempt to receive from c2, then the all messages in group ONE should be available (which
+ * requires c2 to go "backwards" in the queue). The first such message should be marked as redelivered
+ *
+ */
+ private void consumerCloseWithRelease(boolean sharedGroups) throws AMQException, JMSException
+ {
+ final Map<String,Object> arguments = new HashMap<String, Object>();
+ arguments.put("qpid.group_header_key","group");
+ if(sharedGroups)
+ {
+ arguments.put("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);
+
+ producer.send(createMessage(1, "ONE"));
+ producer.send(createMessage(2, "ONE"));
+ producer.send(createMessage(3, "TWO"));
+ producer.send(createMessage(4, "ONE"));
+
+ producerSession.commit();
+ producer.close();
+ producerSession.close();
+ producerConnection.close();
+
+ Session cs1 = ((AMQConnection)consumerConnection).createSession(true, Session.SESSION_TRANSACTED,1);
+ Session cs2 = ((AMQConnection)consumerConnection).createSession(true, Session.SESSION_TRANSACTED,1);
+
+
+ MessageConsumer consumer1 = cs1.createConsumer(queue);
+
+ consumerConnection.start();
+
+ MessageConsumer consumer2 = cs2.createConsumer(queue);
+
+ Message cs1Received = consumer1.receive(1000);
+ assertNotNull("Consumer 1 should have received its first message", cs1Received);
+ assertEquals("incorrect message received", 1, cs1Received.getIntProperty("msg"));
+
+ Message received = consumer2.receive(1000);
+
+ assertNotNull("Consumer 2 should have received its first message", received);
+ assertEquals("incorrect message received", 3, received.getIntProperty("msg"));
+
+ received = consumer2.receive(1000);
+
+ assertNull("Consumer 2 should not yet have received second message", received);
+
+ consumer1.close();
+ cs1.close();
+ cs2.commit();
+ received = consumer2.receive(1000);
+
+ assertNotNull("Consumer 2 should now have received second message", received);
+ assertEquals("Unexpected group", "ONE", received.getStringProperty("group"));
+ assertEquals("incorrect message received", 1, received.getIntProperty("msg"));
+ assertTrue("Expected second message to be marked as redelivered " + received.getIntProperty("msg"),
+ received.getJMSRedelivered());
+
+ cs2.commit();
+
+
+ received = consumer2.receive(1000);
+
+ assertNotNull("Consumer 2 should have received a third message", received);
+ assertEquals("Unexpected group", "ONE", received.getStringProperty("group"));
+ assertEquals("incorrect message received", 2, received.getIntProperty("msg"));
+
+ cs2.commit();
+
+ received = consumer2.receive(1000);
+
+ assertNotNull("Consumer 2 should have received a fourth message", received);
+ assertEquals("Unexpected group", "ONE", received.getStringProperty("group"));
+ assertEquals("incorrect message received", 4, received.getIntProperty("msg"));
+
+ cs2.commit();
+
+
+ assertNull(consumer2.receive(1000));
+ }
+
+ public void testGroupAssignmentSurvivesEmpty() throws JMSException, AMQException
+ {
+ groupAssignmentOnEmpty(false);
+ }
+
+ public void testSharedGroupAssignmentDoesNotSurviveEmpty() throws JMSException, AMQException
+ {
+ groupAssignmentOnEmpty(true);
+ }
+
+ private void groupAssignmentOnEmpty(boolean sharedGroups) throws AMQException, JMSException
+ {
+ final Map<String,Object> arguments = new HashMap<String, Object>();
+ arguments.put("qpid.group_header_key","group");
+ if(sharedGroups)
+ {
+ arguments.put("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);
+
+ producer.send(createMessage(1, "ONE"));
+ producer.send(createMessage(2, "TWO"));
+ producer.send(createMessage(3, "THREE"));
+ producer.send(createMessage(4, "ONE"));
+
+ producerSession.commit();
+ producer.close();
+ producerSession.close();
+ producerConnection.close();
+
+ Session cs1 = ((AMQConnection)consumerConnection).createSession(true, Session.SESSION_TRANSACTED,1);
+ Session cs2 = ((AMQConnection)consumerConnection).createSession(true, Session.SESSION_TRANSACTED,1);
+
+
+ MessageConsumer consumer1 = cs1.createConsumer(queue);
+
+ consumerConnection.start();
+
+ MessageConsumer consumer2 = cs2.createConsumer(queue);
+
+ Message received = consumer1.receive(1000);
+ assertNotNull("Consumer 1 should have received its first message", received);
+ assertEquals("incorrect message received", 1, received.getIntProperty("msg"));
+
+ received = consumer2.receive(1000);
+
+ assertNotNull("Consumer 2 should have received its first message", received);
+ assertEquals("incorrect message received", 2, received.getIntProperty("msg"));
+
+ cs1.commit();
+
+ received = consumer1.receive(1000);
+ assertNotNull("Consumer 1 should have received its second message", received);
+ assertEquals("incorrect message received", 3, received.getIntProperty("msg"));
+
+ // We expect different behaviours from "shared groups": here the assignment of a subscription to a group
+ // is terminated when there are no outstanding delivered but unacknowledged messages. In contrast, with a
+ // standard message grouping queue the assignment will be retained until the subscription is no longer
+ // registered
+ if(sharedGroups)
+ {
+ cs2.commit();
+ received = consumer2.receive(1000);
+
+ assertNotNull("Consumer 2 should have received its second message", received);
+ assertEquals("incorrect message received", 4, received.getIntProperty("msg"));
+
+ cs2.commit();
+ }
+ else
+ {
+ cs2.commit();
+ received = consumer2.receive(1000);
+
+ assertNull("Consumer 2 should not have received a second message", received);
+
+ cs1.commit();
+
+ received = consumer1.receive(1000);
+ assertNotNull("Consumer 1 should have received its third message", received);
+ assertEquals("incorrect message received", 4, received.getIntProperty("msg"));
+
+ }
+
+ }
+
+
+ private Message createMessage(int msg, String group) throws JMSException
+ {
+ Message send = producerSession.createTextMessage("Message: " + msg);
+ send.setIntProperty("msg", msg);
+ send.setStringProperty("group", group);
+
+ return send;
+ }
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/ProducerFlowControlTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/ProducerFlowControlTest.java
index 775d2c3eb0..47f334adf6 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/ProducerFlowControlTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/ProducerFlowControlTest.java
@@ -154,8 +154,7 @@ public class ProducerFlowControlTest extends AbstractTestLogging
// try to send 5 messages (should block after 4)
sendMessagesAsync(producer, producerSession, 5, 50L);
- Thread.sleep(5000);
- List<String> results = waitAndFindMatches("QUE-1003");
+ List<String> results = waitAndFindMatches("QUE-1003", 7000);
assertEquals("Did not find correct number of QUE-1003 queue overfull messages", 1, results.size());
@@ -199,11 +198,13 @@ public class ProducerFlowControlTest extends AbstractTestLogging
// try to send 5 messages (should block after 4)
MessageSender sender = sendMessagesAsync(producer, producerSession, 5, 50L);
- Thread.sleep(TIMEOUT);
List<String> results = waitAndFindMatches("Message send delayed by", TIMEOUT);
assertTrue("No delay messages logged by client",results.size()!=0);
- results = findMatches("Message send failed due to timeout waiting on broker enforced flow control");
- assertEquals("Incorrect number of send failure messages logged by client",1,results.size());
+
+ List<String> failedMessages = waitAndFindMatches("Message send failed due to timeout waiting on broker enforced"
+ + " flow control", TIMEOUT);
+ assertEquals("Incorrect number of send failure messages logged by client (got " + results.size() + " delay "
+ + "messages)",1,failedMessages.size());
@@ -325,8 +326,9 @@ public class ProducerFlowControlTest extends AbstractTestLogging
// try to send 5 messages (should block after 4)
- MessageSender sender = sendMessagesAsync(producer, producerSession, 5, 50L);
+ MessageSender sender = sendMessagesAsync(producer, producerSession, 5, 100L);
+
Thread.sleep(10000);
Exception e = sender.getException();
@@ -440,6 +442,15 @@ public class ProducerFlowControlTest extends AbstractTestLogging
e.printStackTrace();
throw new RuntimeException(e);
}
+
+ try
+ {
+ Thread.sleep(sleepPeriod);
+ }
+ catch (InterruptedException e)
+ {
+ throw new RuntimeException(e);
+ }
}
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java
index a5c38e7e33..2d450cf09c 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java
@@ -22,11 +22,13 @@ package org.apache.qpid.server.store;
import org.apache.commons.configuration.Configuration;
import org.apache.log4j.Logger;
-import org.apache.qpid.AMQException;
import org.apache.qpid.AMQStoreException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.federation.Bridge;
+import org.apache.qpid.server.federation.BrokerLink;
+import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.logging.LogSubject;
@@ -35,7 +37,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.nio.ByteBuffer;
-public class SlowMessageStore implements MessageStore
+public class SlowMessageStore implements MessageStore, DurableConfigurationStore
{
private static final Logger _logger = Logger.getLogger(SlowMessageStore.class);
private static final String DELAYS = "delays";
@@ -43,6 +45,7 @@ public class SlowMessageStore implements MessageStore
private HashMap<String, Long> _postDelays = new HashMap<String, Long>();
private long _defaultDelay = 0L;
private MessageStore _realStore = new MemoryMessageStore();
+ private DurableConfigurationStore _durableConfigurationStore = (MemoryMessageStore) _realStore;
private static final String PRE = "pre";
private static final String POST = "post";
private String DEFAULT_DELAY = "default";
@@ -80,12 +83,13 @@ public class SlowMessageStore implements MessageStore
" does not.");
}
_realStore = (MessageStore) o;
- _realStore.configureConfigStore(name, recoveryHandler, config, logSubject);
- }
- else
- {
- _realStore.configureConfigStore(name, recoveryHandler, config, logSubject);
+ if(o instanceof DurableConfigurationStore)
+ {
+ _durableConfigurationStore = (DurableConfigurationStore)o;
+ }
}
+ _durableConfigurationStore.configureConfigStore(name, recoveryHandler, config, logSubject);
+
}
private void configureDelays(Configuration config)
@@ -178,28 +182,28 @@ public class SlowMessageStore implements MessageStore
public void createExchange(Exchange exchange) throws AMQStoreException
{
doPreDelay("createExchange");
- _realStore.createExchange(exchange);
+ _durableConfigurationStore.createExchange(exchange);
doPostDelay("createExchange");
}
public void removeExchange(Exchange exchange) throws AMQStoreException
{
doPreDelay("removeExchange");
- _realStore.removeExchange(exchange);
+ _durableConfigurationStore.removeExchange(exchange);
doPostDelay("removeExchange");
}
public void bindQueue(Exchange exchange, AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQStoreException
{
doPreDelay("bindQueue");
- _realStore.bindQueue(exchange, routingKey, queue, args);
+ _durableConfigurationStore.bindQueue(exchange, routingKey, queue, args);
doPostDelay("bindQueue");
}
public void unbindQueue(Exchange exchange, AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQStoreException
{
doPreDelay("unbindQueue");
- _realStore.unbindQueue(exchange, routingKey, queue, args);
+ _durableConfigurationStore.unbindQueue(exchange, routingKey, queue, args);
doPostDelay("unbindQueue");
}
@@ -211,14 +215,14 @@ public class SlowMessageStore implements MessageStore
public void createQueue(AMQQueue queue, FieldTable arguments) throws AMQStoreException
{
doPreDelay("createQueue");
- _realStore.createQueue(queue, arguments);
+ _durableConfigurationStore.createQueue(queue, arguments);
doPostDelay("createQueue");
}
public void removeQueue(AMQQueue queue) throws AMQStoreException
{
doPreDelay("removeQueue");
- _realStore.removeQueue(queue);
+ _durableConfigurationStore.removeQueue(queue);
doPostDelay("removeQueue");
}
@@ -268,19 +272,19 @@ public class SlowMessageStore implements MessageStore
_underlying = underlying;
}
- public void enqueueMessage(TransactionLogResource queue, Long messageId)
+ public void enqueueMessage(TransactionLogResource queue, EnqueableMessage message)
throws AMQStoreException
{
doPreDelay("enqueueMessage");
- _underlying.enqueueMessage(queue, messageId);
+ _underlying.enqueueMessage(queue, message);
doPostDelay("enqueueMessage");
}
- public void dequeueMessage(TransactionLogResource queue, Long messageId)
+ public void dequeueMessage(TransactionLogResource queue, EnqueableMessage message)
throws AMQStoreException
{
doPreDelay("dequeueMessage");
- _underlying.dequeueMessage(queue, messageId);
+ _underlying.dequeueMessage(queue, message);
doPostDelay("dequeueMessage");
}
@@ -313,9 +317,36 @@ public class SlowMessageStore implements MessageStore
public void updateQueue(AMQQueue queue) throws AMQStoreException
{
doPreDelay("updateQueue");
- _realStore.updateQueue(queue);
+ _durableConfigurationStore.updateQueue(queue);
doPostDelay("updateQueue");
}
+ public void createBrokerLink(final BrokerLink link) throws AMQStoreException
+ {
+ doPreDelay("createBrokerLink");
+ _durableConfigurationStore.createBrokerLink(link);
+ doPostDelay("createBrokerLink");
+ }
+
+ public void deleteBrokerLink(final BrokerLink link) throws AMQStoreException
+ {
+ doPreDelay("deleteBrokerLink");
+ _durableConfigurationStore.deleteBrokerLink(link);
+ doPostDelay("deleteBrokerLink");
+ }
+
+ public void createBridge(final Bridge bridge) throws AMQStoreException
+ {
+ doPreDelay("createBridge");
+ _durableConfigurationStore.createBridge(bridge);
+ doPostDelay("createBridge");
+ }
+
+ public void deleteBridge(final Bridge bridge) throws AMQStoreException
+ {
+ doPreDelay("deleteBridge");
+ _durableConfigurationStore.deleteBridge(bridge);
+ doPostDelay("deleteBridge");
+ }
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/ObjectMessageTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/ObjectMessageTest.java
index 147a03be0c..fa16152b69 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/ObjectMessageTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/ObjectMessageTest.java
@@ -138,4 +138,21 @@ public class ObjectMessageTest extends QpidBrokerTestCase
assertEquals("Second read: UUIDs were not equal", sent, result);
}
+
+
+ public void testSendEmptyObjectMessage() throws JMSException
+ {
+ ObjectMessage testMessage = _session.createObjectMessage();
+ testMessage.setStringProperty("test-property", "test-value");
+ assertNotNull("Object was null", testMessage.toString());
+
+ _producer.send(testMessage);
+
+ ObjectMessage receivedMessage = (ObjectMessage) _consumer.receive(1000);
+
+ assertNotNull("Message was not received.", receivedMessage);
+ assertNull("No object was sent", receivedMessage.getObject());
+ assertEquals("Unexpected property received", "test-value", receivedMessage.getStringProperty("test-property"));
+ }
+
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/queue/QueuePolicyTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/queue/QueuePolicyTest.java
index e3557efd97..e7c3fad27d 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/queue/QueuePolicyTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/queue/QueuePolicyTest.java
@@ -53,6 +53,10 @@ public class QueuePolicyTest extends QpidBrokerTestCase
super.tearDown();
}
+ /**
+ * Test Goal : To create a ring queue programitcally with max queue count using the
+ * address string and observe that it works as expected.
+ */
public void testRejectPolicy() throws Exception
{
String addr = "ADDR:queue; {create: always, " +
@@ -82,6 +86,10 @@ public class QueuePolicyTest extends QpidBrokerTestCase
}
}
+ /**
+ * Test Goal : To create a ring queue programitcally using the address string and observe
+ * that it works as expected.
+ */
public void testRingPolicy() throws Exception
{
Session ssn = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
@@ -94,17 +102,18 @@ public class QueuePolicyTest extends QpidBrokerTestCase
MessageConsumer consumer = ssn.createConsumer(dest);
MessageProducer prod = ssn.createProducer(ssn.createQueue("ADDR:amq.direct/test"));
+ _connection.stop();
+
prod.send(ssn.createTextMessage("Test1"));
prod.send(ssn.createTextMessage("Test2"));
prod.send(ssn.createTextMessage("Test3"));
+
+ _connection.start();
TextMessage msg = (TextMessage)consumer.receive(1000);
- assertEquals("The consumer should receive the msg with body='Test2'",msg.getText(),"Test2");
+ assertEquals("The consumer should receive the msg with body='Test2'","Test2",msg.getText());
msg = (TextMessage)consumer.receive(1000);
- assertEquals("The consumer should receive the msg with body='Test3'",msg.getText(),"Test3");
-
- prod.send(ssn.createTextMessage("Test4"));
- assertEquals("The consumer should receive the msg with body='Test4'",msg.getText(),"Test3");
+ assertEquals("The consumer should receive the msg with body='Test3'","Test3",msg.getText());
}
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java
index 7f166d07fe..20044b7a14 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java
@@ -20,19 +20,11 @@
*/
package org.apache.qpid.test.unit.client.connection;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-import org.apache.qpid.transport.util.Logger;
-
-import java.util.HashMap;
-import java.util.Map;
-
import javax.jms.Connection;
import javax.jms.JMSException;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
import javax.jms.Session;
-import javax.jms.TextMessage;
+
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
/**
* ConnectionCloseTest
@@ -42,63 +34,6 @@ import javax.jms.TextMessage;
public class ConnectionCloseTest extends QpidBrokerTestCase
{
- private static final Logger log = Logger.get(ConnectionCloseTest.class);
-
- public void testSendReceiveClose() throws Exception
- {
- Map<Thread,StackTraceElement[]> before = Thread.getAllStackTraces();
-
- for (int i = 0; i < 50; i++)
- {
- if ((i % 10) == 0)
- {
- log.warn("%d messages sent and received", i);
- }
-
- Connection receiver = getConnection();
- receiver.start();
- Session rssn = receiver.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Queue queue = rssn.createQueue("connection-close-test-queue");
- MessageConsumer cons = rssn.createConsumer(queue);
-
- Connection sender = getConnection();
- sender.start();
- Session sssn = sender.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer prod = sssn.createProducer(queue);
- prod.send(sssn.createTextMessage("test"));
- sender.close();
-
- TextMessage m = (TextMessage) cons.receive(2000);
- assertNotNull("message was lost", m);
- assertEquals(m.getText(), "test");
- receiver.close();
- }
-
- // The finalizer is notifying connector thread waiting on a selector key.
- // This should leave the finalizer enough time to notify those threads
- synchronized (this)
- {
- this.wait(10000);
- }
-
- Map<Thread,StackTraceElement[]> after = Thread.getAllStackTraces();
-
- Map<Thread,StackTraceElement[]> delta = new HashMap<Thread,StackTraceElement[]>(after);
- for (Thread t : before.keySet())
- {
- delta.remove(t);
- }
-
- dumpStacks(delta);
-
- int deltaThreshold = (isExternalBroker()? 1 : 2) //InVM creates more thread pools in the same VM
- * (Runtime.getRuntime().availableProcessors() + 1) + 5;
-
- assertTrue("Spurious thread creation exceeded threshold, " +
- delta.size() + " threads created.",
- delta.size() < deltaThreshold);
- }
-
/**
* This test is added due to QPID-3453 to test connection closing when AMQ
* session is not closed but underlying transport session is in detached
@@ -124,14 +59,4 @@ public class ConnectionCloseTest extends QpidBrokerTestCase
}
}
- private void dumpStacks(Map<Thread,StackTraceElement[]> map)
- {
- for (Map.Entry<Thread,StackTraceElement[]> entry : map.entrySet())
- {
- Throwable t = new Throwable();
- t.setStackTrace(entry.getValue());
- log.warn(t, entry.getKey().toString());
- }
- }
-
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactedTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactedTest.java
index 653ab8f733..3c0f951c96 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactedTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactedTest.java
@@ -31,6 +31,8 @@ import org.apache.qpid.test.utils.QpidBrokerTestCase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.jms.Connection;
+import javax.jms.IllegalStateException;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
@@ -303,6 +305,70 @@ public class TransactedTest extends QpidBrokerTestCase
con2.close();
}
+ public void testCommitOnClosedConnection() throws Exception
+ {
+ Connection connnection = getConnection();
+ javax.jms.Session transactedSession = connnection.createSession(true, Session.SESSION_TRANSACTED);
+ connnection.close();
+ try
+ {
+ transactedSession.commit();
+ fail("Commit on closed connection should throw IllegalStateException!");
+ }
+ catch(IllegalStateException e)
+ {
+ // passed
+ }
+ }
+
+ public void testCommitOnClosedSession() throws Exception
+ {
+ Connection connnection = getConnection();
+ javax.jms.Session transactedSession = connnection.createSession(true, Session.SESSION_TRANSACTED);
+ transactedSession.close();
+ try
+ {
+ transactedSession.commit();
+ fail("Commit on closed session should throw IllegalStateException!");
+ }
+ catch(IllegalStateException e)
+ {
+ // passed
+ }
+ }
+
+ public void testRollbackOnClosedSession() throws Exception
+ {
+ Connection connnection = getConnection();
+ javax.jms.Session transactedSession = connnection.createSession(true, Session.SESSION_TRANSACTED);
+ transactedSession.close();
+ try
+ {
+ transactedSession.rollback();
+ fail("Rollback on closed session should throw IllegalStateException!");
+ }
+ catch(IllegalStateException e)
+ {
+ // passed
+ }
+ }
+
+ public void testGetTransactedOnClosedSession() throws Exception
+ {
+ Connection connnection = getConnection();
+ javax.jms.Session transactedSession = connnection.createSession(true, Session.SESSION_TRANSACTED);
+ transactedSession.close();
+ try
+ {
+ transactedSession.getTransacted();
+ fail("According to Sun TCK invocation of Session#getTransacted on closed session should throw IllegalStateException!");
+ }
+ catch(IllegalStateException e)
+ {
+ // passed
+ }
+ }
+
private void expect(String text, Message msg) throws JMSException
{
expect(text, msg, false);
diff --git a/qpid/java/test-profiles/CPPExcludes b/qpid/java/test-profiles/CPPExcludes
index 66a20bcfc1..d8c463b810 100755
--- a/qpid/java/test-profiles/CPPExcludes
+++ b/qpid/java/test-profiles/CPPExcludes
@@ -172,3 +172,9 @@ org.apache.qpid.server.management.AMQUserManagementMBeanTest#*
// QPID-3133: On 0-10, the exception listener is currently not invoked when reconnection fails to occurs.
org.apache.qpid.server.failover.FailoverMethodTest#*
+// CPP Broker does not implement non-"shared group" message groups
+org.apache.qpid.server.queue.MessageGroupQueueTest#testSimpleGroupAssignment
+org.apache.qpid.server.queue.MessageGroupQueueTest#testConsumerCloseGroupAssignment
+org.apache.qpid.server.queue.MessageGroupQueueTest#testConsumerCloseWithRelease
+org.apache.qpid.server.queue.MessageGroupQueueTest#testGroupAssignmentSurvivesEmpty
+
diff --git a/qpid/java/test-profiles/Java010Excludes b/qpid/java/test-profiles/Java010Excludes
index 59cb5066f1..0de4c6bae5 100755
--- a/qpid/java/test-profiles/Java010Excludes
+++ b/qpid/java/test-profiles/Java010Excludes
@@ -45,9 +45,6 @@ org.apache.qpid.server.logging.SubscriptionLoggingTest#testSubscriptionSuspend
// 0-10 is not supported by the MethodRegistry
org.apache.qpid.test.unit.close.JavaServerCloseRaceConditionTest#*
-//QPID-942 : Implemented Channel.Flow based Producer Side flow control to the Java Broker (not in CPP Broker)
-org.apache.qpid.server.queue.ProducerFlowControlTest#*
-
//QPID-1864: rollback with subscriptions does not work in 0-10 yet
org.apache.qpid.test.client.RollbackOrderTest#testOrderingAfterRollbackOnMessage